diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-01-05 06:47:57 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-01-05 06:47:29 -0500 |
commit | 1de3447a41ea72972966b4896a9f8d2b064bd23f (patch) | |
tree | 83683c7202f17797a09697956243a2b4745aab86 /arch/s390/kernel/entry.S | |
parent | ce322ccd53f2505cf8b0ed204631d6ac054ac66a (diff) |
[S390] 31 bit entry.S update.
Make the code in the 31 bit entry.S code as similar as possible to the
64 bit version in entry64.S. That makes it easier to add new code to
the first level interrupt handler that affects both 31 and 64 bit kernels.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 212 |
1 files changed, 109 insertions, 103 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 68d1a02db6be..af8bd3b90a26 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -9,7 +9,6 @@ | |||
9 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 9 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/sys.h> | ||
13 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <asm/cache.h> | 14 | #include <asm/cache.h> |
@@ -110,31 +109,36 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
110 | 1: stm %r10,%r11,\lc_sum | 109 | 1: stm %r10,%r11,\lc_sum |
111 | .endm | 110 | .endm |
112 | 111 | ||
113 | .macro SAVE_ALL_BASE savearea | 112 | .macro SAVE_ALL_SVC psworg,savearea |
114 | stm %r12,%r15,\savearea | 113 | stm %r12,%r15,\savearea |
115 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 | 114 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 |
115 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | ||
116 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
116 | .endm | 117 | .endm |
117 | 118 | ||
118 | .macro SAVE_ALL_SVC psworg,savearea | 119 | .macro SAVE_ALL_BASE savearea |
119 | la %r12,\psworg | 120 | stm %r12,%r15,\savearea |
120 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | 121 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 |
121 | .endm | 122 | .endm |
122 | 123 | ||
123 | .macro SAVE_ALL_SYNC psworg,savearea | 124 | .macro SAVE_ALL_PGM psworg,savearea |
124 | la %r12,\psworg | ||
125 | tm \psworg+1,0x01 # test problem state bit | 125 | tm \psworg+1,0x01 # test problem state bit |
126 | bz BASED(2f) # skip stack setup save | ||
127 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | ||
128 | #ifdef CONFIG_CHECK_STACK | 126 | #ifdef CONFIG_CHECK_STACK |
129 | b BASED(3f) | 127 | bnz BASED(1f) |
130 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | 128 | tml %r15,STACK_SIZE - CONFIG_STACK_GUARD |
131 | bz BASED(stack_overflow) | 129 | bnz BASED(2f) |
132 | 3: | 130 | la %r12,\psworg |
131 | b BASED(stack_overflow) | ||
132 | #else | ||
133 | bz BASED(2f) | ||
133 | #endif | 134 | #endif |
134 | 2: | 135 | 1: l %r15,__LC_KERNEL_STACK # problem state -> load ksp |
136 | 2: s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
135 | .endm | 137 | .endm |
136 | 138 | ||
137 | .macro SAVE_ALL_ASYNC psworg,savearea | 139 | .macro SAVE_ALL_ASYNC psworg,savearea |
140 | stm %r12,%r15,\savearea | ||
141 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 | ||
138 | la %r12,\psworg | 142 | la %r12,\psworg |
139 | tm \psworg+1,0x01 # test problem state bit | 143 | tm \psworg+1,0x01 # test problem state bit |
140 | bnz BASED(1f) # from user -> load async stack | 144 | bnz BASED(1f) # from user -> load async stack |
@@ -149,27 +153,23 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
149 | 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? | 153 | 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? |
150 | slr %r14,%r15 | 154 | slr %r14,%r15 |
151 | sra %r14,STACK_SHIFT | 155 | sra %r14,STACK_SHIFT |
152 | be BASED(2f) | ||
153 | 1: l %r15,__LC_ASYNC_STACK | ||
154 | #ifdef CONFIG_CHECK_STACK | 156 | #ifdef CONFIG_CHECK_STACK |
155 | b BASED(3f) | 157 | bnz BASED(1f) |
156 | 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD | 158 | tml %r15,STACK_SIZE - CONFIG_STACK_GUARD |
157 | bz BASED(stack_overflow) | 159 | bnz BASED(2f) |
158 | 3: | 160 | b BASED(stack_overflow) |
161 | #else | ||
162 | bz BASED(2f) | ||
159 | #endif | 163 | #endif |
160 | 2: | 164 | 1: l %r15,__LC_ASYNC_STACK |
165 | 2: s %r15,BASED(.Lc_spsize) # make room for registers & psw | ||
161 | .endm | 166 | .endm |
162 | 167 | ||
163 | .macro CREATE_STACK_FRAME psworg,savearea | 168 | .macro CREATE_STACK_FRAME savearea |
164 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 169 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
165 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | ||
166 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 | 170 | st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 |
167 | icm %r12,12,__LC_SVC_ILC | ||
168 | stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack | ||
169 | st %r12,SP_ILC(%r15) | ||
170 | mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack | 171 | mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack |
171 | la %r12,0 | 172 | stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack |
172 | st %r12,__SF_BACKCHAIN(%r15) # clear back chain | ||
173 | .endm | 173 | .endm |
174 | 174 | ||
175 | .macro RESTORE_ALL psworg,sync | 175 | .macro RESTORE_ALL psworg,sync |
@@ -237,10 +237,11 @@ __critical_start: | |||
237 | system_call: | 237 | system_call: |
238 | stpt __LC_SYNC_ENTER_TIMER | 238 | stpt __LC_SYNC_ENTER_TIMER |
239 | sysc_saveall: | 239 | sysc_saveall: |
240 | SAVE_ALL_BASE __LC_SAVE_AREA | ||
241 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 240 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
242 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 241 | CREATE_STACK_FRAME __LC_SAVE_AREA |
243 | lh %r7,0x8a # get svc number from lowcore | 242 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW |
243 | mvc SP_ILC(4,%r15),__LC_SVC_ILC | ||
244 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
244 | sysc_vtime: | 245 | sysc_vtime: |
245 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 246 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
246 | sysc_stime: | 247 | sysc_stime: |
@@ -248,20 +249,20 @@ sysc_stime: | |||
248 | sysc_update: | 249 | sysc_update: |
249 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 250 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
250 | sysc_do_svc: | 251 | sysc_do_svc: |
251 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 252 | xr %r7,%r7 |
252 | ltr %r7,%r7 # test for svc 0 | 253 | icm %r7,3,SP_SVCNR(%r15) # load svc number and test for svc 0 |
253 | bnz BASED(sysc_nr_ok) # svc number > 0 | 254 | bnz BASED(sysc_nr_ok) # svc number > 0 |
254 | # svc 0: system call number in %r1 | 255 | # svc 0: system call number in %r1 |
255 | cl %r1,BASED(.Lnr_syscalls) | 256 | cl %r1,BASED(.Lnr_syscalls) |
256 | bnl BASED(sysc_nr_ok) | 257 | bnl BASED(sysc_nr_ok) |
258 | sth %r1,SP_SVCNR(%r15) | ||
257 | lr %r7,%r1 # copy svc number to %r7 | 259 | lr %r7,%r1 # copy svc number to %r7 |
258 | sysc_nr_ok: | 260 | sysc_nr_ok: |
259 | sth %r7,SP_SVCNR(%r15) | ||
260 | sll %r7,2 # svc number *4 | 261 | sll %r7,2 # svc number *4 |
261 | l %r8,BASED(.Lsysc_table) | 262 | l %r10,BASED(.Lsysc_table) |
262 | tm __TI_flags+2(%r9),_TIF_SYSCALL | 263 | tm __TI_flags+2(%r12),_TIF_SYSCALL |
263 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | 264 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
264 | l %r8,0(%r7,%r8) # get system call addr. | 265 | l %r8,0(%r7,%r10) # get system call addr. |
265 | bnz BASED(sysc_tracesys) | 266 | bnz BASED(sysc_tracesys) |
266 | basr %r14,%r8 # call sys_xxxx | 267 | basr %r14,%r8 # call sys_xxxx |
267 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 268 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
@@ -269,7 +270,7 @@ sysc_nr_ok: | |||
269 | sysc_return: | 270 | sysc_return: |
270 | LOCKDEP_SYS_EXIT | 271 | LOCKDEP_SYS_EXIT |
271 | sysc_tif: | 272 | sysc_tif: |
272 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 273 | tm __TI_flags+3(%r12),_TIF_WORK_SVC |
273 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 274 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
274 | sysc_restore: | 275 | sysc_restore: |
275 | RESTORE_ALL __LC_RETURN_PSW,1 | 276 | RESTORE_ALL __LC_RETURN_PSW,1 |
@@ -286,17 +287,17 @@ sysc_work: | |||
286 | # One of the work bits is on. Find out which one. | 287 | # One of the work bits is on. Find out which one. |
287 | # | 288 | # |
288 | sysc_work_tif: | 289 | sysc_work_tif: |
289 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 290 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
290 | bo BASED(sysc_mcck_pending) | 291 | bo BASED(sysc_mcck_pending) |
291 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 292 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
292 | bo BASED(sysc_reschedule) | 293 | bo BASED(sysc_reschedule) |
293 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 294 | tm __TI_flags+3(%r12),_TIF_SIGPENDING |
294 | bo BASED(sysc_sigpending) | 295 | bo BASED(sysc_sigpending) |
295 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 296 | tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME |
296 | bo BASED(sysc_notify_resume) | 297 | bo BASED(sysc_notify_resume) |
297 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 298 | tm __TI_flags+3(%r12),_TIF_RESTART_SVC |
298 | bo BASED(sysc_restart) | 299 | bo BASED(sysc_restart) |
299 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 300 | tm __TI_flags+3(%r12),_TIF_SINGLE_STEP |
300 | bo BASED(sysc_singlestep) | 301 | bo BASED(sysc_singlestep) |
301 | b BASED(sysc_return) # beware of critical section cleanup | 302 | b BASED(sysc_return) # beware of critical section cleanup |
302 | 303 | ||
@@ -320,13 +321,13 @@ sysc_mcck_pending: | |||
320 | # _TIF_SIGPENDING is set, call do_signal | 321 | # _TIF_SIGPENDING is set, call do_signal |
321 | # | 322 | # |
322 | sysc_sigpending: | 323 | sysc_sigpending: |
323 | ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 324 | ni __TI_flags+3(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP |
324 | la %r2,SP_PTREGS(%r15) # load pt_regs | 325 | la %r2,SP_PTREGS(%r15) # load pt_regs |
325 | l %r1,BASED(.Ldo_signal) | 326 | l %r1,BASED(.Ldo_signal) |
326 | basr %r14,%r1 # call do_signal | 327 | basr %r14,%r1 # call do_signal |
327 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 328 | tm __TI_flags+3(%r12),_TIF_RESTART_SVC |
328 | bo BASED(sysc_restart) | 329 | bo BASED(sysc_restart) |
329 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 330 | tm __TI_flags+3(%r12),_TIF_SINGLE_STEP |
330 | bo BASED(sysc_singlestep) | 331 | bo BASED(sysc_singlestep) |
331 | b BASED(sysc_return) | 332 | b BASED(sysc_return) |
332 | 333 | ||
@@ -344,19 +345,19 @@ sysc_notify_resume: | |||
344 | # _TIF_RESTART_SVC is set, set up registers and restart svc | 345 | # _TIF_RESTART_SVC is set, set up registers and restart svc |
345 | # | 346 | # |
346 | sysc_restart: | 347 | sysc_restart: |
347 | ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC | 348 | ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC |
348 | l %r7,SP_R2(%r15) # load new svc number | 349 | l %r7,SP_R2(%r15) # load new svc number |
349 | mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument | 350 | mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument |
350 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 351 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
352 | sth %r7,SP_SVCNR(%r15) | ||
351 | b BASED(sysc_nr_ok) # restart svc | 353 | b BASED(sysc_nr_ok) # restart svc |
352 | 354 | ||
353 | # | 355 | # |
354 | # _TIF_SINGLE_STEP is set, call do_single_step | 356 | # _TIF_SINGLE_STEP is set, call do_single_step |
355 | # | 357 | # |
356 | sysc_singlestep: | 358 | sysc_singlestep: |
357 | ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 359 | ni __TI_flags+3(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP |
358 | mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check | 360 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number |
359 | mvi SP_SVCNR+1(%r15),0xff | ||
360 | la %r2,SP_PTREGS(%r15) # address of register-save area | 361 | la %r2,SP_PTREGS(%r15) # address of register-save area |
361 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 362 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
362 | la %r14,BASED(sysc_return) # load adr. of system return | 363 | la %r14,BASED(sysc_return) # load adr. of system return |
@@ -370,15 +371,15 @@ sysc_tracesys: | |||
370 | l %r1,BASED(.Ltrace_entry) | 371 | l %r1,BASED(.Ltrace_entry) |
371 | la %r2,SP_PTREGS(%r15) # load pt_regs | 372 | la %r2,SP_PTREGS(%r15) # load pt_regs |
372 | la %r3,0 | 373 | la %r3,0 |
373 | srl %r7,2 | 374 | xr %r0,%r0 |
374 | st %r7,SP_R2(%r15) | 375 | icm %r0,3,SP_SVCNR(%r15) |
376 | st %r0,SP_R2(%r15) | ||
375 | basr %r14,%r1 | 377 | basr %r14,%r1 |
376 | cl %r2,BASED(.Lnr_syscalls) | 378 | cl %r2,BASED(.Lnr_syscalls) |
377 | bnl BASED(sysc_tracenogo) | 379 | bnl BASED(sysc_tracenogo) |
378 | l %r8,BASED(.Lsysc_table) | ||
379 | lr %r7,%r2 | 380 | lr %r7,%r2 |
380 | sll %r7,2 # svc number *4 | 381 | sll %r7,2 # svc number *4 |
381 | l %r8,0(%r7,%r8) | 382 | l %r8,0(%r7,%r10) |
382 | sysc_tracego: | 383 | sysc_tracego: |
383 | lm %r3,%r6,SP_R3(%r15) | 384 | lm %r3,%r6,SP_R3(%r15) |
384 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | 385 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
@@ -386,7 +387,7 @@ sysc_tracego: | |||
386 | basr %r14,%r8 # call sys_xxx | 387 | basr %r14,%r8 # call sys_xxx |
387 | st %r2,SP_R2(%r15) # store return value | 388 | st %r2,SP_R2(%r15) # store return value |
388 | sysc_tracenogo: | 389 | sysc_tracenogo: |
389 | tm __TI_flags+2(%r9),_TIF_SYSCALL | 390 | tm __TI_flags+2(%r12),_TIF_SYSCALL |
390 | bz BASED(sysc_return) | 391 | bz BASED(sysc_return) |
391 | l %r1,BASED(.Ltrace_exit) | 392 | l %r1,BASED(.Ltrace_exit) |
392 | la %r2,SP_PTREGS(%r15) # load pt_regs | 393 | la %r2,SP_PTREGS(%r15) # load pt_regs |
@@ -399,7 +400,7 @@ sysc_tracenogo: | |||
399 | .globl ret_from_fork | 400 | .globl ret_from_fork |
400 | ret_from_fork: | 401 | ret_from_fork: |
401 | l %r13,__LC_SVC_NEW_PSW+4 | 402 | l %r13,__LC_SVC_NEW_PSW+4 |
402 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 403 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
403 | tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? | 404 | tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? |
404 | bo BASED(0f) | 405 | bo BASED(0f) |
405 | st %r15,SP_R15(%r15) # store stack pointer for new kthread | 406 | st %r15,SP_R15(%r15) # store stack pointer for new kthread |
@@ -434,8 +435,8 @@ kernel_execve: | |||
434 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts | 435 | 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts |
435 | l %r15,__LC_KERNEL_STACK # load ksp | 436 | l %r15,__LC_KERNEL_STACK # load ksp |
436 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 437 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
437 | l %r9,__LC_THREAD_INFO | ||
438 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs | 438 | mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs |
439 | l %r12,__LC_THREAD_INFO | ||
439 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 440 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
440 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 441 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
441 | l %r1,BASED(.Lexecve_tail) | 442 | l %r1,BASED(.Lexecve_tail) |
@@ -465,26 +466,27 @@ pgm_check_handler: | |||
465 | SAVE_ALL_BASE __LC_SAVE_AREA | 466 | SAVE_ALL_BASE __LC_SAVE_AREA |
466 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 467 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
467 | bnz BASED(pgm_per) # got per exception -> special case | 468 | bnz BASED(pgm_per) # got per exception -> special case |
468 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 469 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
469 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 470 | CREATE_STACK_FRAME __LC_SAVE_AREA |
471 | xc SP_ILC(4,%r15),SP_ILC(%r15) | ||
472 | mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW | ||
473 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
470 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 474 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
471 | bz BASED(pgm_no_vtime) | 475 | bz BASED(pgm_no_vtime) |
472 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 476 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
473 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 477 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
474 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 478 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
475 | pgm_no_vtime: | 479 | pgm_no_vtime: |
476 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
477 | l %r3,__LC_PGM_ILC # load program interruption code | 480 | l %r3,__LC_PGM_ILC # load program interruption code |
478 | l %r4,__LC_TRANS_EXC_CODE | 481 | l %r4,__LC_TRANS_EXC_CODE |
479 | REENABLE_IRQS | 482 | REENABLE_IRQS |
480 | la %r8,0x7f | 483 | la %r8,0x7f |
481 | nr %r8,%r3 | 484 | nr %r8,%r3 |
482 | pgm_do_call: | ||
483 | l %r7,BASED(.Ljump_table) | ||
484 | sll %r8,2 | 485 | sll %r8,2 |
485 | l %r7,0(%r8,%r7) # load address of handler routine | 486 | l %r1,BASED(.Ljump_table) |
487 | l %r1,0(%r8,%r1) # load address of handler routine | ||
486 | la %r2,SP_PTREGS(%r15) # address of register-save area | 488 | la %r2,SP_PTREGS(%r15) # address of register-save area |
487 | basr %r14,%r7 # branch to interrupt-handler | 489 | basr %r14,%r1 # branch to interrupt-handler |
488 | pgm_exit: | 490 | pgm_exit: |
489 | b BASED(sysc_return) | 491 | b BASED(sysc_return) |
490 | 492 | ||
@@ -505,33 +507,34 @@ pgm_per: | |||
505 | # Normal per exception | 507 | # Normal per exception |
506 | # | 508 | # |
507 | pgm_per_std: | 509 | pgm_per_std: |
508 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 510 | SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
509 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 511 | CREATE_STACK_FRAME __LC_SAVE_AREA |
512 | mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW | ||
513 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
510 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 514 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
511 | bz BASED(pgm_no_vtime2) | 515 | bz BASED(pgm_no_vtime2) |
512 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 516 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
513 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 517 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
514 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 518 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
515 | pgm_no_vtime2: | 519 | pgm_no_vtime2: |
516 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 520 | l %r1,__TI_task(%r12) |
517 | l %r1,__TI_task(%r9) | ||
518 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | 521 | tm SP_PSW+1(%r15),0x01 # kernel per event ? |
519 | bz BASED(kernel_per) | 522 | bz BASED(kernel_per) |
520 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID | 523 | mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID |
521 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS | 524 | mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS |
522 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID | 525 | mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID |
523 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 526 | oi __TI_flags+3(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
524 | l %r3,__LC_PGM_ILC # load program interruption code | 527 | l %r3,__LC_PGM_ILC # load program interruption code |
525 | l %r4,__LC_TRANS_EXC_CODE | 528 | l %r4,__LC_TRANS_EXC_CODE |
526 | REENABLE_IRQS | 529 | REENABLE_IRQS |
527 | la %r8,0x7f | 530 | la %r8,0x7f |
528 | nr %r8,%r3 # clear per-event-bit and ilc | 531 | nr %r8,%r3 # clear per-event-bit and ilc |
529 | be BASED(pgm_exit2) # only per or per+check ? | 532 | be BASED(pgm_exit2) # only per or per+check ? |
530 | l %r7,BASED(.Ljump_table) | ||
531 | sll %r8,2 | 533 | sll %r8,2 |
532 | l %r7,0(%r8,%r7) # load address of handler routine | 534 | l %r1,BASED(.Ljump_table) |
535 | l %r1,0(%r8,%r1) # load address of handler routine | ||
533 | la %r2,SP_PTREGS(%r15) # address of register-save area | 536 | la %r2,SP_PTREGS(%r15) # address of register-save area |
534 | basr %r14,%r7 # branch to interrupt-handler | 537 | basr %r14,%r1 # branch to interrupt-handler |
535 | pgm_exit2: | 538 | pgm_exit2: |
536 | b BASED(sysc_return) | 539 | b BASED(sysc_return) |
537 | 540 | ||
@@ -539,18 +542,19 @@ pgm_exit2: | |||
539 | # it was a single stepped SVC that is causing all the trouble | 542 | # it was a single stepped SVC that is causing all the trouble |
540 | # | 543 | # |
541 | pgm_svcper: | 544 | pgm_svcper: |
542 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 545 | SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
543 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 546 | CREATE_STACK_FRAME __LC_SAVE_AREA |
547 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | ||
548 | mvc SP_ILC(4,%r15),__LC_SVC_ILC | ||
549 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
544 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 550 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
545 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 551 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
546 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 552 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
547 | lh %r7,0x8a # get svc number from lowcore | 553 | l %r8,__TI_task(%r12) |
548 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
549 | l %r8,__TI_task(%r9) | ||
550 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID | 554 | mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID |
551 | mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS | 555 | mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS |
552 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID | 556 | mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID |
553 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 557 | oi __TI_flags+3(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
554 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 558 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
555 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 559 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
556 | b BASED(sysc_do_svc) | 560 | b BASED(sysc_do_svc) |
@@ -560,8 +564,7 @@ pgm_svcper: | |||
560 | # | 564 | # |
561 | kernel_per: | 565 | kernel_per: |
562 | REENABLE_IRQS | 566 | REENABLE_IRQS |
563 | mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check | 567 | xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) |
564 | mvi SP_SVCNR+1(%r15),0xff | ||
565 | la %r2,SP_PTREGS(%r15) # address of register-save area | 568 | la %r2,SP_PTREGS(%r15) # address of register-save area |
566 | l %r1,BASED(.Lhandle_per) # load adr. of per handler | 569 | l %r1,BASED(.Lhandle_per) # load adr. of per handler |
567 | basr %r14,%r1 # branch to do_single_step | 570 | basr %r14,%r1 # branch to do_single_step |
@@ -575,9 +578,10 @@ kernel_per: | |||
575 | io_int_handler: | 578 | io_int_handler: |
576 | stck __LC_INT_CLOCK | 579 | stck __LC_INT_CLOCK |
577 | stpt __LC_ASYNC_ENTER_TIMER | 580 | stpt __LC_ASYNC_ENTER_TIMER |
578 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | ||
579 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 581 | SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 |
580 | CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 | 582 | CREATE_STACK_FRAME __LC_SAVE_AREA+16 |
583 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | ||
584 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
581 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 585 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
582 | bz BASED(io_no_vtime) | 586 | bz BASED(io_no_vtime) |
583 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 587 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
@@ -585,7 +589,6 @@ io_int_handler: | |||
585 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 589 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
586 | io_no_vtime: | 590 | io_no_vtime: |
587 | TRACE_IRQS_OFF | 591 | TRACE_IRQS_OFF |
588 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
589 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ | 592 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ |
590 | la %r2,SP_PTREGS(%r15) # address of register-save area | 593 | la %r2,SP_PTREGS(%r15) # address of register-save area |
591 | basr %r14,%r1 # branch to standard irq handler | 594 | basr %r14,%r1 # branch to standard irq handler |
@@ -593,7 +596,7 @@ io_return: | |||
593 | LOCKDEP_SYS_EXIT | 596 | LOCKDEP_SYS_EXIT |
594 | TRACE_IRQS_ON | 597 | TRACE_IRQS_ON |
595 | io_tif: | 598 | io_tif: |
596 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 599 | tm __TI_flags+3(%r12),_TIF_WORK_INT |
597 | bnz BASED(io_work) # there is work to do (signals etc.) | 600 | bnz BASED(io_work) # there is work to do (signals etc.) |
598 | io_restore: | 601 | io_restore: |
599 | RESTORE_ALL __LC_RETURN_PSW,0 | 602 | RESTORE_ALL __LC_RETURN_PSW,0 |
@@ -611,9 +614,9 @@ io_work: | |||
611 | bo BASED(io_work_user) # yes -> do resched & signal | 614 | bo BASED(io_work_user) # yes -> do resched & signal |
612 | #ifdef CONFIG_PREEMPT | 615 | #ifdef CONFIG_PREEMPT |
613 | # check for preemptive scheduling | 616 | # check for preemptive scheduling |
614 | icm %r0,15,__TI_precount(%r9) | 617 | icm %r0,15,__TI_precount(%r12) |
615 | bnz BASED(io_restore) # preemption disabled | 618 | bnz BASED(io_restore) # preemption disabled |
616 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 619 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
617 | bno BASED(io_restore) | 620 | bno BASED(io_restore) |
618 | # switch to kernel stack | 621 | # switch to kernel stack |
619 | l %r1,SP_R15(%r15) | 622 | l %r1,SP_R15(%r15) |
@@ -647,13 +650,13 @@ io_work_user: | |||
647 | # and _TIF_MCCK_PENDING | 650 | # and _TIF_MCCK_PENDING |
648 | # | 651 | # |
649 | io_work_tif: | 652 | io_work_tif: |
650 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 653 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
651 | bo BASED(io_mcck_pending) | 654 | bo BASED(io_mcck_pending) |
652 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 655 | tm __TI_flags+3(%r12),_TIF_NEED_RESCHED |
653 | bo BASED(io_reschedule) | 656 | bo BASED(io_reschedule) |
654 | tm __TI_flags+3(%r9),_TIF_SIGPENDING | 657 | tm __TI_flags+3(%r12),_TIF_SIGPENDING |
655 | bo BASED(io_sigpending) | 658 | bo BASED(io_sigpending) |
656 | tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME | 659 | tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME |
657 | bo BASED(io_notify_resume) | 660 | bo BASED(io_notify_resume) |
658 | b BASED(io_return) # beware of critical section cleanup | 661 | b BASED(io_return) # beware of critical section cleanup |
659 | 662 | ||
@@ -713,16 +716,16 @@ io_notify_resume: | |||
713 | ext_int_handler: | 716 | ext_int_handler: |
714 | stck __LC_INT_CLOCK | 717 | stck __LC_INT_CLOCK |
715 | stpt __LC_ASYNC_ENTER_TIMER | 718 | stpt __LC_ASYNC_ENTER_TIMER |
716 | SAVE_ALL_BASE __LC_SAVE_AREA+16 | ||
717 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 719 | SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 |
718 | CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 | 720 | CREATE_STACK_FRAME __LC_SAVE_AREA+16 |
721 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | ||
722 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
719 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 723 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
720 | bz BASED(ext_no_vtime) | 724 | bz BASED(ext_no_vtime) |
721 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 725 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
722 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 726 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
723 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 727 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
724 | ext_no_vtime: | 728 | ext_no_vtime: |
725 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
726 | TRACE_IRQS_OFF | 729 | TRACE_IRQS_OFF |
727 | la %r2,SP_PTREGS(%r15) # address of register-save area | 730 | la %r2,SP_PTREGS(%r15) # address of register-save area |
728 | l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code | 731 | l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code |
@@ -777,7 +780,10 @@ mcck_int_main: | |||
777 | sra %r14,PAGE_SHIFT | 780 | sra %r14,PAGE_SHIFT |
778 | be BASED(0f) | 781 | be BASED(0f) |
779 | l %r15,__LC_PANIC_STACK # load panic stack | 782 | l %r15,__LC_PANIC_STACK # load panic stack |
780 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 | 783 | 0: s %r15,BASED(.Lc_spsize) # make room for registers & psw |
784 | CREATE_STACK_FRAME __LC_SAVE_AREA+32 | ||
785 | mvc SP_PSW(8,%r15),0(%r12) | ||
786 | l %r12,__LC_THREAD_INFO # load pointer to thread_info struct | ||
781 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | 787 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? |
782 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | 788 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical |
783 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 789 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
@@ -786,7 +792,6 @@ mcck_int_main: | |||
786 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 792 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
787 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER | 793 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER |
788 | mcck_no_vtime: | 794 | mcck_no_vtime: |
789 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | ||
790 | la %r2,SP_PTREGS(%r15) # load pt_regs | 795 | la %r2,SP_PTREGS(%r15) # load pt_regs |
791 | l %r1,BASED(.Ls390_mcck) | 796 | l %r1,BASED(.Ls390_mcck) |
792 | basr %r14,%r1 # call machine check handler | 797 | basr %r14,%r1 # call machine check handler |
@@ -798,7 +803,7 @@ mcck_no_vtime: | |||
798 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 803 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
799 | lr %r15,%r1 | 804 | lr %r15,%r1 |
800 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | 805 | stosm __SF_EMPTY(%r15),0x04 # turn dat on |
801 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 806 | tm __TI_flags+3(%r12),_TIF_MCCK_PENDING |
802 | bno BASED(mcck_return) | 807 | bno BASED(mcck_return) |
803 | TRACE_IRQS_OFF | 808 | TRACE_IRQS_OFF |
804 | l %r1,BASED(.Ls390_handle_mcck) | 809 | l %r1,BASED(.Ls390_handle_mcck) |
@@ -947,12 +952,13 @@ cleanup_system_call: | |||
947 | bh BASED(0f) | 952 | bh BASED(0f) |
948 | mvc __LC_SAVE_AREA(16),0(%r12) | 953 | mvc __LC_SAVE_AREA(16),0(%r12) |
949 | 0: st %r13,4(%r12) | 954 | 0: st %r13,4(%r12) |
950 | st %r12,__LC_SAVE_AREA+48 # argh | 955 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp |
951 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 956 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
952 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | ||
953 | l %r12,__LC_SAVE_AREA+48 # argh | ||
954 | st %r15,12(%r12) | 957 | st %r15,12(%r12) |
955 | lh %r7,0x8a | 958 | CREATE_STACK_FRAME __LC_SAVE_AREA |
959 | mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW | ||
960 | mvc SP_ILC(4,%r15),__LC_SVC_ILC | ||
961 | mvc 0(4,%r12),__LC_THREAD_INFO | ||
956 | cleanup_vtime: | 962 | cleanup_vtime: |
957 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) | 963 | clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) |
958 | bhe BASED(cleanup_stime) | 964 | bhe BASED(cleanup_stime) |