1 | /* |
---|
2 | * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation |
---|
3 | * |
---|
4 | * This program is free software; you can redistribute it and/or modify |
---|
5 | * it under the terms of the GNU General Public License as published by |
---|
6 | * the Free Software Foundation; either version 2 of the License, or |
---|
7 | * (at your option) any later version. |
---|
8 | * |
---|
9 | * This program is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | * GNU General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU General Public License |
---|
15 | * along with this program; if not, write to the Free Software |
---|
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
17 | * |
---|
18 | */ |
---|
19 | #include <asm/config.h> |
---|
20 | #include <asm/processor.h> |
---|
21 | |
---|
22 | .macro save_gprs rsave, rend, off, rbase |
---|
23 | std \rsave, \off(\rbase) |
---|
24 | .if \rend-\rsave |
---|
25 | save_gprs "(\rsave+1)",\rend,"(\off+8)",\rbase |
---|
26 | .endif |
---|
27 | .endm |
---|
28 | |
---|
29 | .macro restore_gprs rsave, rend, off, rbase |
---|
30 | ld \rsave, \off(\rbase) |
---|
31 | .if \rend-\rsave |
---|
32 | restore_gprs "(\rsave+1)",\rend,"(\off+8)",\rbase |
---|
33 | .endif |
---|
34 | .endm |
---|
35 | |
---|
36 | /* |
---|
37 | * s32 prom_call(void *arg, ulong base, ulong func, ulong msr); |
---|
38 | * r3 is arg pointer |
---|
39 | * r4 is RTAS base, should be 0 for OF |
---|
40 | * r5 is Prom vector |
---|
41 | * r6 is the MSR we should use |
---|
42 | */ |
---|
43 | _GLOBAL(prom_call) |
---|
44 | SET_REG_TO_LABEL(r7, gpr_store) |
---|
45 | |
---|
46 | std r1, 0(r7) |
---|
47 | std r2, 8(r7) |
---|
48 | SAVE_GPRS r13, r31, 16, r7 # save all volatiles |
---|
49 | |
---|
50 | /* |
---|
51 | * We can stuff the LT, MSR, SRR0/1 into GPRS that the caller |
---|
52 | * must retore |
---|
53 | */ |
---|
54 | |
---|
55 | mflr r18 |
---|
56 | sradi r19, r18, 32 /* store lr in r18, r19 */ |
---|
57 | |
---|
58 | mfmsr r20 |
---|
59 | sradi r21, r20, 32 /* r20,r21 contain caller's msr */ |
---|
60 | |
---|
61 | /* save SRR0/1 */ |
---|
62 | mfsrr0 r24 |
---|
63 | sradi r25, r24, 32 |
---|
64 | mfsrr1 r26 |
---|
65 | sradi r27, r26, 32 |
---|
66 | |
---|
67 | bl go_to_real |
---|
68 | |
---|
69 | /* come back here after rfid in "native_of_call" */ |
---|
70 | insrdi r18, r19, 32, 0 /* restore lr */ |
---|
71 | mtlr r18 |
---|
72 | |
---|
73 | /* restore SRR0/1 */ |
---|
74 | insrdi r24, r25, 32, 0 |
---|
75 | mtsrr0 r24 |
---|
76 | insrdi r26, r27, 32, 0 |
---|
77 | mtsrr1 r26 |
---|
78 | |
---|
79 | |
---|
80 | |
---|
81 | SET_REG_TO_LABEL(r7, gpr_store) |
---|
82 | |
---|
83 | ld r1, 0(r7) |
---|
84 | ld r2, 8(r7) |
---|
85 | RESTORE_GPRS r13, r31, 16, r7 |
---|
86 | blr |
---|
87 | |
---|
88 | native_call: |
---|
89 | mtctr r5 |
---|
90 | bctrl /* call of or rtas */ |
---|
91 | |
---|
92 | insrdi r22, r23, 32, 0 /* reconstruct return point iar */ |
---|
93 | insrdi r20, r21, 32, 0 /* reconstruct caller's msr */ |
---|
94 | |
---|
95 | mtsrr0 r22 |
---|
96 | mtsrr1 r20 |
---|
97 | rfid |
---|
98 | |
---|
99 | |
---|
100 | go_to_real: |
---|
101 | mflr r22 |
---|
102 | sradi r23, r22, 32 /* save address we rfid back to*/ |
---|
103 | |
---|
104 | SET_REG_TO_LABEL(r8, native_call) |
---|
105 | |
---|
106 | mtsrr0 r8 |
---|
107 | mtsrr1 r6 |
---|
108 | rfid |
---|
109 | |
---|
110 | |
---|
111 | .data |
---|
112 | .p2align 3 |
---|
113 | gpr_store: |
---|
114 | .space 8 # r1 |
---|
115 | .space 8 # r2 |
---|
116 | .space (32 - 13) * 8 # r13 - r31 |
---|