1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58#include <stdarg.h>
59
60#include <linux/delay.h>
61#include <linux/init.h>
62#include <linux/kernel.h>
63#include <linux/module.h>
64#include <linux/string.h>
65#include <linux/spinlock.h>
66
67#include <asm/page.h>
68#include <asm/pdc.h>
69#include <asm/pdcpat.h>
70#include <asm/system.h>
71#include <asm/processor.h>
72
73static DEFINE_SPINLOCK(pdc_lock);
74extern unsigned long pdc_result[NUM_PDC_RESULT];
75extern unsigned long pdc_result2[NUM_PDC_RESULT];
76
77#ifdef CONFIG_64BIT
78#define WIDE_FIRMWARE 0x1
79#define NARROW_FIRMWARE 0x2
80
81
82
83int parisc_narrow_firmware __read_mostly = 1;
84#endif
85
86
87
88
89
90
91
92
93
94
95
96
97#ifdef CONFIG_64BIT
98long real64_call(unsigned long function, ...);
99#endif
100long real32_call(unsigned long function, ...);
101
102#ifdef CONFIG_64BIT
103# define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
104# define mem_pdc_call(args...) unlikely(parisc_narrow_firmware) ? real32_call(MEM_PDC, args) : real64_call(MEM_PDC, args)
105#else
106# define MEM_PDC (unsigned long)PAGE0->mem_pdc
107# define mem_pdc_call(args...) real32_call(MEM_PDC, args)
108#endif
109
110
111
112
113
114
115
116
117
118static unsigned long f_extend(unsigned long address)
119{
120#ifdef CONFIG_64BIT
121 if(unlikely(parisc_narrow_firmware)) {
122 if((address & 0xff000000) == 0xf0000000)
123 return 0xf0f0f0f000000000UL | (u32)address;
124
125 if((address & 0xf0000000) == 0xf0000000)
126 return 0xffffffff00000000UL | (u32)address;
127 }
128#endif
129 return address;
130}
131
132
133
134
135
136
137
138
139
140static void convert_to_wide(unsigned long *addr)
141{
142#ifdef CONFIG_64BIT
143 int i;
144 unsigned int *p = (unsigned int *)addr;
145
146 if(unlikely(parisc_narrow_firmware)) {
147 for(i = 31; i >= 0; --i)
148 addr[i] = p[i];
149 }
150#endif
151}
152
153#ifdef CONFIG_64BIT
154void __cpuinit set_firmware_width_unlocked(void)
155{
156 int ret;
157
158 ret = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES,
159 __pa(pdc_result), 0);
160 convert_to_wide(pdc_result);
161 if (pdc_result[0] != NARROW_FIRMWARE)
162 parisc_narrow_firmware = 0;
163}
164
165
166
167
168
169
170
171void __cpuinit set_firmware_width(void)
172{
173 unsigned long flags;
174 spin_lock_irqsave(&pdc_lock, flags);
175 set_firmware_width_unlocked();
176 spin_unlock_irqrestore(&pdc_lock, flags);
177}
178#else
179void __cpuinit set_firmware_width_unlocked(void) {
180 return;
181}
182
183void __cpuinit set_firmware_width(void) {
184 return;
185}
186#endif
187
188
189
190
191
192
193
194void pdc_emergency_unlock(void)
195{
196
197 if (spin_is_locked(&pdc_lock))
198 spin_unlock(&pdc_lock);
199}
200
201
202
203
204
205
206
207
208
209
210
211int pdc_add_valid(unsigned long address)
212{
213 int retval;
214 unsigned long flags;
215
216 spin_lock_irqsave(&pdc_lock, flags);
217 retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
218 spin_unlock_irqrestore(&pdc_lock, flags);
219
220 return retval;
221}
222EXPORT_SYMBOL(pdc_add_valid);
223
224
225
226
227
228
229
230
231
232int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
233{
234 int retval;
235 unsigned long flags;
236
237 spin_lock_irqsave(&pdc_lock, flags);
238 memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
239 memcpy(&pdc_result2, led_info, len);
240 retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
241 __pa(pdc_result), __pa(pdc_result2), len);
242 memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
243 memcpy(led_info, pdc_result2, len);
244 spin_unlock_irqrestore(&pdc_lock, flags);
245
246 return retval;
247}
248
249
250
251
252
253
254
255#ifdef CONFIG_64BIT
256int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
257{
258 int retval = 0;
259 unsigned long flags;
260
261 if (!is_pdc_pat())
262 return -1;
263
264 spin_lock_irqsave(&pdc_lock, flags);
265 retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
266 spin_unlock_irqrestore(&pdc_lock, flags);
267
268 return retval;
269}
270#endif
271
272
273
274
275
276int pdc_chassis_disp(unsigned long disp)
277{
278 int retval = 0;
279 unsigned long flags;
280
281 spin_lock_irqsave(&pdc_lock, flags);
282 retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
283 spin_unlock_irqrestore(&pdc_lock, flags);
284
285 return retval;
286}
287
288
289
290
291
292int pdc_chassis_warn(unsigned long *warn)
293{
294 int retval = 0;
295 unsigned long flags;
296
297 spin_lock_irqsave(&pdc_lock, flags);
298 retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result));
299 *warn = pdc_result[0];
300 spin_unlock_irqrestore(&pdc_lock, flags);
301
302 return retval;
303}
304
305int __cpuinit pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info)
306{
307 int ret;
308
309 ret = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
310 convert_to_wide(pdc_result);
311 pdc_coproc_info->ccr_functional = pdc_result[0];
312 pdc_coproc_info->ccr_present = pdc_result[1];
313 pdc_coproc_info->revision = pdc_result[17];
314 pdc_coproc_info->model = pdc_result[18];
315
316 return ret;
317}
318
319
320
321
322
323
324
325
326int __cpuinit pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
327{
328 int ret;
329 unsigned long flags;
330
331 spin_lock_irqsave(&pdc_lock, flags);
332 ret = pdc_coproc_cfg_unlocked(pdc_coproc_info);
333 spin_unlock_irqrestore(&pdc_lock, flags);
334
335 return ret;
336}
337
338
339
340
341
342
343
344
345
346
347
348
349int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
350 void *iodc_data, unsigned int iodc_data_size)
351{
352 int retval;
353 unsigned long flags;
354
355 spin_lock_irqsave(&pdc_lock, flags);
356 retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa,
357 index, __pa(pdc_result2), iodc_data_size);
358 convert_to_wide(pdc_result);
359 *actcnt = pdc_result[0];
360 memcpy(iodc_data, pdc_result2, iodc_data_size);
361 spin_unlock_irqrestore(&pdc_lock, flags);
362
363 return retval;
364}
365EXPORT_SYMBOL(pdc_iodc_read);
366
367
368
369
370
371
372
373
374
375
376int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
377 struct pdc_module_path *mod_path, long mod_index)
378{
379 int retval;
380 unsigned long flags;
381
382 spin_lock_irqsave(&pdc_lock, flags);
383 retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result),
384 __pa(pdc_result2), mod_index);
385 convert_to_wide(pdc_result);
386 memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
387 memcpy(mod_path, pdc_result2, sizeof(*mod_path));
388 spin_unlock_irqrestore(&pdc_lock, flags);
389
390 pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
391 return retval;
392}
393
394
395
396
397
398
399
400
401
402
403int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
404 long mod_index, long addr_index)
405{
406 int retval;
407 unsigned long flags;
408
409 spin_lock_irqsave(&pdc_lock, flags);
410 retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
411 mod_index, addr_index);
412 convert_to_wide(pdc_result);
413 memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
414 spin_unlock_irqrestore(&pdc_lock, flags);
415
416 pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
417 return retval;
418}
419
420
421
422
423
424
425
426int pdc_model_info(struct pdc_model *model)
427{
428 int retval;
429 unsigned long flags;
430
431 spin_lock_irqsave(&pdc_lock, flags);
432 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
433 convert_to_wide(pdc_result);
434 memcpy(model, pdc_result, sizeof(*model));
435 spin_unlock_irqrestore(&pdc_lock, flags);
436
437 return retval;
438}
439
440
441
442
443
444
445
446
447
448int pdc_model_sysmodel(char *name)
449{
450 int retval;
451 unsigned long flags;
452
453 spin_lock_irqsave(&pdc_lock, flags);
454 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
455 OS_ID_HPUX, __pa(name));
456 convert_to_wide(pdc_result);
457
458 if (retval == PDC_OK) {
459 name[pdc_result[0]] = '\0';
460 } else {
461 name[0] = 0;
462 }
463 spin_unlock_irqrestore(&pdc_lock, flags);
464
465 return retval;
466}
467
468
469
470
471
472
473
474
475
476
477
478int pdc_model_versions(unsigned long *versions, int id)
479{
480 int retval;
481 unsigned long flags;
482
483 spin_lock_irqsave(&pdc_lock, flags);
484 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
485 convert_to_wide(pdc_result);
486 *versions = pdc_result[0];
487 spin_unlock_irqrestore(&pdc_lock, flags);
488
489 return retval;
490}
491
492
493
494
495
496
497
498
499int pdc_model_cpuid(unsigned long *cpu_id)
500{
501 int retval;
502 unsigned long flags;
503
504 spin_lock_irqsave(&pdc_lock, flags);
505 pdc_result[0] = 0;
506 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
507 convert_to_wide(pdc_result);
508 *cpu_id = pdc_result[0];
509 spin_unlock_irqrestore(&pdc_lock, flags);
510
511 return retval;
512}
513
514
515
516
517
518
519
520
521int pdc_model_capabilities(unsigned long *capabilities)
522{
523 int retval;
524 unsigned long flags;
525
526 spin_lock_irqsave(&pdc_lock, flags);
527 pdc_result[0] = 0;
528 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
529 convert_to_wide(pdc_result);
530 if (retval == PDC_OK) {
531 *capabilities = pdc_result[0];
532 } else {
533 *capabilities = PDC_MODEL_OS32;
534 }
535 spin_unlock_irqrestore(&pdc_lock, flags);
536
537 return retval;
538}
539
540
541
542
543
544
545
546int pdc_cache_info(struct pdc_cache_info *cache_info)
547{
548 int retval;
549 unsigned long flags;
550
551 spin_lock_irqsave(&pdc_lock, flags);
552 retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
553 convert_to_wide(pdc_result);
554 memcpy(cache_info, pdc_result, sizeof(*cache_info));
555 spin_unlock_irqrestore(&pdc_lock, flags);
556
557 return retval;
558}
559
560
561
562
563
564
565
566int pdc_spaceid_bits(unsigned long *space_bits)
567{
568 int retval;
569 unsigned long flags;
570
571 spin_lock_irqsave(&pdc_lock, flags);
572 pdc_result[0] = 0;
573 retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0);
574 convert_to_wide(pdc_result);
575 *space_bits = pdc_result[0];
576 spin_unlock_irqrestore(&pdc_lock, flags);
577
578 return retval;
579}
580
581#ifndef CONFIG_PA20
582
583
584
585
586
587
588int pdc_btlb_info(struct pdc_btlb_info *btlb)
589{
590 int retval;
591 unsigned long flags;
592
593 spin_lock_irqsave(&pdc_lock, flags);
594 retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
595 memcpy(btlb, pdc_result, sizeof(*btlb));
596 spin_unlock_irqrestore(&pdc_lock, flags);
597
598 if(retval < 0) {
599 btlb->max_size = 0;
600 }
601 return retval;
602}
603
604
605
606
607
608
609
610
611
612
613
614
615
616int pdc_mem_map_hpa(struct pdc_memory_map *address,
617 struct pdc_module_path *mod_path)
618{
619 int retval;
620 unsigned long flags;
621
622 spin_lock_irqsave(&pdc_lock, flags);
623 memcpy(pdc_result2, mod_path, sizeof(*mod_path));
624 retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
625 __pa(pdc_result2));
626 memcpy(address, pdc_result, sizeof(*address));
627 spin_unlock_irqrestore(&pdc_lock, flags);
628
629 return retval;
630}
631#endif
632
633
634
635
636
637
638
639
640int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
641{
642 int retval;
643 unsigned long flags;
644
645 spin_lock_irqsave(&pdc_lock, flags);
646 retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
647 __pa(pdc_result), hpa);
648 if (retval < 0) {
649
650 memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
651 } else {
652 memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
653 }
654 spin_unlock_irqrestore(&pdc_lock, flags);
655
656 return retval;
657}
658EXPORT_SYMBOL(pdc_lan_station_id);
659
660
661
662
663
664
665
666
667
668
669
670int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count)
671{
672 int retval;
673 unsigned long flags;
674
675 spin_lock_irqsave(&pdc_lock, flags);
676 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_READ, staddr,
677 __pa(pdc_result), count);
678 convert_to_wide(pdc_result);
679 memcpy(memaddr, pdc_result, count);
680 spin_unlock_irqrestore(&pdc_lock, flags);
681
682 return retval;
683}
684EXPORT_SYMBOL(pdc_stable_read);
685
686
687
688
689
690
691
692
693
694
695
696int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count)
697{
698 int retval;
699 unsigned long flags;
700
701 spin_lock_irqsave(&pdc_lock, flags);
702 memcpy(pdc_result, memaddr, count);
703 convert_to_wide(pdc_result);
704 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_WRITE, staddr,
705 __pa(pdc_result), count);
706 spin_unlock_irqrestore(&pdc_lock, flags);
707
708 return retval;
709}
710EXPORT_SYMBOL(pdc_stable_write);
711
712
713
714
715
716
717
718
719
720
721int pdc_stable_get_size(unsigned long *size)
722{
723 int retval;
724 unsigned long flags;
725
726 spin_lock_irqsave(&pdc_lock, flags);
727 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_RETURN_SIZE, __pa(pdc_result));
728 *size = pdc_result[0];
729 spin_unlock_irqrestore(&pdc_lock, flags);
730
731 return retval;
732}
733EXPORT_SYMBOL(pdc_stable_get_size);
734
735
736
737
738
739
740
741int pdc_stable_verify_contents(void)
742{
743 int retval;
744 unsigned long flags;
745
746 spin_lock_irqsave(&pdc_lock, flags);
747 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_VERIFY_CONTENTS);
748 spin_unlock_irqrestore(&pdc_lock, flags);
749
750 return retval;
751}
752EXPORT_SYMBOL(pdc_stable_verify_contents);
753
754
755
756
757
758
759
760int pdc_stable_initialize(void)
761{
762 int retval;
763 unsigned long flags;
764
765 spin_lock_irqsave(&pdc_lock, flags);
766 retval = mem_pdc_call(PDC_STABLE, PDC_STABLE_INITIALIZE);
767 spin_unlock_irqrestore(&pdc_lock, flags);
768
769 return retval;
770}
771EXPORT_SYMBOL(pdc_stable_initialize);
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787int pdc_get_initiator(struct hardware_path *hwpath, struct pdc_initiator *initiator)
788{
789 int retval;
790 unsigned long flags;
791
792 spin_lock_irqsave(&pdc_lock, flags);
793
794
795#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
796 strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0)
797
798 retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR,
799 __pa(pdc_result), __pa(hwpath));
800 if (retval < PDC_OK)
801 goto out;
802
803 if (pdc_result[0] < 16) {
804 initiator->host_id = pdc_result[0];
805 } else {
806 initiator->host_id = -1;
807 }
808
809
810
811
812
813 switch (pdc_result[1]) {
814 case 1: initiator->factor = 50; break;
815 case 2: initiator->factor = 25; break;
816 case 5: initiator->factor = 12; break;
817 case 25: initiator->factor = 10; break;
818 case 20: initiator->factor = 12; break;
819 case 40: initiator->factor = 10; break;
820 default: initiator->factor = -1; break;
821 }
822
823 if (IS_SPROCKETS()) {
824 initiator->width = pdc_result[4];
825 initiator->mode = pdc_result[5];
826 } else {
827 initiator->width = -1;
828 initiator->mode = -1;
829 }
830
831 out:
832 spin_unlock_irqrestore(&pdc_lock, flags);
833
834 return (retval >= PDC_OK);
835}
836EXPORT_SYMBOL(pdc_get_initiator);
837
838
839
840
841
842
843
844
845
846
847
848int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
849{
850 int retval;
851 unsigned long flags;
852
853 spin_lock_irqsave(&pdc_lock, flags);
854 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
855 __pa(pdc_result), hpa);
856 convert_to_wide(pdc_result);
857 *num_entries = pdc_result[0];
858 spin_unlock_irqrestore(&pdc_lock, flags);
859
860 return retval;
861}
862
863
864
865
866
867
868
869
870
871
872int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
873{
874 int retval;
875 unsigned long flags;
876
877 BUG_ON((unsigned long)tbl & 0x7);
878
879 spin_lock_irqsave(&pdc_lock, flags);
880 pdc_result[0] = num_entries;
881 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
882 __pa(pdc_result), hpa, __pa(tbl));
883 spin_unlock_irqrestore(&pdc_lock, flags);
884
885 return retval;
886}
887
888
889#if 0
890
891
892
893
894
895
896
897
898unsigned int pdc_pci_config_read(void *hpa, unsigned long cfg_addr)
899{
900 int retval;
901 unsigned long flags;
902
903 spin_lock_irqsave(&pdc_lock, flags);
904 pdc_result[0] = 0;
905 pdc_result[1] = 0;
906 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_READ_CONFIG,
907 __pa(pdc_result), hpa, cfg_addr&~3UL, 4UL);
908 spin_unlock_irqrestore(&pdc_lock, flags);
909
910 return retval ? ~0 : (unsigned int) pdc_result[0];
911}
912
913
914
915
916
917
918
919
920
921
922void pdc_pci_config_write(void *hpa, unsigned long cfg_addr, unsigned int val)
923{
924 int retval;
925 unsigned long flags;
926
927 spin_lock_irqsave(&pdc_lock, flags);
928 pdc_result[0] = 0;
929 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_WRITE_CONFIG,
930 __pa(pdc_result), hpa,
931 cfg_addr&~3UL, 4UL, (unsigned long) val);
932 spin_unlock_irqrestore(&pdc_lock, flags);
933
934 return retval;
935}
936#endif
937
938
939
940
941
942
943
944int pdc_tod_read(struct pdc_tod *tod)
945{
946 int retval;
947 unsigned long flags;
948
949 spin_lock_irqsave(&pdc_lock, flags);
950 retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
951 convert_to_wide(pdc_result);
952 memcpy(tod, pdc_result, sizeof(*tod));
953 spin_unlock_irqrestore(&pdc_lock, flags);
954
955 return retval;
956}
957EXPORT_SYMBOL(pdc_tod_read);
958
959
960
961
962
963
964
965
966int pdc_tod_set(unsigned long sec, unsigned long usec)
967{
968 int retval;
969 unsigned long flags;
970
971 spin_lock_irqsave(&pdc_lock, flags);
972 retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
973 spin_unlock_irqrestore(&pdc_lock, flags);
974
975 return retval;
976}
977EXPORT_SYMBOL(pdc_tod_set);
978
979#ifdef CONFIG_64BIT
980int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
981 struct pdc_memory_table *tbl, unsigned long entries)
982{
983 int retval;
984 unsigned long flags;
985
986 spin_lock_irqsave(&pdc_lock, flags);
987 retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
988 convert_to_wide(pdc_result);
989 memcpy(r_addr, pdc_result, sizeof(*r_addr));
990 memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
991 spin_unlock_irqrestore(&pdc_lock, flags);
992
993 return retval;
994}
995#endif
996
997
998
999
1000
1001int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
1002{
1003 int retval;
1004 unsigned long flags;
1005
1006 spin_lock_irqsave(&pdc_lock, flags);
1007 retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
1008 PDC_FIRM_TEST_MAGIC, ftc_bitmap);
1009 spin_unlock_irqrestore(&pdc_lock, flags);
1010
1011 return retval;
1012}
1013
1014
1015
1016
1017
1018
1019int pdc_do_reset(void)
1020{
1021 int retval;
1022 unsigned long flags;
1023
1024 spin_lock_irqsave(&pdc_lock, flags);
1025 retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
1026 spin_unlock_irqrestore(&pdc_lock, flags);
1027
1028 return retval;
1029}
1030
1031
1032
1033
1034
1035
1036
1037int __init pdc_soft_power_info(unsigned long *power_reg)
1038{
1039 int retval;
1040 unsigned long flags;
1041
1042 *power_reg = (unsigned long) (-1);
1043
1044 spin_lock_irqsave(&pdc_lock, flags);
1045 retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
1046 if (retval == PDC_OK) {
1047 convert_to_wide(pdc_result);
1048 *power_reg = f_extend(pdc_result[0]);
1049 }
1050 spin_unlock_irqrestore(&pdc_lock, flags);
1051
1052 return retval;
1053}
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066int pdc_soft_power_button(int sw_control)
1067{
1068 int retval;
1069 unsigned long flags;
1070
1071 spin_lock_irqsave(&pdc_lock, flags);
1072 retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
1073 spin_unlock_irqrestore(&pdc_lock, flags);
1074
1075 return retval;
1076}
1077
1078
1079
1080
1081
1082
1083void pdc_io_reset(void)
1084{
1085 unsigned long flags;
1086
1087 spin_lock_irqsave(&pdc_lock, flags);
1088 mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
1089 spin_unlock_irqrestore(&pdc_lock, flags);
1090}
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101void pdc_io_reset_devices(void)
1102{
1103 unsigned long flags;
1104
1105 spin_lock_irqsave(&pdc_lock, flags);
1106 mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
1107 spin_unlock_irqrestore(&pdc_lock, flags);
1108}
1109
1110
1111static int __attribute__((aligned(8))) iodc_retbuf[32];
1112static char __attribute__((aligned(64))) iodc_dbuf[4096];
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124int pdc_iodc_print(const unsigned char *str, unsigned count)
1125{
1126 unsigned int i;
1127 unsigned long flags;
1128
1129 for (i = 0; i < count && i < 79;) {
1130 switch(str[i]) {
1131 case '\n':
1132 iodc_dbuf[i+0] = '\r';
1133 iodc_dbuf[i+1] = '\n';
1134 i += 2;
1135 goto print;
1136 case '\b':
1137 i--;
1138 default:
1139 iodc_dbuf[i] = str[i];
1140 i++;
1141 break;
1142 }
1143 }
1144
1145
1146
1147
1148
1149 if (i == 79 && iodc_dbuf[i-1] != '\n') {
1150 iodc_dbuf[i+0] = '\r';
1151 iodc_dbuf[i+1] = '\n';
1152 }
1153
1154print:
1155 spin_lock_irqsave(&pdc_lock, flags);
1156 real32_call(PAGE0->mem_cons.iodc_io,
1157 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
1158 PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
1159 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0);
1160 spin_unlock_irqrestore(&pdc_lock, flags);
1161
1162 return i;
1163}
1164
1165
1166
1167
1168
1169
1170
1171int pdc_iodc_getc(void)
1172{
1173 int ch;
1174 int status;
1175 unsigned long flags;
1176
1177
1178 if (!PAGE0->mem_kbd.iodc_io)
1179 return 0;
1180
1181
1182 spin_lock_irqsave(&pdc_lock, flags);
1183 real32_call(PAGE0->mem_kbd.iodc_io,
1184 (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
1185 PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
1186 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
1187
1188 ch = *iodc_dbuf;
1189 status = *iodc_retbuf;
1190 spin_unlock_irqrestore(&pdc_lock, flags);
1191
1192 if (status == 0)
1193 return -1;
1194
1195 return ch;
1196}
1197
1198int pdc_sti_call(unsigned long func, unsigned long flags,
1199 unsigned long inptr, unsigned long outputr,
1200 unsigned long glob_cfg)
1201{
1202 int retval;
1203 unsigned long irqflags;
1204
1205 spin_lock_irqsave(&pdc_lock, irqflags);
1206 retval = real32_call(func, flags, inptr, outputr, glob_cfg);
1207 spin_unlock_irqrestore(&pdc_lock, irqflags);
1208
1209 return retval;
1210}
1211EXPORT_SYMBOL(pdc_sti_call);
1212
1213#ifdef CONFIG_64BIT
1214
1215
1216
1217
1218
1219
1220
1221int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
1222{
1223 int retval;
1224 unsigned long flags;
1225
1226 spin_lock_irqsave(&pdc_lock, flags);
1227 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
1228 memcpy(cell_info, pdc_result, sizeof(*cell_info));
1229 spin_unlock_irqrestore(&pdc_lock, flags);
1230
1231 return retval;
1232}
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
1246 unsigned long view_type, void *mem_addr)
1247{
1248 int retval;
1249 unsigned long flags;
1250 static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
1251
1252 spin_lock_irqsave(&pdc_lock, flags);
1253 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result),
1254 ploc, mod, view_type, __pa(&result));
1255 if(!retval) {
1256 *actcnt = pdc_result[0];
1257 memcpy(mem_addr, &result, *actcnt);
1258 }
1259 spin_unlock_irqrestore(&pdc_lock, flags);
1260
1261 return retval;
1262}
1263
1264
1265
1266
1267
1268
1269
1270
1271int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
1272{
1273 int retval;
1274 unsigned long flags;
1275
1276 spin_lock_irqsave(&pdc_lock, flags);
1277 retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
1278 __pa(&pdc_result), hpa);
1279 memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
1280 spin_unlock_irqrestore(&pdc_lock, flags);
1281
1282 return retval;
1283}
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
1294{
1295 int retval;
1296 unsigned long flags;
1297
1298 spin_lock_irqsave(&pdc_lock, flags);
1299 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
1300 __pa(pdc_result), cell_num);
1301 *num_entries = pdc_result[0];
1302 spin_unlock_irqrestore(&pdc_lock, flags);
1303
1304 return retval;
1305}
1306
1307
1308
1309
1310
1311
1312
1313
1314int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
1315{
1316 int retval;
1317 unsigned long flags;
1318
1319 spin_lock_irqsave(&pdc_lock, flags);
1320 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
1321 __pa(r_addr), cell_num);
1322 spin_unlock_irqrestore(&pdc_lock, flags);
1323
1324 return retval;
1325}
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
1336 unsigned long count, unsigned long offset)
1337{
1338 int retval;
1339 unsigned long flags;
1340
1341 spin_lock_irqsave(&pdc_lock, flags);
1342 retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result),
1343 __pa(pdc_result2), count, offset);
1344 *actual_len = pdc_result[0];
1345 memcpy(mem_addr, pdc_result2, *actual_len);
1346 spin_unlock_irqrestore(&pdc_lock, flags);
1347
1348 return retval;
1349}
1350
1351
1352
1353
1354
1355
1356
1357
1358int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
1359{
1360 int retval;
1361 unsigned long flags;
1362
1363 spin_lock_irqsave(&pdc_lock, flags);
1364 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ,
1365 __pa(pdc_result), pci_addr, pci_size);
1366 switch(pci_size) {
1367 case 1: *(u8 *) mem_addr = (u8) pdc_result[0];
1368 case 2: *(u16 *)mem_addr = (u16) pdc_result[0];
1369 case 4: *(u32 *)mem_addr = (u32) pdc_result[0];
1370 }
1371 spin_unlock_irqrestore(&pdc_lock, flags);
1372
1373 return retval;
1374}
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
1385{
1386 int retval;
1387 unsigned long flags;
1388
1389 spin_lock_irqsave(&pdc_lock, flags);
1390 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE,
1391 pci_addr, pci_size, val);
1392 spin_unlock_irqrestore(&pdc_lock, flags);
1393
1394 return retval;
1395}
1396#endif
1397
1398
1399
1400
1401
1402
1403
1404
1405struct narrow_stack {
1406
1407 unsigned int arg13;
1408 unsigned int arg12;
1409 unsigned int arg11;
1410 unsigned int arg10;
1411 unsigned int arg9;
1412 unsigned int arg8;
1413 unsigned int arg7;
1414 unsigned int arg6;
1415 unsigned int arg5;
1416 unsigned int arg4;
1417 unsigned int arg3;
1418 unsigned int arg2;
1419 unsigned int arg1;
1420 unsigned int arg0;
1421 unsigned int frame_marker[8];
1422 unsigned int sp;
1423
1424};
1425
1426long real32_call(unsigned long fn, ...)
1427{
1428 va_list args;
1429 extern struct narrow_stack real_stack;
1430 extern unsigned long real32_call_asm(unsigned int *,
1431 unsigned int *,
1432 unsigned int);
1433
1434 va_start(args, fn);
1435 real_stack.arg0 = va_arg(args, unsigned int);
1436 real_stack.arg1 = va_arg(args, unsigned int);
1437 real_stack.arg2 = va_arg(args, unsigned int);
1438 real_stack.arg3 = va_arg(args, unsigned int);
1439 real_stack.arg4 = va_arg(args, unsigned int);
1440 real_stack.arg5 = va_arg(args, unsigned int);
1441 real_stack.arg6 = va_arg(args, unsigned int);
1442 real_stack.arg7 = va_arg(args, unsigned int);
1443 real_stack.arg8 = va_arg(args, unsigned int);
1444 real_stack.arg9 = va_arg(args, unsigned int);
1445 real_stack.arg10 = va_arg(args, unsigned int);
1446 real_stack.arg11 = va_arg(args, unsigned int);
1447 real_stack.arg12 = va_arg(args, unsigned int);
1448 real_stack.arg13 = va_arg(args, unsigned int);
1449 va_end(args);
1450
1451 return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
1452}
1453
1454#ifdef CONFIG_64BIT
1455
1456
1457struct wide_stack {
1458 unsigned long arg0;
1459 unsigned long arg1;
1460 unsigned long arg2;
1461 unsigned long arg3;
1462 unsigned long arg4;
1463 unsigned long arg5;
1464 unsigned long arg6;
1465 unsigned long arg7;
1466 unsigned long arg8;
1467 unsigned long arg9;
1468 unsigned long arg10;
1469 unsigned long arg11;
1470 unsigned long arg12;
1471 unsigned long arg13;
1472 unsigned long frame_marker[2];
1473 unsigned long sp;
1474
1475};
1476
1477long real64_call(unsigned long fn, ...)
1478{
1479 va_list args;
1480 extern struct wide_stack real64_stack;
1481 extern unsigned long real64_call_asm(unsigned long *,
1482 unsigned long *,
1483 unsigned long);
1484
1485 va_start(args, fn);
1486 real64_stack.arg0 = va_arg(args, unsigned long);
1487 real64_stack.arg1 = va_arg(args, unsigned long);
1488 real64_stack.arg2 = va_arg(args, unsigned long);
1489 real64_stack.arg3 = va_arg(args, unsigned long);
1490 real64_stack.arg4 = va_arg(args, unsigned long);
1491 real64_stack.arg5 = va_arg(args, unsigned long);
1492 real64_stack.arg6 = va_arg(args, unsigned long);
1493 real64_stack.arg7 = va_arg(args, unsigned long);
1494 real64_stack.arg8 = va_arg(args, unsigned long);
1495 real64_stack.arg9 = va_arg(args, unsigned long);
1496 real64_stack.arg10 = va_arg(args, unsigned long);
1497 real64_stack.arg11 = va_arg(args, unsigned long);
1498 real64_stack.arg12 = va_arg(args, unsigned long);
1499 real64_stack.arg13 = va_arg(args, unsigned long);
1500 va_end(args);
1501
1502 return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn);
1503}
1504
1505#endif
1506
1507