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#include <linux/kernel.h>
45#include <linux/string.h>
46#include <linux/spinlock.h>
47#include <linux/init.h>
48#include <linux/delay.h>
49
50#include <asm/page.h>
51#include <asm/pdc.h>
52#include <asm/system.h>
53#include <asm/processor.h>
54
55#include <stdarg.h>
56
57static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
58static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
59static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
60
61
62
63
64
65
66
67
68
69
70
71
72#ifdef __LP64__
73static long real64_call(unsigned long function, ...);
74#endif
75static long real32_call(unsigned long function, ...);
76
77#if defined(__LP64__) && ! defined(CONFIG_PDC_NARROW)
78#define MEM_PDC (unsigned long)(PAGE0->mem_pdc_hi) << 32 | PAGE0->mem_pdc
79# define mem_pdc_call(args...) real64_call(MEM_PDC, args)
80#else
81#define MEM_PDC (unsigned long)PAGE0->mem_pdc
82# define mem_pdc_call(args...) real32_call(MEM_PDC, args)
83#endif
84
85
86
87
88
89
90
91
92
93static unsigned long f_extend(unsigned long address)
94{
95#ifdef CONFIG_PDC_NARROW
96 if((address & 0xff000000) == 0xf0000000)
97 return 0xf0f0f0f000000000 | (u32)address;
98
99 if((address & 0xf0000000) == 0xf0000000)
100 return 0xffffffff00000000 | (u32)address;
101#endif
102 return address;
103}
104
105
106
107
108
109
110
111
112
113static void convert_to_wide(unsigned long *addr)
114{
115#ifdef CONFIG_PDC_NARROW
116 int i;
117 unsigned *p = (unsigned int *)addr;
118 for(i = 31; i >= 0; --i)
119 addr[i] = p[i];
120#endif
121}
122
123
124
125
126
127
128
129void pdc_emergency_unlock(void)
130{
131 spin_unlock(&pdc_lock);
132}
133
134
135
136
137
138
139
140
141
142
143
144int pdc_add_valid(unsigned long address)
145{
146 int retval;
147
148 spin_lock_irq(&pdc_lock);
149 retval = mem_pdc_call(PDC_ADD_VALID, PDC_ADD_VALID_VERIFY, address);
150 spin_unlock_irq(&pdc_lock);
151
152 return retval;
153}
154
155
156
157
158
159
160
161
162
163int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len)
164{
165 int retval;
166
167 spin_lock_irq(&pdc_lock);
168 memcpy(&pdc_result, chassis_info, sizeof(*chassis_info));
169 memcpy(&pdc_result2, led_info, len);
170 retval = mem_pdc_call(PDC_CHASSIS, PDC_RETURN_CHASSIS_INFO,
171 __pa(pdc_result), __pa(pdc_result2), len);
172 memcpy(chassis_info, pdc_result, sizeof(*chassis_info));
173 memcpy(led_info, pdc_result2, len);
174 spin_unlock_irq(&pdc_lock);
175
176 return retval;
177}
178
179
180
181
182
183
184
185#ifdef __LP64__
186int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
187{
188 if (!is_pdc_pat())
189 return -1;
190
191 int retval = 0;
192
193 spin_lock_irq(&pdc_lock);
194 retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
195 spin_unlock_irq(&pdc_lock);
196
197 return retval;
198}
199#endif
200
201
202
203
204
205
206
207int pdc_chassis_disp(unsigned long disp)
208{
209 int retval = 0;
210
211 spin_lock_irq(&pdc_lock);
212 retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_DISP, disp);
213 spin_unlock_irq(&pdc_lock);
214
215 return retval;
216}
217
218
219
220
221
222
223
224
225int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
226{
227 int retval;
228
229 spin_lock_irq(&pdc_lock);
230 retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
231 convert_to_wide(pdc_result);
232 pdc_coproc_info->ccr_functional = pdc_result[0];
233 pdc_coproc_info->ccr_present = pdc_result[1];
234 pdc_coproc_info->revision = pdc_result[17];
235 pdc_coproc_info->model = pdc_result[18];
236 spin_unlock_irq(&pdc_lock);
237
238 return retval;
239}
240
241
242
243
244
245
246
247
248
249
250
251
252int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
253 void *iodc_data, unsigned int iodc_data_size)
254{
255 int retval;
256
257 spin_lock_irq(&pdc_lock);
258 retval = mem_pdc_call(PDC_IODC, PDC_IODC_READ, __pa(pdc_result), hpa,
259 index, __pa(pdc_result2), iodc_data_size);
260 convert_to_wide(pdc_result);
261 *actcnt = pdc_result[0];
262 memcpy(iodc_data, pdc_result2, iodc_data_size);
263 spin_unlock_irq(&pdc_lock);
264
265 return retval;
266}
267
268
269
270
271
272
273
274
275
276
277int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
278 struct pdc_module_path *mod_path, long mod_index)
279{
280 int retval;
281
282 spin_lock_irq(&pdc_lock);
283 retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result),
284 __pa(pdc_result2), mod_index);
285 convert_to_wide(pdc_result);
286 memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info));
287 memcpy(mod_path, pdc_result2, sizeof(*mod_path));
288 spin_unlock_irq(&pdc_lock);
289
290 pdc_mod_info->mod_addr = f_extend(pdc_mod_info->mod_addr);
291 return retval;
292}
293
294
295
296
297
298
299
300
301
302
303int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
304 long mod_index, long addr_index)
305{
306 int retval;
307
308 spin_lock_irq(&pdc_lock);
309 retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_ADDRESS, __pa(pdc_result),
310 mod_index, addr_index);
311 convert_to_wide(pdc_result);
312 memcpy(pdc_addr_info, pdc_result, sizeof(*pdc_addr_info));
313 spin_unlock_irq(&pdc_lock);
314
315 pdc_addr_info->mod_addr = f_extend(pdc_addr_info->mod_addr);
316 return retval;
317}
318
319
320
321
322
323
324
325int pdc_model_info(struct pdc_model *model)
326{
327 int retval;
328
329 spin_lock_irq(&pdc_lock);
330 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_INFO, __pa(pdc_result), 0);
331 convert_to_wide(pdc_result);
332 memcpy(model, pdc_result, sizeof(*model));
333 spin_unlock_irq(&pdc_lock);
334
335 return retval;
336}
337
338
339
340
341
342
343
344int pdc_model_sysmodel(char *name)
345{
346 int retval;
347
348 spin_lock_irq(&pdc_lock);
349 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_SYSMODEL, __pa(pdc_result),
350 OS_ID_HPUX, __pa(name));
351 convert_to_wide(pdc_result);
352
353 if (retval == PDC_OK) {
354 name[pdc_result[0]] = '\0';
355 } else {
356 name[0] = 0;
357 }
358 spin_unlock_irq(&pdc_lock);
359
360 return retval;
361}
362
363
364
365
366
367
368
369
370
371
372
373int pdc_model_versions(unsigned long *versions, int id)
374{
375 int retval;
376
377 spin_lock_irq(&pdc_lock);
378 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_VERSIONS, __pa(pdc_result), id);
379 convert_to_wide(pdc_result);
380 *versions = pdc_result[0];
381 spin_unlock_irq(&pdc_lock);
382
383 return retval;
384}
385
386
387
388
389
390
391
392
393int pdc_model_cpuid(unsigned long *cpu_id)
394{
395 int retval;
396
397 spin_lock_irq(&pdc_lock);
398 pdc_result[0] = 0;
399 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CPU_ID, __pa(pdc_result), 0);
400 convert_to_wide(pdc_result);
401 *cpu_id = pdc_result[0];
402 spin_unlock_irq(&pdc_lock);
403
404 return retval;
405}
406
407
408
409
410
411
412
413
414int pdc_model_capabilities(unsigned long *capabilities)
415{
416 int retval;
417
418 spin_lock_irq(&pdc_lock);
419 pdc_result[0] = 0;
420 retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
421 convert_to_wide(pdc_result);
422 *capabilities = pdc_result[0];
423 spin_unlock_irq(&pdc_lock);
424
425 return retval;
426}
427
428
429
430
431
432
433
434int pdc_cache_info(struct pdc_cache_info *cache_info)
435{
436 int retval;
437
438 spin_lock_irq(&pdc_lock);
439 retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_INFO, __pa(pdc_result), 0);
440 convert_to_wide(pdc_result);
441 memcpy(cache_info, pdc_result, sizeof(*cache_info));
442 spin_unlock_irq(&pdc_lock);
443
444 return retval;
445}
446
447#ifndef CONFIG_PA20
448
449
450
451
452
453
454int pdc_btlb_info(struct pdc_btlb_info *btlb)
455{
456 int retval;
457
458 spin_lock_irq(&pdc_lock);
459 retval = mem_pdc_call(PDC_BLOCK_TLB, PDC_BTLB_INFO, __pa(pdc_result), 0);
460 memcpy(btlb, pdc_result, sizeof(*btlb));
461 spin_unlock_irq(&pdc_lock);
462
463 if(retval < 0) {
464 btlb->max_size = 0;
465 }
466 return retval;
467}
468
469
470
471
472
473
474
475
476
477
478
479
480
481int pdc_mem_map_hpa(struct pdc_memory_map *address,
482 struct pdc_module_path *mod_path)
483{
484 int retval;
485
486 spin_lock_irq(&pdc_lock);
487 memcpy(pdc_result2, mod_path, sizeof(*mod_path));
488 retval = mem_pdc_call(PDC_MEM_MAP, PDC_MEM_MAP_HPA, __pa(pdc_result),
489 __pa(pdc_result2));
490 memcpy(address, pdc_result, sizeof(*address));
491 spin_unlock_irq(&pdc_lock);
492
493 return retval;
494}
495#endif
496
497
498
499
500
501
502
503
504int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
505{
506 int retval;
507
508 spin_lock_irq(&pdc_lock);
509 retval = mem_pdc_call(PDC_LAN_STATION_ID, PDC_LAN_STATION_ID_READ,
510 __pa(pdc_result), hpa);
511 if (retval < 0) {
512
513 memset(lan_addr, 0, PDC_LAN_STATION_ID_SIZE);
514 } else {
515 memcpy(lan_addr, pdc_result, PDC_LAN_STATION_ID_SIZE);
516 }
517 spin_unlock_irq(&pdc_lock);
518
519 return retval;
520}
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540int pdc_get_initiator( struct hardware_path *hwpath, unsigned char *scsi_id,
541 unsigned long *period, char *width, char *mode)
542{
543 int retval;
544
545 spin_lock_irq(&pdc_lock);
546
547
548#define IS_SPROCKETS() (strlen(boot_cpu_data.pdc.sys_model_name) == 14 && \
549 strncmp(boot_cpu_data.pdc.sys_model_name, "9000/785", 8) == 0)
550
551 retval = mem_pdc_call(PDC_INITIATOR, PDC_GET_INITIATOR,
552 __pa(pdc_result), __pa(hwpath));
553
554 if (retval >= PDC_OK) {
555 *scsi_id = (unsigned char) pdc_result[0];
556
557
558 switch(pdc_result[1]) {
559
560
561
562
563 case 5: *period = 2000; break;
564 case 10: *period = 1000; break;
565 case 20: *period = 500; break;
566 case 40: *period = 250; break;
567 default: break;
568 }
569
570
571
572
573
574
575
576
577
578
579 if (IS_SPROCKETS()) {
580
581
582
583
584 *width = (char) pdc_result[4];
585
586
587
588
589
590
591 *mode = (char) pdc_result[5];
592 }
593 }
594
595 spin_unlock_irq(&pdc_lock);
596 return retval >= PDC_OK;
597}
598
599
600
601
602
603
604
605
606
607
608
609int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa)
610{
611 int retval;
612
613 spin_lock_irq(&pdc_lock);
614 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SIZE,
615 __pa(pdc_result), hpa);
616 convert_to_wide(pdc_result);
617 *num_entries = pdc_result[0];
618 spin_unlock_irq(&pdc_lock);
619
620 return retval;
621}
622
623
624
625
626
627
628
629
630
631
632int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl)
633{
634 int retval;
635
636 spin_lock_irq(&pdc_lock);
637 pdc_result[0] = num_entries;
638 retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
639 __pa(pdc_result), hpa, __pa(tbl));
640 spin_unlock_irq(&pdc_lock);
641
642 return retval;
643}
644
645
646
647
648
649
650
651
652int pdc_tod_read(struct pdc_tod *tod)
653{
654 int retval;
655
656 spin_lock_irq(&pdc_lock);
657 retval = mem_pdc_call(PDC_TOD, PDC_TOD_READ, __pa(pdc_result), 0);
658 convert_to_wide(pdc_result);
659 memcpy(tod, pdc_result, sizeof(*tod));
660 spin_unlock_irq(&pdc_lock);
661
662 return retval;
663}
664
665
666
667
668
669
670
671
672int pdc_tod_set(unsigned long sec, unsigned long usec)
673{
674 int retval;
675
676 spin_lock_irq(&pdc_lock);
677 retval = mem_pdc_call(PDC_TOD, PDC_TOD_WRITE, sec, usec);
678 spin_unlock_irq(&pdc_lock);
679
680 return retval;
681}
682
683#ifdef __LP64__
684int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
685 struct pdc_memory_table *tbl, unsigned long entries)
686{
687 int retval;
688
689 spin_lock_irq(&pdc_lock);
690 retval = mem_pdc_call(PDC_MEM, PDC_MEM_TABLE, __pa(pdc_result), __pa(pdc_result2), entries);
691 convert_to_wide(pdc_result);
692 memcpy(r_addr, pdc_result, sizeof(*r_addr));
693 memcpy(tbl, pdc_result2, entries * sizeof(*tbl));
694 spin_unlock_irq(&pdc_lock);
695
696 return retval;
697}
698#endif
699
700
701
702
703
704int pdc_do_firm_test_reset(unsigned long ftc_bitmap)
705{
706 int retval;
707
708 spin_lock_irq(&pdc_lock);
709 retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_FIRM_TEST_RESET,
710 PDC_FIRM_TEST_MAGIC, ftc_bitmap);
711 spin_unlock_irq(&pdc_lock);
712
713 return retval;
714}
715
716
717
718
719
720
721int pdc_do_reset()
722{
723 int retval;
724
725 spin_lock_irq(&pdc_lock);
726 retval = mem_pdc_call(PDC_BROADCAST_RESET, PDC_DO_RESET);
727 spin_unlock_irq(&pdc_lock);
728
729 return retval;
730}
731
732
733
734
735
736
737
738int __init pdc_soft_power_info(unsigned long *power_reg)
739{
740 int retval;
741
742 *power_reg = (unsigned long) (-1);
743
744 spin_lock_irq(&pdc_lock);
745 retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, __pa(pdc_result), 0);
746 if (retval == PDC_OK) {
747 convert_to_wide(pdc_result);
748 *power_reg = f_extend(pdc_result[0]);
749 }
750 spin_unlock_irq(&pdc_lock);
751
752 return retval;
753}
754
755
756
757
758
759
760
761
762
763
764
765
766int pdc_soft_power_button(int sw_control)
767{
768 int retval;
769 spin_lock_irq(&pdc_lock);
770 retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
771 spin_unlock_irq(&pdc_lock);
772 return retval;
773}
774
775
776
777
778
779
780
781
782
783void pdc_suspend_usb(void)
784{
785 spin_lock_irq(&pdc_lock);
786 mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0);
787 spin_unlock_irq(&pdc_lock);
788}
789
790
791
792
793
794
795
796
797
798
799void pdc_iodc_putc(unsigned char c)
800{
801
802 static int posx;
803 static int __attribute__((aligned(8))) iodc_retbuf[32];
804 static char __attribute__((aligned(64))) iodc_dbuf[4096];
805 unsigned int n;
806 unsigned int flags;
807
808 switch (c) {
809 case '\n':
810 iodc_dbuf[0] = '\r';
811 iodc_dbuf[1] = '\n';
812 n = 2;
813 posx = 0;
814 break;
815 case '\t':
816 pdc_iodc_putc(' ');
817 while (posx & 7)
818 pdc_iodc_putc(' ');
819 return;
820 case '\b':
821 posx-=2;
822 default:
823 iodc_dbuf[0] = c;
824 n = 1;
825 posx++;
826 break;
827 }
828
829 spin_lock_irqsave(&pdc_lock, flags);
830 real32_call(PAGE0->mem_cons.iodc_io,
831 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
832 PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
833 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
834 spin_unlock_irqrestore(&pdc_lock, flags);
835}
836
837
838
839
840
841
842
843void pdc_iodc_outc(unsigned char c)
844{
845 unsigned int n, flags;
846
847
848 static int __attribute__((aligned(8))) iodc_retbuf[32];
849 static char __attribute__((aligned(64))) iodc_dbuf[4096];
850
851 n = 1;
852 iodc_dbuf[0] = c;
853
854 spin_lock_irqsave(&pdc_lock, flags);
855 real32_call(PAGE0->mem_cons.iodc_io,
856 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
857 PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
858 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), n, 0);
859 spin_unlock_irqrestore(&pdc_lock, flags);
860}
861
862
863
864
865
866
867
868int pdc_iodc_getc(void)
869{
870 unsigned int flags;
871 static int __attribute__((aligned(8))) iodc_retbuf[32];
872 static char __attribute__((aligned(64))) iodc_dbuf[4096];
873 int ch;
874 int status;
875
876
877 if (!PAGE0->mem_kbd.iodc_io)
878 return 0;
879
880
881 spin_lock_irqsave(&pdc_lock, flags);
882 real32_call(PAGE0->mem_kbd.iodc_io,
883 (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
884 PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
885 __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
886
887 ch = *iodc_dbuf;
888 status = *iodc_retbuf;
889 spin_unlock_irqrestore(&pdc_lock, flags);
890
891 if (status == 0)
892 return -1;
893
894 return ch;
895}
896
897int pdc_sti_call(unsigned long func, unsigned long flags,
898 unsigned long inptr, unsigned long outputr,
899 unsigned long glob_cfg)
900{
901 int retval;
902
903 spin_lock_irq(&pdc_lock);
904 retval = real32_call(func, flags, inptr, outputr, glob_cfg);
905 spin_unlock_irq(&pdc_lock);
906
907 return retval;
908}
909
910#ifdef __LP64__
911
912
913
914
915
916
917
918int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info)
919{
920 int retval;
921
922 spin_lock_irq(&pdc_lock);
923 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_NUMBER, __pa(pdc_result));
924 memcpy(cell_info, pdc_result, sizeof(*cell_info));
925 spin_unlock_irq(&pdc_lock);
926
927 return retval;
928}
929
930
931
932
933
934
935
936
937
938
939
940
941int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
942 unsigned long view_type, void *mem_addr)
943{
944 int retval;
945 static struct pdc_pat_cell_mod_maddr_block result __attribute__ ((aligned (8)));
946
947 spin_lock_irq(&pdc_lock);
948 retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_MODULE, __pa(pdc_result),
949 ploc, mod, view_type, __pa(&result));
950 if(!retval) {
951 *actcnt = pdc_result[0];
952 memcpy(mem_addr, &result, *actcnt);
953 }
954 spin_unlock_irq(&pdc_lock);
955
956 return retval;
957}
958
959
960
961
962
963
964
965
966int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa)
967{
968 int retval;
969
970 spin_lock_irq(&pdc_lock);
971 retval = mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_GET_NUMBER,
972 __pa(&pdc_result), hpa);
973 memcpy(cpu_info, pdc_result, sizeof(*cpu_info));
974 spin_unlock_irq(&pdc_lock);
975
976 return retval;
977}
978
979
980
981
982
983
984
985
986
987int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num)
988{
989 int retval;
990
991 spin_lock_irq(&pdc_lock);
992 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE,
993 __pa(pdc_result), cell_num);
994 *num_entries = pdc_result[0];
995 spin_unlock_irq(&pdc_lock);
996
997 return retval;
998}
999
1000
1001
1002
1003
1004
1005
1006
1007int pdc_pat_get_irt(void *r_addr, unsigned long cell_num)
1008{
1009 int retval;
1010
1011 spin_lock_irq(&pdc_lock);
1012 retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_GET_PCI_ROUTING_TABLE,
1013 __pa(r_addr), cell_num);
1014 spin_unlock_irq(&pdc_lock);
1015
1016 return retval;
1017}
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
1028 unsigned long count, unsigned long offset)
1029{
1030 int retval;
1031
1032 spin_lock_irq(&pdc_lock);
1033 retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_ADDR_MAP, __pa(pdc_result),
1034 __pa(pdc_result2), count, offset);
1035 *actual_len = pdc_result[0];
1036 memcpy(mem_addr, pdc_result2, *actual_len);
1037 spin_unlock_irq(&pdc_lock);
1038
1039 return retval;
1040}
1041#endif
1042
1043
1044
1045
1046
1047
1048
1049
1050struct narrow_stack {
1051
1052 unsigned int arg13;
1053 unsigned int arg12;
1054 unsigned int arg11;
1055 unsigned int arg10;
1056 unsigned int arg9;
1057 unsigned int arg8;
1058 unsigned int arg7;
1059 unsigned int arg6;
1060 unsigned int arg5;
1061 unsigned int arg4;
1062 unsigned int arg3;
1063 unsigned int arg2;
1064 unsigned int arg1;
1065 unsigned int arg0;
1066 unsigned int frame_marker[8];
1067 unsigned int sp;
1068
1069};
1070
1071static long real32_call(unsigned long fn, ...)
1072{
1073 va_list args;
1074 extern struct narrow_stack real_stack;
1075 extern unsigned long real32_call_asm(unsigned int *,
1076 unsigned int *,
1077 unsigned int);
1078
1079 va_start(args, fn);
1080 real_stack.arg0 = va_arg(args, unsigned int);
1081 real_stack.arg1 = va_arg(args, unsigned int);
1082 real_stack.arg2 = va_arg(args, unsigned int);
1083 real_stack.arg3 = va_arg(args, unsigned int);
1084 real_stack.arg4 = va_arg(args, unsigned int);
1085 real_stack.arg5 = va_arg(args, unsigned int);
1086 real_stack.arg6 = va_arg(args, unsigned int);
1087 real_stack.arg7 = va_arg(args, unsigned int);
1088 real_stack.arg8 = va_arg(args, unsigned int);
1089 real_stack.arg9 = va_arg(args, unsigned int);
1090 real_stack.arg10 = va_arg(args, unsigned int);
1091 real_stack.arg11 = va_arg(args, unsigned int);
1092 real_stack.arg12 = va_arg(args, unsigned int);
1093 real_stack.arg13 = va_arg(args, unsigned int);
1094 va_end(args);
1095
1096 return real32_call_asm(&real_stack.sp, &real_stack.arg0, fn);
1097}
1098
1099#ifdef __LP64__
1100
1101
1102struct wide_stack {
1103 unsigned long arg0;
1104 unsigned long arg1;
1105 unsigned long arg2;
1106 unsigned long arg3;
1107 unsigned long arg4;
1108 unsigned long arg5;
1109 unsigned long arg6;
1110 unsigned long arg7;
1111 unsigned long arg8;
1112 unsigned long arg9;
1113 unsigned long arg10;
1114 unsigned long arg11;
1115 unsigned long arg12;
1116 unsigned long arg13;
1117 unsigned long frame_marker[2];
1118 unsigned long sp;
1119
1120};
1121
1122static long real64_call(unsigned long fn, ...)
1123{
1124 va_list args;
1125 extern struct wide_stack real_stack;
1126 extern unsigned long real64_call_asm(unsigned long *,
1127 unsigned long *,
1128 unsigned long);
1129
1130 va_start(args, fn);
1131 real_stack.arg0 = va_arg(args, unsigned long);
1132 real_stack.arg1 = va_arg(args, unsigned long);
1133 real_stack.arg2 = va_arg(args, unsigned long);
1134 real_stack.arg3 = va_arg(args, unsigned long);
1135 real_stack.arg4 = va_arg(args, unsigned long);
1136 real_stack.arg5 = va_arg(args, unsigned long);
1137 real_stack.arg6 = va_arg(args, unsigned long);
1138 real_stack.arg7 = va_arg(args, unsigned long);
1139 real_stack.arg8 = va_arg(args, unsigned long);
1140 real_stack.arg9 = va_arg(args, unsigned long);
1141 real_stack.arg10 = va_arg(args, unsigned long);
1142 real_stack.arg11 = va_arg(args, unsigned long);
1143 real_stack.arg12 = va_arg(args, unsigned long);
1144 real_stack.arg13 = va_arg(args, unsigned long);
1145 va_end(args);
1146
1147 return real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
1148}
1149
1150#endif
1151
1152