diff options
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 469 |
1 files changed, 234 insertions, 235 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 0c712b78a7e8..dddc3de30401 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -4,8 +4,8 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) IBM Corp. 1999,2006 | 5 | * Copyright (C) IBM Corp. 1999,2006 |
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
7 | * Hartmut Penner (hp@de.ibm.com), | 7 | * Hartmut Penner (hp@de.ibm.com), |
8 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | 8 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), |
9 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 9 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -24,29 +24,29 @@ | |||
24 | * Stack layout for the system_call stack entry. | 24 | * Stack layout for the system_call stack entry. |
25 | * The first few entries are identical to the user_regs_struct. | 25 | * The first few entries are identical to the user_regs_struct. |
26 | */ | 26 | */ |
27 | SP_PTREGS = STACK_FRAME_OVERHEAD | 27 | SP_PTREGS = STACK_FRAME_OVERHEAD |
28 | SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS | 28 | SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS |
29 | SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW | 29 | SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW |
30 | SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS | 30 | SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS |
31 | SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 | 31 | SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 |
32 | SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 | 32 | SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 |
33 | SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 | 33 | SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 |
34 | SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 | 34 | SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 |
35 | SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 | 35 | SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 |
36 | SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 | 36 | SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 |
37 | SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 | 37 | SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 |
38 | SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 | 38 | SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 |
39 | SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36 | 39 | SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36 |
40 | SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 | 40 | SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 |
41 | SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44 | 41 | SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44 |
42 | SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 | 42 | SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 |
43 | SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52 | 43 | SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52 |
44 | SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 | 44 | SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 |
45 | SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 | 45 | SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 |
46 | SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 | 46 | SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 |
47 | SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC | 47 | SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC |
48 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP | 48 | SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP |
49 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE | 49 | SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE |
50 | 50 | ||
51 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ | 51 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ |
52 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) | 52 | _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) |
@@ -81,14 +81,14 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
81 | * R15 - kernel stack pointer | 81 | * R15 - kernel stack pointer |
82 | */ | 82 | */ |
83 | 83 | ||
84 | .macro STORE_TIMER lc_offset | 84 | .macro STORE_TIMER lc_offset |
85 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 85 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
86 | stpt \lc_offset | 86 | stpt \lc_offset |
87 | #endif | 87 | #endif |
88 | .endm | 88 | .endm |
89 | 89 | ||
90 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 90 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
91 | .macro UPDATE_VTIME lc_from,lc_to,lc_sum | 91 | .macro UPDATE_VTIME lc_from,lc_to,lc_sum |
92 | lm %r10,%r11,\lc_from | 92 | lm %r10,%r11,\lc_from |
93 | sl %r10,\lc_to | 93 | sl %r10,\lc_to |
94 | sl %r11,\lc_to+4 | 94 | sl %r11,\lc_to+4 |
@@ -147,7 +147,7 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
147 | 2: | 147 | 2: |
148 | .endm | 148 | .endm |
149 | 149 | ||
150 | .macro CREATE_STACK_FRAME psworg,savearea | 150 | .macro CREATE_STACK_FRAME psworg,savearea |
151 | s %r15,BASED(.Lc_spsize) # make room for registers & psw | 151 | s %r15,BASED(.Lc_spsize) # make room for registers & psw |
152 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack | 152 | mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack |
153 | la %r12,\psworg | 153 | la %r12,\psworg |
@@ -160,7 +160,7 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
160 | st %r12,__SF_BACKCHAIN(%r15) # clear back chain | 160 | st %r12,__SF_BACKCHAIN(%r15) # clear back chain |
161 | .endm | 161 | .endm |
162 | 162 | ||
163 | .macro RESTORE_ALL psworg,sync | 163 | .macro RESTORE_ALL psworg,sync |
164 | mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore | 164 | mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore |
165 | .if !\sync | 165 | .if !\sync |
166 | ni \psworg+1,0xfd # clear wait state bit | 166 | ni \psworg+1,0xfd # clear wait state bit |
@@ -177,16 +177,16 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
177 | * Returns: | 177 | * Returns: |
178 | * gpr2 = prev | 178 | * gpr2 = prev |
179 | */ | 179 | */ |
180 | .globl __switch_to | 180 | .globl __switch_to |
181 | __switch_to: | 181 | __switch_to: |
182 | basr %r1,0 | 182 | basr %r1,0 |
183 | __switch_to_base: | 183 | __switch_to_base: |
184 | tm __THREAD_per(%r3),0xe8 # new process is using per ? | 184 | tm __THREAD_per(%r3),0xe8 # new process is using per ? |
185 | bz __switch_to_noper-__switch_to_base(%r1) # if not we're fine | 185 | bz __switch_to_noper-__switch_to_base(%r1) # if not we're fine |
186 | stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff | 186 | stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff |
187 | clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) | 187 | clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) |
188 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's | 188 | be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's |
189 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't | 189 | lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't |
190 | __switch_to_noper: | 190 | __switch_to_noper: |
191 | l %r4,__THREAD_info(%r2) # get thread_info of prev | 191 | l %r4,__THREAD_info(%r2) # get thread_info of prev |
192 | tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? | 192 | tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? |
@@ -195,13 +195,13 @@ __switch_to_noper: | |||
195 | l %r4,__THREAD_info(%r3) # get thread_info of next | 195 | l %r4,__THREAD_info(%r3) # get thread_info of next |
196 | oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next | 196 | oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next |
197 | __switch_to_no_mcck: | 197 | __switch_to_no_mcck: |
198 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task | 198 | stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task |
199 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp | 199 | st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp |
200 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp | 200 | l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp |
201 | lm %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task | 201 | lm %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task |
202 | st %r3,__LC_CURRENT # __LC_CURRENT = current task struct | 202 | st %r3,__LC_CURRENT # __LC_CURRENT = current task struct |
203 | lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 | 203 | lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 |
204 | l %r3,__THREAD_info(%r3) # load thread_info from task struct | 204 | l %r3,__THREAD_info(%r3) # load thread_info from task struct |
205 | st %r3,__LC_THREAD_INFO | 205 | st %r3,__LC_THREAD_INFO |
206 | ahi %r3,STACK_SIZE | 206 | ahi %r3,STACK_SIZE |
207 | st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack | 207 | st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack |
@@ -213,7 +213,7 @@ __critical_start: | |||
213 | * are executed with interrupts enabled. | 213 | * are executed with interrupts enabled. |
214 | */ | 214 | */ |
215 | 215 | ||
216 | .globl system_call | 216 | .globl system_call |
217 | system_call: | 217 | system_call: |
218 | STORE_TIMER __LC_SYNC_ENTER_TIMER | 218 | STORE_TIMER __LC_SYNC_ENTER_TIMER |
219 | sysc_saveall: | 219 | sysc_saveall: |
@@ -233,24 +233,24 @@ sysc_update: | |||
233 | #endif | 233 | #endif |
234 | sysc_do_svc: | 234 | sysc_do_svc: |
235 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 235 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
236 | sla %r7,2 # *4 and test for svc 0 | 236 | sla %r7,2 # *4 and test for svc 0 |
237 | bnz BASED(sysc_nr_ok) # svc number > 0 | 237 | bnz BASED(sysc_nr_ok) # svc number > 0 |
238 | # svc 0: system call number in %r1 | 238 | # svc 0: system call number in %r1 |
239 | cl %r1,BASED(.Lnr_syscalls) | 239 | cl %r1,BASED(.Lnr_syscalls) |
240 | bnl BASED(sysc_nr_ok) | 240 | bnl BASED(sysc_nr_ok) |
241 | lr %r7,%r1 # copy svc number to %r7 | 241 | lr %r7,%r1 # copy svc number to %r7 |
242 | sla %r7,2 # *4 | 242 | sla %r7,2 # *4 |
243 | sysc_nr_ok: | 243 | sysc_nr_ok: |
244 | mvc SP_ARGS(4,%r15),SP_R7(%r15) | 244 | mvc SP_ARGS(4,%r15),SP_R7(%r15) |
245 | sysc_do_restart: | 245 | sysc_do_restart: |
246 | l %r8,BASED(.Lsysc_table) | 246 | l %r8,BASED(.Lsysc_table) |
247 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) | 247 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) |
248 | l %r8,0(%r7,%r8) # get system call addr. | 248 | l %r8,0(%r7,%r8) # get system call addr. |
249 | bnz BASED(sysc_tracesys) | 249 | bnz BASED(sysc_tracesys) |
250 | basr %r14,%r8 # call sys_xxxx | 250 | basr %r14,%r8 # call sys_xxxx |
251 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) | 251 | st %r2,SP_R2(%r15) # store return value (change R2 on stack) |
252 | # ATTENTION: check sys_execve_glue before | 252 | # ATTENTION: check sys_execve_glue before |
253 | # changing anything here !! | 253 | # changing anything here !! |
254 | 254 | ||
255 | sysc_return: | 255 | sysc_return: |
256 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 256 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
@@ -258,14 +258,14 @@ sysc_return: | |||
258 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 258 | tm __TI_flags+3(%r9),_TIF_WORK_SVC |
259 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 259 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
260 | sysc_leave: | 260 | sysc_leave: |
261 | RESTORE_ALL __LC_RETURN_PSW,1 | 261 | RESTORE_ALL __LC_RETURN_PSW,1 |
262 | 262 | ||
263 | # | 263 | # |
264 | # recheck if there is more work to do | 264 | # recheck if there is more work to do |
265 | # | 265 | # |
266 | sysc_work_loop: | 266 | sysc_work_loop: |
267 | tm __TI_flags+3(%r9),_TIF_WORK_SVC | 267 | tm __TI_flags+3(%r9),_TIF_WORK_SVC |
268 | bz BASED(sysc_leave) # there is no work to do | 268 | bz BASED(sysc_leave) # there is no work to do |
269 | # | 269 | # |
270 | # One of the work bits is on. Find out which one. | 270 | # One of the work bits is on. Find out which one. |
271 | # | 271 | # |
@@ -284,11 +284,11 @@ sysc_work: | |||
284 | 284 | ||
285 | # | 285 | # |
286 | # _TIF_NEED_RESCHED is set, call schedule | 286 | # _TIF_NEED_RESCHED is set, call schedule |
287 | # | 287 | # |
288 | sysc_reschedule: | 288 | sysc_reschedule: |
289 | l %r1,BASED(.Lschedule) | 289 | l %r1,BASED(.Lschedule) |
290 | la %r14,BASED(sysc_work_loop) | 290 | la %r14,BASED(sysc_work_loop) |
291 | br %r1 # call scheduler | 291 | br %r1 # call scheduler |
292 | 292 | ||
293 | # | 293 | # |
294 | # _TIF_MCCK_PENDING is set, call handler | 294 | # _TIF_MCCK_PENDING is set, call handler |
@@ -301,11 +301,11 @@ sysc_mcck_pending: | |||
301 | # | 301 | # |
302 | # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal | 302 | # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal |
303 | # | 303 | # |
304 | sysc_sigpending: | 304 | sysc_sigpending: |
305 | ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP | 305 | ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP |
306 | la %r2,SP_PTREGS(%r15) # load pt_regs | 306 | la %r2,SP_PTREGS(%r15) # load pt_regs |
307 | l %r1,BASED(.Ldo_signal) | 307 | l %r1,BASED(.Ldo_signal) |
308 | basr %r14,%r1 # call do_signal | 308 | basr %r14,%r1 # call do_signal |
309 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC | 309 | tm __TI_flags+3(%r9),_TIF_RESTART_SVC |
310 | bo BASED(sysc_restart) | 310 | bo BASED(sysc_restart) |
311 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP | 311 | tm __TI_flags+3(%r9),_TIF_SINGLE_STEP |
@@ -317,11 +317,11 @@ sysc_sigpending: | |||
317 | # | 317 | # |
318 | sysc_restart: | 318 | sysc_restart: |
319 | ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC | 319 | ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC |
320 | l %r7,SP_R2(%r15) # load new svc number | 320 | l %r7,SP_R2(%r15) # load new svc number |
321 | sla %r7,2 | 321 | sla %r7,2 |
322 | mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument | 322 | mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument |
323 | lm %r2,%r6,SP_R2(%r15) # load svc arguments | 323 | lm %r2,%r6,SP_R2(%r15) # load svc arguments |
324 | b BASED(sysc_do_restart) # restart svc | 324 | b BASED(sysc_do_restart) # restart svc |
325 | 325 | ||
326 | # | 326 | # |
327 | # _TIF_SINGLE_STEP is set, call do_single_step | 327 | # _TIF_SINGLE_STEP is set, call do_single_step |
@@ -338,8 +338,8 @@ sysc_singlestep: | |||
338 | # call trace before and after sys_call | 338 | # call trace before and after sys_call |
339 | # | 339 | # |
340 | sysc_tracesys: | 340 | sysc_tracesys: |
341 | l %r1,BASED(.Ltrace) | 341 | l %r1,BASED(.Ltrace) |
342 | la %r2,SP_PTREGS(%r15) # load pt_regs | 342 | la %r2,SP_PTREGS(%r15) # load pt_regs |
343 | la %r3,0 | 343 | la %r3,0 |
344 | srl %r7,2 | 344 | srl %r7,2 |
345 | st %r7,SP_R2(%r15) | 345 | st %r7,SP_R2(%r15) |
@@ -347,19 +347,19 @@ sysc_tracesys: | |||
347 | clc SP_R2(4,%r15),BASED(.Lnr_syscalls) | 347 | clc SP_R2(4,%r15),BASED(.Lnr_syscalls) |
348 | bnl BASED(sysc_tracenogo) | 348 | bnl BASED(sysc_tracenogo) |
349 | l %r8,BASED(.Lsysc_table) | 349 | l %r8,BASED(.Lsysc_table) |
350 | l %r7,SP_R2(%r15) # strace might have changed the | 350 | l %r7,SP_R2(%r15) # strace might have changed the |
351 | sll %r7,2 # system call | 351 | sll %r7,2 # system call |
352 | l %r8,0(%r7,%r8) | 352 | l %r8,0(%r7,%r8) |
353 | sysc_tracego: | 353 | sysc_tracego: |
354 | lm %r3,%r6,SP_R3(%r15) | 354 | lm %r3,%r6,SP_R3(%r15) |
355 | l %r2,SP_ORIG_R2(%r15) | 355 | l %r2,SP_ORIG_R2(%r15) |
356 | basr %r14,%r8 # call sys_xxx | 356 | basr %r14,%r8 # call sys_xxx |
357 | st %r2,SP_R2(%r15) # store return value | 357 | st %r2,SP_R2(%r15) # store return value |
358 | sysc_tracenogo: | 358 | sysc_tracenogo: |
359 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) | 359 | tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) |
360 | bz BASED(sysc_return) | 360 | bz BASED(sysc_return) |
361 | l %r1,BASED(.Ltrace) | 361 | l %r1,BASED(.Ltrace) |
362 | la %r2,SP_PTREGS(%r15) # load pt_regs | 362 | la %r2,SP_PTREGS(%r15) # load pt_regs |
363 | la %r3,1 | 363 | la %r3,1 |
364 | la %r14,BASED(sysc_return) | 364 | la %r14,BASED(sysc_return) |
365 | br %r1 | 365 | br %r1 |
@@ -367,17 +367,17 @@ sysc_tracenogo: | |||
367 | # | 367 | # |
368 | # a new process exits the kernel with ret_from_fork | 368 | # a new process exits the kernel with ret_from_fork |
369 | # | 369 | # |
370 | .globl ret_from_fork | 370 | .globl ret_from_fork |
371 | ret_from_fork: | 371 | ret_from_fork: |
372 | l %r13,__LC_SVC_NEW_PSW+4 | 372 | l %r13,__LC_SVC_NEW_PSW+4 |
373 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 373 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
374 | tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? | 374 | tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? |
375 | bo BASED(0f) | 375 | bo BASED(0f) |
376 | st %r15,SP_R15(%r15) # store stack pointer for new kthread | 376 | st %r15,SP_R15(%r15) # store stack pointer for new kthread |
377 | 0: l %r1,BASED(.Lschedtail) | 377 | 0: l %r1,BASED(.Lschedtail) |
378 | basr %r14,%r1 | 378 | basr %r14,%r1 |
379 | TRACE_IRQS_ON | 379 | TRACE_IRQS_ON |
380 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 380 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
381 | b BASED(sysc_return) | 381 | b BASED(sysc_return) |
382 | 382 | ||
383 | # | 383 | # |
@@ -386,52 +386,51 @@ ret_from_fork: | |||
386 | # but are called with different parameter. | 386 | # but are called with different parameter. |
387 | # return-address is set up above | 387 | # return-address is set up above |
388 | # | 388 | # |
389 | sys_clone_glue: | 389 | sys_clone_glue: |
390 | la %r2,SP_PTREGS(%r15) # load pt_regs | 390 | la %r2,SP_PTREGS(%r15) # load pt_regs |
391 | l %r1,BASED(.Lclone) | 391 | l %r1,BASED(.Lclone) |
392 | br %r1 # branch to sys_clone | 392 | br %r1 # branch to sys_clone |
393 | |||
394 | sys_fork_glue: | ||
395 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
396 | l %r1,BASED(.Lfork) | ||
397 | br %r1 # branch to sys_fork | ||
398 | |||
399 | sys_vfork_glue: | ||
400 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
401 | l %r1,BASED(.Lvfork) | ||
402 | br %r1 # branch to sys_vfork | ||
403 | |||
404 | sys_execve_glue: | ||
405 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
406 | l %r1,BASED(.Lexecve) | ||
407 | lr %r12,%r14 # save return address | ||
408 | basr %r14,%r1 # call sys_execve | ||
409 | ltr %r2,%r2 # check if execve failed | ||
410 | bnz 0(%r12) # it did fail -> store result in gpr2 | ||
411 | b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 | ||
412 | # in system_call/sysc_tracesys | ||
413 | |||
414 | sys_sigreturn_glue: | ||
415 | la %r2,SP_PTREGS(%r15) # load pt_regs as parameter | ||
416 | l %r1,BASED(.Lsigreturn) | ||
417 | br %r1 # branch to sys_sigreturn | ||
418 | |||
419 | sys_rt_sigreturn_glue: | ||
420 | la %r2,SP_PTREGS(%r15) # load pt_regs as parameter | ||
421 | l %r1,BASED(.Lrt_sigreturn) | ||
422 | br %r1 # branch to sys_sigreturn | ||
423 | 393 | ||
424 | sys_sigaltstack_glue: | 394 | sys_fork_glue: |
425 | la %r4,SP_PTREGS(%r15) # load pt_regs as parameter | 395 | la %r2,SP_PTREGS(%r15) # load pt_regs |
426 | l %r1,BASED(.Lsigaltstack) | 396 | l %r1,BASED(.Lfork) |
427 | br %r1 # branch to sys_sigreturn | 397 | br %r1 # branch to sys_fork |
428 | 398 | ||
399 | sys_vfork_glue: | ||
400 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
401 | l %r1,BASED(.Lvfork) | ||
402 | br %r1 # branch to sys_vfork | ||
403 | |||
404 | sys_execve_glue: | ||
405 | la %r2,SP_PTREGS(%r15) # load pt_regs | ||
406 | l %r1,BASED(.Lexecve) | ||
407 | lr %r12,%r14 # save return address | ||
408 | basr %r14,%r1 # call sys_execve | ||
409 | ltr %r2,%r2 # check if execve failed | ||
410 | bnz 0(%r12) # it did fail -> store result in gpr2 | ||
411 | b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 | ||
412 | # in system_call/sysc_tracesys | ||
413 | |||
414 | sys_sigreturn_glue: | ||
415 | la %r2,SP_PTREGS(%r15) # load pt_regs as parameter | ||
416 | l %r1,BASED(.Lsigreturn) | ||
417 | br %r1 # branch to sys_sigreturn | ||
418 | |||
419 | sys_rt_sigreturn_glue: | ||
420 | la %r2,SP_PTREGS(%r15) # load pt_regs as parameter | ||
421 | l %r1,BASED(.Lrt_sigreturn) | ||
422 | br %r1 # branch to sys_sigreturn | ||
423 | |||
424 | sys_sigaltstack_glue: | ||
425 | la %r4,SP_PTREGS(%r15) # load pt_regs as parameter | ||
426 | l %r1,BASED(.Lsigaltstack) | ||
427 | br %r1 # branch to sys_sigreturn | ||
429 | 428 | ||
430 | /* | 429 | /* |
431 | * Program check handler routine | 430 | * Program check handler routine |
432 | */ | 431 | */ |
433 | 432 | ||
434 | .globl pgm_check_handler | 433 | .globl pgm_check_handler |
435 | pgm_check_handler: | 434 | pgm_check_handler: |
436 | /* | 435 | /* |
437 | * First we need to check for a special case: | 436 | * First we need to check for a special case: |
@@ -448,8 +447,8 @@ pgm_check_handler: | |||
448 | */ | 447 | */ |
449 | STORE_TIMER __LC_SYNC_ENTER_TIMER | 448 | STORE_TIMER __LC_SYNC_ENTER_TIMER |
450 | SAVE_ALL_BASE __LC_SAVE_AREA | 449 | SAVE_ALL_BASE __LC_SAVE_AREA |
451 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception | 450 | tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception |
452 | bnz BASED(pgm_per) # got per exception -> special case | 451 | bnz BASED(pgm_per) # got per exception -> special case |
453 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 452 | SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
454 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA | 453 | CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA |
455 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 454 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
@@ -461,29 +460,29 @@ pgm_check_handler: | |||
461 | pgm_no_vtime: | 460 | pgm_no_vtime: |
462 | #endif | 461 | #endif |
463 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 462 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
464 | l %r3,__LC_PGM_ILC # load program interruption code | 463 | l %r3,__LC_PGM_ILC # load program interruption code |
465 | la %r8,0x7f | 464 | la %r8,0x7f |
466 | nr %r8,%r3 | 465 | nr %r8,%r3 |
467 | pgm_do_call: | 466 | pgm_do_call: |
468 | l %r7,BASED(.Ljump_table) | 467 | l %r7,BASED(.Ljump_table) |
469 | sll %r8,2 | 468 | sll %r8,2 |
470 | l %r7,0(%r8,%r7) # load address of handler routine | 469 | l %r7,0(%r8,%r7) # load address of handler routine |
471 | la %r2,SP_PTREGS(%r15) # address of register-save area | 470 | la %r2,SP_PTREGS(%r15) # address of register-save area |
472 | la %r14,BASED(sysc_return) | 471 | la %r14,BASED(sysc_return) |
473 | br %r7 # branch to interrupt-handler | 472 | br %r7 # branch to interrupt-handler |
474 | 473 | ||
475 | # | 474 | # |
476 | # handle per exception | 475 | # handle per exception |
477 | # | 476 | # |
478 | pgm_per: | 477 | pgm_per: |
479 | tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on | 478 | tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on |
480 | bnz BASED(pgm_per_std) # ok, normal per event from user space | 479 | bnz BASED(pgm_per_std) # ok, normal per event from user space |
481 | # ok its one of the special cases, now we need to find out which one | 480 | # ok its one of the special cases, now we need to find out which one |
482 | clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW | 481 | clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW |
483 | be BASED(pgm_svcper) | 482 | be BASED(pgm_svcper) |
484 | # no interesting special case, ignore PER event | 483 | # no interesting special case, ignore PER event |
485 | lm %r12,%r15,__LC_SAVE_AREA | 484 | lm %r12,%r15,__LC_SAVE_AREA |
486 | lpsw 0x28 | 485 | lpsw 0x28 |
487 | 486 | ||
488 | # | 487 | # |
489 | # Normal per exception | 488 | # Normal per exception |
@@ -507,10 +506,10 @@ pgm_no_vtime2: | |||
507 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP | 506 | oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP |
508 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | 507 | tm SP_PSW+1(%r15),0x01 # kernel per event ? |
509 | bz BASED(kernel_per) | 508 | bz BASED(kernel_per) |
510 | l %r3,__LC_PGM_ILC # load program interruption code | 509 | l %r3,__LC_PGM_ILC # load program interruption code |
511 | la %r8,0x7f | 510 | la %r8,0x7f |
512 | nr %r8,%r3 # clear per-event-bit and ilc | 511 | nr %r8,%r3 # clear per-event-bit and ilc |
513 | be BASED(sysc_return) # only per or per+check ? | 512 | be BASED(sysc_return) # only per or per+check ? |
514 | b BASED(pgm_do_call) | 513 | b BASED(pgm_do_call) |
515 | 514 | ||
516 | # | 515 | # |
@@ -552,7 +551,7 @@ kernel_per: | |||
552 | * IO interrupt handler routine | 551 | * IO interrupt handler routine |
553 | */ | 552 | */ |
554 | 553 | ||
555 | .globl io_int_handler | 554 | .globl io_int_handler |
556 | io_int_handler: | 555 | io_int_handler: |
557 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 556 | STORE_TIMER __LC_ASYNC_ENTER_TIMER |
558 | stck __LC_INT_CLOCK | 557 | stck __LC_INT_CLOCK |
@@ -569,42 +568,42 @@ io_no_vtime: | |||
569 | #endif | 568 | #endif |
570 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 569 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
571 | TRACE_IRQS_OFF | 570 | TRACE_IRQS_OFF |
572 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ | 571 | l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ |
573 | la %r2,SP_PTREGS(%r15) # address of register-save area | 572 | la %r2,SP_PTREGS(%r15) # address of register-save area |
574 | basr %r14,%r1 # branch to standard irq handler | 573 | basr %r14,%r1 # branch to standard irq handler |
575 | TRACE_IRQS_ON | 574 | TRACE_IRQS_ON |
576 | 575 | ||
577 | io_return: | 576 | io_return: |
578 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 577 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
579 | #ifdef CONFIG_PREEMPT | 578 | #ifdef CONFIG_PREEMPT |
580 | bno BASED(io_preempt) # no -> check for preemptive scheduling | 579 | bno BASED(io_preempt) # no -> check for preemptive scheduling |
581 | #else | 580 | #else |
582 | bno BASED(io_leave) # no-> skip resched & signal | 581 | bno BASED(io_leave) # no-> skip resched & signal |
583 | #endif | 582 | #endif |
584 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 583 | tm __TI_flags+3(%r9),_TIF_WORK_INT |
585 | bnz BASED(io_work) # there is work to do (signals etc.) | 584 | bnz BASED(io_work) # there is work to do (signals etc.) |
586 | io_leave: | 585 | io_leave: |
587 | RESTORE_ALL __LC_RETURN_PSW,0 | 586 | RESTORE_ALL __LC_RETURN_PSW,0 |
588 | io_done: | 587 | io_done: |
589 | 588 | ||
590 | #ifdef CONFIG_PREEMPT | 589 | #ifdef CONFIG_PREEMPT |
591 | io_preempt: | 590 | io_preempt: |
592 | icm %r0,15,__TI_precount(%r9) | 591 | icm %r0,15,__TI_precount(%r9) |
593 | bnz BASED(io_leave) | 592 | bnz BASED(io_leave) |
594 | l %r1,SP_R15(%r15) | 593 | l %r1,SP_R15(%r15) |
595 | s %r1,BASED(.Lc_spsize) | 594 | s %r1,BASED(.Lc_spsize) |
596 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 595 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
597 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 596 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
598 | lr %r15,%r1 | 597 | lr %r15,%r1 |
599 | io_resume_loop: | 598 | io_resume_loop: |
600 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 599 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
601 | bno BASED(io_leave) | 600 | bno BASED(io_leave) |
602 | mvc __TI_precount(4,%r9),BASED(.Lc_pactive) | 601 | mvc __TI_precount(4,%r9),BASED(.Lc_pactive) |
603 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 602 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
604 | l %r1,BASED(.Lschedule) | 603 | l %r1,BASED(.Lschedule) |
605 | basr %r14,%r1 # call schedule | 604 | basr %r14,%r1 # call schedule |
606 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 605 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
607 | xc __TI_precount(4,%r9),__TI_precount(%r9) | 606 | xc __TI_precount(4,%r9),__TI_precount(%r9) |
608 | b BASED(io_resume_loop) | 607 | b BASED(io_resume_loop) |
609 | #endif | 608 | #endif |
610 | 609 | ||
@@ -615,16 +614,16 @@ io_work: | |||
615 | l %r1,__LC_KERNEL_STACK | 614 | l %r1,__LC_KERNEL_STACK |
616 | s %r1,BASED(.Lc_spsize) | 615 | s %r1,BASED(.Lc_spsize) |
617 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 616 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
618 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 617 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
619 | lr %r15,%r1 | 618 | lr %r15,%r1 |
620 | # | 619 | # |
621 | # One of the work bits is on. Find out which one. | 620 | # One of the work bits is on. Find out which one. |
622 | # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED | 621 | # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED |
623 | # and _TIF_MCCK_PENDING | 622 | # and _TIF_MCCK_PENDING |
624 | # | 623 | # |
625 | io_work_loop: | 624 | io_work_loop: |
626 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 625 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
627 | bo BASED(io_mcck_pending) | 626 | bo BASED(io_mcck_pending) |
628 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 627 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
629 | bo BASED(io_reschedule) | 628 | bo BASED(io_reschedule) |
630 | tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) | 629 | tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) |
@@ -637,36 +636,36 @@ io_work_loop: | |||
637 | io_mcck_pending: | 636 | io_mcck_pending: |
638 | l %r1,BASED(.Ls390_handle_mcck) | 637 | l %r1,BASED(.Ls390_handle_mcck) |
639 | la %r14,BASED(io_work_loop) | 638 | la %r14,BASED(io_work_loop) |
640 | br %r1 # TIF bit will be cleared by handler | 639 | br %r1 # TIF bit will be cleared by handler |
641 | 640 | ||
642 | # | 641 | # |
643 | # _TIF_NEED_RESCHED is set, call schedule | 642 | # _TIF_NEED_RESCHED is set, call schedule |
644 | # | 643 | # |
645 | io_reschedule: | 644 | io_reschedule: |
646 | l %r1,BASED(.Lschedule) | 645 | l %r1,BASED(.Lschedule) |
647 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 646 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
648 | basr %r14,%r1 # call scheduler | 647 | basr %r14,%r1 # call scheduler |
649 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 648 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
650 | tm __TI_flags+3(%r9),_TIF_WORK_INT | 649 | tm __TI_flags+3(%r9),_TIF_WORK_INT |
651 | bz BASED(io_leave) # there is no work to do | 650 | bz BASED(io_leave) # there is no work to do |
652 | b BASED(io_work_loop) | 651 | b BASED(io_work_loop) |
653 | 652 | ||
654 | # | 653 | # |
655 | # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal | 654 | # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal |
656 | # | 655 | # |
657 | io_sigpending: | 656 | io_sigpending: |
658 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 657 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts |
659 | la %r2,SP_PTREGS(%r15) # load pt_regs | 658 | la %r2,SP_PTREGS(%r15) # load pt_regs |
660 | l %r1,BASED(.Ldo_signal) | 659 | l %r1,BASED(.Ldo_signal) |
661 | basr %r14,%r1 # call do_signal | 660 | basr %r14,%r1 # call do_signal |
662 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | 661 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts |
663 | b BASED(io_work_loop) | 662 | b BASED(io_work_loop) |
664 | 663 | ||
665 | /* | 664 | /* |
666 | * External interrupt handler routine | 665 | * External interrupt handler routine |
667 | */ | 666 | */ |
668 | 667 | ||
669 | .globl ext_int_handler | 668 | .globl ext_int_handler |
670 | ext_int_handler: | 669 | ext_int_handler: |
671 | STORE_TIMER __LC_ASYNC_ENTER_TIMER | 670 | STORE_TIMER __LC_ASYNC_ENTER_TIMER |
672 | stck __LC_INT_CLOCK | 671 | stck __LC_INT_CLOCK |
@@ -683,8 +682,8 @@ ext_no_vtime: | |||
683 | #endif | 682 | #endif |
684 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 683 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
685 | TRACE_IRQS_OFF | 684 | TRACE_IRQS_OFF |
686 | la %r2,SP_PTREGS(%r15) # address of register-save area | 685 | la %r2,SP_PTREGS(%r15) # address of register-save area |
687 | lh %r3,__LC_EXT_INT_CODE # get interruption code | 686 | lh %r3,__LC_EXT_INT_CODE # get interruption code |
688 | l %r1,BASED(.Ldo_extint) | 687 | l %r1,BASED(.Ldo_extint) |
689 | basr %r14,%r1 | 688 | basr %r14,%r1 |
690 | TRACE_IRQS_ON | 689 | TRACE_IRQS_ON |
@@ -696,13 +695,13 @@ __critical_end: | |||
696 | * Machine check handler routines | 695 | * Machine check handler routines |
697 | */ | 696 | */ |
698 | 697 | ||
699 | .globl mcck_int_handler | 698 | .globl mcck_int_handler |
700 | mcck_int_handler: | 699 | mcck_int_handler: |
701 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer | 700 | spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer |
702 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs | 701 | lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs |
703 | SAVE_ALL_BASE __LC_SAVE_AREA+32 | 702 | SAVE_ALL_BASE __LC_SAVE_AREA+32 |
704 | la %r12,__LC_MCK_OLD_PSW | 703 | la %r12,__LC_MCK_OLD_PSW |
705 | tm __LC_MCCK_CODE,0x80 # system damage? | 704 | tm __LC_MCCK_CODE,0x80 # system damage? |
706 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid | 705 | bo BASED(mcck_int_main) # yes -> rest of mcck code invalid |
707 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 706 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
708 | mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER | 707 | mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER |
@@ -741,7 +740,7 @@ mcck_int_main: | |||
741 | l %r15,__LC_PANIC_STACK # load panic stack | 740 | l %r15,__LC_PANIC_STACK # load panic stack |
742 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 | 741 | 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 |
743 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 742 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
744 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | 743 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? |
745 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical | 744 | bno BASED(mcck_no_vtime) # no -> skip cleanup critical |
746 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 745 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
747 | bz BASED(mcck_no_vtime) | 746 | bz BASED(mcck_no_vtime) |
@@ -752,14 +751,14 @@ mcck_no_vtime: | |||
752 | #endif | 751 | #endif |
753 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 752 | l %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
754 | la %r2,SP_PTREGS(%r15) # load pt_regs | 753 | la %r2,SP_PTREGS(%r15) # load pt_regs |
755 | l %r1,BASED(.Ls390_mcck) | 754 | l %r1,BASED(.Ls390_mcck) |
756 | basr %r14,%r1 # call machine check handler | 755 | basr %r14,%r1 # call machine check handler |
757 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 756 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
758 | bno BASED(mcck_return) | 757 | bno BASED(mcck_return) |
759 | l %r1,__LC_KERNEL_STACK # switch to kernel stack | 758 | l %r1,__LC_KERNEL_STACK # switch to kernel stack |
760 | s %r1,BASED(.Lc_spsize) | 759 | s %r1,BASED(.Lc_spsize) |
761 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) | 760 | mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) |
762 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain | 761 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain |
763 | lr %r15,%r1 | 762 | lr %r15,%r1 |
764 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | 763 | stosm __SF_EMPTY(%r15),0x04 # turn dat on |
765 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING | 764 | tm __TI_flags+3(%r9),_TIF_MCCK_PENDING |
@@ -783,36 +782,36 @@ mcck_return: | |||
783 | lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 | 782 | lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 |
784 | lpsw __LC_RETURN_MCCK_PSW # back to caller | 783 | lpsw __LC_RETURN_MCCK_PSW # back to caller |
785 | 784 | ||
786 | RESTORE_ALL __LC_RETURN_MCCK_PSW,0 | 785 | RESTORE_ALL __LC_RETURN_MCCK_PSW,0 |
787 | 786 | ||
788 | #ifdef CONFIG_SMP | 787 | #ifdef CONFIG_SMP |
789 | /* | 788 | /* |
790 | * Restart interruption handler, kick starter for additional CPUs | 789 | * Restart interruption handler, kick starter for additional CPUs |
791 | */ | 790 | */ |
792 | .globl restart_int_handler | 791 | .globl restart_int_handler |
793 | restart_int_handler: | 792 | restart_int_handler: |
794 | l %r15,__LC_SAVE_AREA+60 # load ksp | 793 | l %r15,__LC_SAVE_AREA+60 # load ksp |
795 | lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs | 794 | lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs |
796 | lam %a0,%a15,__LC_AREGS_SAVE_AREA | 795 | lam %a0,%a15,__LC_AREGS_SAVE_AREA |
797 | lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone | 796 | lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone |
798 | stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on | 797 | stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on |
799 | basr %r14,0 | 798 | basr %r14,0 |
800 | l %r14,restart_addr-.(%r14) | 799 | l %r14,restart_addr-.(%r14) |
801 | br %r14 # branch to start_secondary | 800 | br %r14 # branch to start_secondary |
802 | restart_addr: | 801 | restart_addr: |
803 | .long start_secondary | 802 | .long start_secondary |
804 | #else | 803 | #else |
805 | /* | 804 | /* |
806 | * If we do not run with SMP enabled, let the new CPU crash ... | 805 | * If we do not run with SMP enabled, let the new CPU crash ... |
807 | */ | 806 | */ |
808 | .globl restart_int_handler | 807 | .globl restart_int_handler |
809 | restart_int_handler: | 808 | restart_int_handler: |
810 | basr %r1,0 | 809 | basr %r1,0 |
811 | restart_base: | 810 | restart_base: |
812 | lpsw restart_crash-restart_base(%r1) | 811 | lpsw restart_crash-restart_base(%r1) |
813 | .align 8 | 812 | .align 8 |
814 | restart_crash: | 813 | restart_crash: |
815 | .long 0x000a0000,0x00000000 | 814 | .long 0x000a0000,0x00000000 |
816 | restart_go: | 815 | restart_go: |
817 | #endif | 816 | #endif |
818 | 817 | ||
@@ -834,11 +833,11 @@ stack_overflow: | |||
834 | be BASED(0f) | 833 | be BASED(0f) |
835 | la %r1,__LC_SAVE_AREA+16 | 834 | la %r1,__LC_SAVE_AREA+16 |
836 | 0: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack | 835 | 0: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack |
837 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain | 836 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain |
838 | l %r1,BASED(1f) # branch to kernel_stack_overflow | 837 | l %r1,BASED(1f) # branch to kernel_stack_overflow |
839 | la %r2,SP_PTREGS(%r15) # load pt_regs | 838 | la %r2,SP_PTREGS(%r15) # load pt_regs |
840 | br %r1 | 839 | br %r1 |
841 | 1: .long kernel_stack_overflow | 840 | 1: .long kernel_stack_overflow |
842 | #endif | 841 | #endif |
843 | 842 | ||
844 | cleanup_table_system_call: | 843 | cleanup_table_system_call: |
@@ -940,10 +939,10 @@ cleanup_novtime: | |||
940 | cleanup_system_call_insn: | 939 | cleanup_system_call_insn: |
941 | .long sysc_saveall + 0x80000000 | 940 | .long sysc_saveall + 0x80000000 |
942 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 941 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
943 | .long system_call + 0x80000000 | 942 | .long system_call + 0x80000000 |
944 | .long sysc_vtime + 0x80000000 | 943 | .long sysc_vtime + 0x80000000 |
945 | .long sysc_stime + 0x80000000 | 944 | .long sysc_stime + 0x80000000 |
946 | .long sysc_update + 0x80000000 | 945 | .long sysc_update + 0x80000000 |
947 | #endif | 946 | #endif |
948 | 947 | ||
949 | cleanup_sysc_return: | 948 | cleanup_sysc_return: |
@@ -1009,57 +1008,57 @@ cleanup_io_leave_insn: | |||
1009 | /* | 1008 | /* |
1010 | * Integer constants | 1009 | * Integer constants |
1011 | */ | 1010 | */ |
1012 | .align 4 | 1011 | .align 4 |
1013 | .Lc_spsize: .long SP_SIZE | 1012 | .Lc_spsize: .long SP_SIZE |
1014 | .Lc_overhead: .long STACK_FRAME_OVERHEAD | 1013 | .Lc_overhead: .long STACK_FRAME_OVERHEAD |
1015 | .Lc_pactive: .long PREEMPT_ACTIVE | 1014 | .Lc_pactive: .long PREEMPT_ACTIVE |
1016 | .Lnr_syscalls: .long NR_syscalls | 1015 | .Lnr_syscalls: .long NR_syscalls |
1017 | .L0x018: .short 0x018 | 1016 | .L0x018: .short 0x018 |
1018 | .L0x020: .short 0x020 | 1017 | .L0x020: .short 0x020 |
1019 | .L0x028: .short 0x028 | 1018 | .L0x028: .short 0x028 |
1020 | .L0x030: .short 0x030 | 1019 | .L0x030: .short 0x030 |
1021 | .L0x038: .short 0x038 | 1020 | .L0x038: .short 0x038 |
1022 | .Lc_1: .long 1 | 1021 | .Lc_1: .long 1 |
1023 | 1022 | ||
1024 | /* | 1023 | /* |
1025 | * Symbol constants | 1024 | * Symbol constants |
1026 | */ | 1025 | */ |
1027 | .Ls390_mcck: .long s390_do_machine_check | 1026 | .Ls390_mcck: .long s390_do_machine_check |
1028 | .Ls390_handle_mcck: | 1027 | .Ls390_handle_mcck: |
1029 | .long s390_handle_mcck | 1028 | .long s390_handle_mcck |
1030 | .Lmck_old_psw: .long __LC_MCK_OLD_PSW | 1029 | .Lmck_old_psw: .long __LC_MCK_OLD_PSW |
1031 | .Ldo_IRQ: .long do_IRQ | 1030 | .Ldo_IRQ: .long do_IRQ |
1032 | .Ldo_extint: .long do_extint | 1031 | .Ldo_extint: .long do_extint |
1033 | .Ldo_signal: .long do_signal | 1032 | .Ldo_signal: .long do_signal |
1034 | .Lhandle_per: .long do_single_step | 1033 | .Lhandle_per: .long do_single_step |
1035 | .Ljump_table: .long pgm_check_table | 1034 | .Ljump_table: .long pgm_check_table |
1036 | .Lschedule: .long schedule | 1035 | .Lschedule: .long schedule |
1037 | .Lclone: .long sys_clone | 1036 | .Lclone: .long sys_clone |
1038 | .Lexecve: .long sys_execve | 1037 | .Lexecve: .long sys_execve |
1039 | .Lfork: .long sys_fork | 1038 | .Lfork: .long sys_fork |
1040 | .Lrt_sigreturn:.long sys_rt_sigreturn | 1039 | .Lrt_sigreturn: .long sys_rt_sigreturn |
1041 | .Lrt_sigsuspend: | 1040 | .Lrt_sigsuspend: |
1042 | .long sys_rt_sigsuspend | 1041 | .long sys_rt_sigsuspend |
1043 | .Lsigreturn: .long sys_sigreturn | 1042 | .Lsigreturn: .long sys_sigreturn |
1044 | .Lsigsuspend: .long sys_sigsuspend | 1043 | .Lsigsuspend: .long sys_sigsuspend |
1045 | .Lsigaltstack: .long sys_sigaltstack | 1044 | .Lsigaltstack: .long sys_sigaltstack |
1046 | .Ltrace: .long syscall_trace | 1045 | .Ltrace: .long syscall_trace |
1047 | .Lvfork: .long sys_vfork | 1046 | .Lvfork: .long sys_vfork |
1048 | .Lschedtail: .long schedule_tail | 1047 | .Lschedtail: .long schedule_tail |
1049 | .Lsysc_table: .long sys_call_table | 1048 | .Lsysc_table: .long sys_call_table |
1050 | #ifdef CONFIG_TRACE_IRQFLAGS | 1049 | #ifdef CONFIG_TRACE_IRQFLAGS |
1051 | .Ltrace_irq_on:.long trace_hardirqs_on | 1050 | .Ltrace_irq_on: .long trace_hardirqs_on |
1052 | .Ltrace_irq_off: | 1051 | .Ltrace_irq_off: |
1053 | .long trace_hardirqs_off | 1052 | .long trace_hardirqs_off |
1054 | #endif | 1053 | #endif |
1055 | .Lcritical_start: | 1054 | .Lcritical_start: |
1056 | .long __critical_start + 0x80000000 | 1055 | .long __critical_start + 0x80000000 |
1057 | .Lcritical_end: | 1056 | .Lcritical_end: |
1058 | .long __critical_end + 0x80000000 | 1057 | .long __critical_end + 0x80000000 |
1059 | .Lcleanup_critical: | 1058 | .Lcleanup_critical: |
1060 | .long cleanup_critical | 1059 | .long cleanup_critical |
1061 | 1060 | ||
1062 | .section .rodata, "a" | 1061 | .section .rodata, "a" |
1063 | #define SYSCALL(esa,esame,emu) .long esa | 1062 | #define SYSCALL(esa,esame,emu) .long esa |
1064 | sys_call_table: | 1063 | sys_call_table: |
1065 | #include "syscalls.S" | 1064 | #include "syscalls.S" |