diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/parisc/kernel/real2.S |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/parisc/kernel/real2.S')
-rw-r--r-- | arch/parisc/kernel/real2.S | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S new file mode 100644 index 000000000000..8dd5defb7316 --- /dev/null +++ b/arch/parisc/kernel/real2.S | |||
@@ -0,0 +1,304 @@ | |||
1 | /* | ||
2 | * | ||
3 | * This file is subject to the terms and conditions of the GNU General Public | ||
4 | * License. See the file "COPYING" in the main directory of this archive | ||
5 | * for more details. | ||
6 | * | ||
7 | * Copyright (C) 2000 Hewlett Packard (Paul Bame bame@puffin.external.hp.com) | ||
8 | * | ||
9 | */ | ||
10 | #include <asm/assembly.h> | ||
11 | #include <asm/psw.h> | ||
12 | |||
13 | .section .bss | ||
14 | .export real_stack | ||
15 | .export real32_stack | ||
16 | .export real64_stack | ||
17 | .align 64 | ||
18 | real_stack: | ||
19 | real32_stack: | ||
20 | real64_stack: | ||
21 | .block 8192 | ||
22 | |||
23 | #ifdef __LP64__ | ||
24 | # define REG_SZ 8 | ||
25 | #else | ||
26 | # define REG_SZ 4 | ||
27 | #endif | ||
28 | |||
29 | #define N_SAVED_REGS 9 | ||
30 | |||
31 | save_cr_space: | ||
32 | .block REG_SZ * N_SAVED_REGS | ||
33 | save_cr_end: | ||
34 | |||
35 | |||
36 | /************************ 32-bit real-mode calls ***********************/ | ||
37 | /* This can be called in both narrow and wide kernels */ | ||
38 | |||
39 | .text | ||
40 | |||
41 | .export real32_call_asm | ||
42 | |||
43 | /* unsigned long real32_call_asm(unsigned int *sp, | ||
44 | * unsigned int *arg0p, | ||
45 | * unsigned int iodc_fn) | ||
46 | * sp is value of stack pointer to adopt before calling PDC (virt) | ||
47 | * arg0p points to where saved arg values may be found | ||
48 | * iodc_fn is the IODC function to call | ||
49 | */ | ||
50 | |||
51 | real32_call_asm: | ||
52 | STREG %rp, -RP_OFFSET(%sp) /* save RP */ | ||
53 | #ifdef __LP64__ | ||
54 | callee_save | ||
55 | ldo 2*REG_SZ(%sp), %sp /* room for a couple more saves */ | ||
56 | STREG %r27, -1*REG_SZ(%sp) | ||
57 | STREG %r29, -2*REG_SZ(%sp) | ||
58 | #endif | ||
59 | STREG %sp, -REG_SZ(%arg0) /* save SP on real-mode stack */ | ||
60 | copy %arg0, %sp /* adopt the real-mode SP */ | ||
61 | |||
62 | /* save iodc_fn */ | ||
63 | copy %arg2, %r31 | ||
64 | |||
65 | /* load up the arg registers from the saved arg area */ | ||
66 | /* 32-bit calling convention passes first 4 args in registers */ | ||
67 | ldw 0(%arg1), %arg0 /* note overwriting arg0 */ | ||
68 | ldw -8(%arg1), %arg2 | ||
69 | ldw -12(%arg1), %arg3 | ||
70 | ldw -4(%arg1), %arg1 /* obviously must do this one last! */ | ||
71 | |||
72 | tophys_r1 %sp | ||
73 | |||
74 | b,l rfi_virt2real,%r2 | ||
75 | nop | ||
76 | |||
77 | b,l save_control_regs,%r2 /* modifies r1, r2, r28 */ | ||
78 | nop | ||
79 | |||
80 | #ifdef __LP64__ | ||
81 | rsm PSW_SM_W, %r0 /* go narrow */ | ||
82 | #endif | ||
83 | |||
84 | load32 PA(ric_ret), %r2 | ||
85 | bv 0(%r31) | ||
86 | nop | ||
87 | ric_ret: | ||
88 | #ifdef __LP64__ | ||
89 | ssm PSW_SM_W, %r0 /* go wide */ | ||
90 | #endif | ||
91 | /* restore CRs before going virtual in case we page fault */ | ||
92 | b,l restore_control_regs, %r2 /* modifies r1, r2, r26 */ | ||
93 | nop | ||
94 | |||
95 | b,l rfi_real2virt,%r2 | ||
96 | nop | ||
97 | |||
98 | tovirt_r1 %sp | ||
99 | LDREG -REG_SZ(%sp), %sp /* restore SP */ | ||
100 | #ifdef __LP64__ | ||
101 | LDREG -1*REG_SZ(%sp), %r27 | ||
102 | LDREG -2*REG_SZ(%sp), %r29 | ||
103 | ldo -2*REG_SZ(%sp), %sp | ||
104 | callee_rest | ||
105 | #endif | ||
106 | LDREG -RP_OFFSET(%sp), %rp /* restore RP */ | ||
107 | bv 0(%rp) | ||
108 | nop | ||
109 | |||
110 | |||
111 | # define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where) | ||
112 | # define POP_CR(r, where) LDREG,mb -REG_SZ(where), %r1 ! mtctl %r1, r | ||
113 | |||
114 | .text | ||
115 | save_control_regs: | ||
116 | load32 PA(save_cr_space), %r28 | ||
117 | PUSH_CR(%cr24, %r28) | ||
118 | PUSH_CR(%cr25, %r28) | ||
119 | PUSH_CR(%cr26, %r28) | ||
120 | PUSH_CR(%cr27, %r28) | ||
121 | PUSH_CR(%cr28, %r28) | ||
122 | PUSH_CR(%cr29, %r28) | ||
123 | PUSH_CR(%cr30, %r28) | ||
124 | PUSH_CR(%cr31, %r28) | ||
125 | PUSH_CR(%cr15, %r28) | ||
126 | bv 0(%r2) | ||
127 | nop | ||
128 | |||
129 | restore_control_regs: | ||
130 | load32 PA(save_cr_end), %r26 | ||
131 | POP_CR(%cr15, %r26) | ||
132 | POP_CR(%cr31, %r26) | ||
133 | POP_CR(%cr30, %r26) | ||
134 | POP_CR(%cr29, %r26) | ||
135 | POP_CR(%cr28, %r26) | ||
136 | POP_CR(%cr27, %r26) | ||
137 | POP_CR(%cr26, %r26) | ||
138 | POP_CR(%cr25, %r26) | ||
139 | POP_CR(%cr24, %r26) | ||
140 | bv 0(%r2) | ||
141 | nop | ||
142 | |||
143 | /* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for | ||
144 | * more general-purpose use by the several places which need RFIs | ||
145 | */ | ||
146 | .align 128 | ||
147 | .text | ||
148 | rfi_virt2real: | ||
149 | /* switch to real mode... */ | ||
150 | ssm 0,0 /* See "relied upon translation" */ | ||
151 | nop /* PA 2.0 Arch. F-5 */ | ||
152 | nop | ||
153 | nop | ||
154 | nop | ||
155 | nop | ||
156 | nop | ||
157 | nop | ||
158 | nop | ||
159 | |||
160 | rsm (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q & I bits to load iia queue */ | ||
161 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | ||
162 | mtctl %r0, %cr17 /* Clear IIASQ head */ | ||
163 | load32 PA(rfi_v2r_1), %r1 | ||
164 | mtctl %r1, %cr18 /* IIAOQ head */ | ||
165 | ldo 4(%r1), %r1 | ||
166 | mtctl %r1, %cr18 /* IIAOQ tail */ | ||
167 | load32 REAL_MODE_PSW, %r1 | ||
168 | mtctl %r1, %cr22 | ||
169 | rfi | ||
170 | |||
171 | nop | ||
172 | nop | ||
173 | nop | ||
174 | nop | ||
175 | nop | ||
176 | nop | ||
177 | nop | ||
178 | nop | ||
179 | rfi_v2r_1: | ||
180 | tophys_r1 %r2 | ||
181 | bv 0(%r2) | ||
182 | nop | ||
183 | |||
184 | .text | ||
185 | .align 128 | ||
186 | rfi_real2virt: | ||
187 | ssm 0,0 /* See "relied upon translation" */ | ||
188 | nop /* PA 2.0 Arch. F-5 */ | ||
189 | nop | ||
190 | nop | ||
191 | nop | ||
192 | nop | ||
193 | nop | ||
194 | nop | ||
195 | nop | ||
196 | |||
197 | rsm PSW_SM_Q,%r0 /* disable Q bit to load iia queue */ | ||
198 | mtctl %r0, %cr17 /* Clear IIASQ tail */ | ||
199 | mtctl %r0, %cr17 /* Clear IIASQ head */ | ||
200 | load32 (rfi_r2v_1), %r1 | ||
201 | mtctl %r1, %cr18 /* IIAOQ head */ | ||
202 | ldo 4(%r1), %r1 | ||
203 | mtctl %r1, %cr18 /* IIAOQ tail */ | ||
204 | load32 KERNEL_PSW, %r1 | ||
205 | mtctl %r1, %cr22 | ||
206 | rfi | ||
207 | |||
208 | nop | ||
209 | nop | ||
210 | nop | ||
211 | nop | ||
212 | nop | ||
213 | nop | ||
214 | nop | ||
215 | nop | ||
216 | rfi_r2v_1: | ||
217 | tovirt_r1 %r2 | ||
218 | bv 0(%r2) | ||
219 | nop | ||
220 | |||
221 | #ifdef __LP64__ | ||
222 | |||
223 | /************************ 64-bit real-mode calls ***********************/ | ||
224 | /* This is only usable in wide kernels right now and will probably stay so */ | ||
225 | .text | ||
226 | .export real64_call_asm | ||
227 | /* unsigned long real64_call_asm(unsigned long *sp, | ||
228 | * unsigned long *arg0p, | ||
229 | * unsigned long fn) | ||
230 | * sp is value of stack pointer to adopt before calling PDC (virt) | ||
231 | * arg0p points to where saved arg values may be found | ||
232 | * iodc_fn is the IODC function to call | ||
233 | */ | ||
234 | real64_call_asm: | ||
235 | std %rp, -0x10(%sp) /* save RP */ | ||
236 | std %sp, -8(%arg0) /* save SP on real-mode stack */ | ||
237 | copy %arg0, %sp /* adopt the real-mode SP */ | ||
238 | |||
239 | /* save fn */ | ||
240 | copy %arg2, %r31 | ||
241 | |||
242 | /* set up the new ap */ | ||
243 | ldo 64(%arg1), %r29 | ||
244 | |||
245 | /* load up the arg registers from the saved arg area */ | ||
246 | /* 32-bit calling convention passes first 4 args in registers */ | ||
247 | ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */ | ||
248 | ldd 2*REG_SZ(%arg1), %arg2 | ||
249 | ldd 3*REG_SZ(%arg1), %arg3 | ||
250 | ldd 4*REG_SZ(%arg1), %r22 | ||
251 | ldd 5*REG_SZ(%arg1), %r21 | ||
252 | ldd 6*REG_SZ(%arg1), %r20 | ||
253 | ldd 7*REG_SZ(%arg1), %r19 | ||
254 | ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */ | ||
255 | |||
256 | tophys_r1 %sp | ||
257 | |||
258 | b,l rfi_virt2real,%r2 | ||
259 | nop | ||
260 | |||
261 | b,l save_control_regs,%r2 /* modifies r1, r2, r28 */ | ||
262 | nop | ||
263 | |||
264 | load32 PA(r64_ret), %r2 | ||
265 | bv 0(%r31) | ||
266 | nop | ||
267 | r64_ret: | ||
268 | /* restore CRs before going virtual in case we page fault */ | ||
269 | b,l restore_control_regs, %r2 /* modifies r1, r2, r26 */ | ||
270 | nop | ||
271 | |||
272 | b,l rfi_real2virt,%r2 | ||
273 | nop | ||
274 | |||
275 | tovirt_r1 %sp | ||
276 | ldd -8(%sp), %sp /* restore SP */ | ||
277 | ldd -0x10(%sp), %rp /* restore RP */ | ||
278 | bv 0(%rp) | ||
279 | nop | ||
280 | |||
281 | #endif | ||
282 | |||
283 | .export pc_in_user_space | ||
284 | .text | ||
285 | /* Doesn't belong here but I couldn't find a nicer spot. */ | ||
286 | /* Should never get called, only used by profile stuff in time.c */ | ||
287 | pc_in_user_space: | ||
288 | bv,n 0(%rp) | ||
289 | nop | ||
290 | |||
291 | |||
292 | .export __canonicalize_funcptr_for_compare | ||
293 | .text | ||
294 | /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html | ||
295 | ** GCC 3.3 and later has a new function in libgcc.a for | ||
296 | ** comparing function pointers. | ||
297 | */ | ||
298 | __canonicalize_funcptr_for_compare: | ||
299 | #ifdef __LP64__ | ||
300 | bve (%r2) | ||
301 | #else | ||
302 | bv %r0(%r2) | ||
303 | #endif | ||
304 | copy %r26,%r28 | ||