diff options
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) |