]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/alpha/kernel/entry.S
Merge tag 'nfs-for-4.12-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[mirror_ubuntu-artful-kernel.git] / arch / alpha / kernel / entry.S
CommitLineData
1da177e4
LT
1/*
2 * arch/alpha/kernel/entry.S
3 *
4 * Kernel entry-points.
5 */
6
e2d5df93 7#include <asm/asm-offsets.h>
1da177e4
LT
8#include <asm/thread_info.h>
9#include <asm/pal.h>
10#include <asm/errno.h>
11#include <asm/unistd.h>
12
13 .text
14 .set noat
231b0bed 15 .cfi_sections .debug_frame
1da177e4
LT
16
17/* Stack offsets. */
18#define SP_OFF 184
19#define SWITCH_STACK_SIZE 320
20
231b0bed
RH
21.macro CFI_START_OSF_FRAME func
22 .align 4
23 .globl \func
24 .type \func,@function
25\func:
26 .cfi_startproc simple
27 .cfi_return_column 64
28 .cfi_def_cfa $sp, 48
29 .cfi_rel_offset 64, 8
30 .cfi_rel_offset $gp, 16
31 .cfi_rel_offset $16, 24
32 .cfi_rel_offset $17, 32
33 .cfi_rel_offset $18, 40
34.endm
35
36.macro CFI_END_OSF_FRAME func
37 .cfi_endproc
38 .size \func, . - \func
39.endm
40
1da177e4
LT
41/*
42 * This defines the normal kernel pt-regs layout.
43 *
44 * regs 9-15 preserved by C code
45 * regs 16-18 saved by PAL-code
46 * regs 29-30 saved and set up by PAL-code
47 * JRP - Save regs 16-18 in a special area of the stack, so that
48 * the palcode-provided values are available to the signal handler.
49 */
50
231b0bed
RH
51.macro SAVE_ALL
52 subq $sp, SP_OFF, $sp
53 .cfi_adjust_cfa_offset SP_OFF
54 stq $0, 0($sp)
55 stq $1, 8($sp)
56 stq $2, 16($sp)
57 stq $3, 24($sp)
58 stq $4, 32($sp)
59 stq $28, 144($sp)
60 .cfi_rel_offset $0, 0
61 .cfi_rel_offset $1, 8
62 .cfi_rel_offset $2, 16
63 .cfi_rel_offset $3, 24
64 .cfi_rel_offset $4, 32
65 .cfi_rel_offset $28, 144
66 lda $2, alpha_mv
67 stq $5, 40($sp)
68 stq $6, 48($sp)
69 stq $7, 56($sp)
70 stq $8, 64($sp)
71 stq $19, 72($sp)
72 stq $20, 80($sp)
73 stq $21, 88($sp)
74 ldq $2, HAE_CACHE($2)
75 stq $22, 96($sp)
76 stq $23, 104($sp)
77 stq $24, 112($sp)
78 stq $25, 120($sp)
79 stq $26, 128($sp)
80 stq $27, 136($sp)
81 stq $2, 152($sp)
82 stq $16, 160($sp)
83 stq $17, 168($sp)
1da177e4 84 stq $18, 176($sp)
231b0bed
RH
85 .cfi_rel_offset $5, 40
86 .cfi_rel_offset $6, 48
87 .cfi_rel_offset $7, 56
88 .cfi_rel_offset $8, 64
89 .cfi_rel_offset $19, 72
90 .cfi_rel_offset $20, 80
91 .cfi_rel_offset $21, 88
92 .cfi_rel_offset $22, 96
93 .cfi_rel_offset $23, 104
94 .cfi_rel_offset $24, 112
95 .cfi_rel_offset $25, 120
96 .cfi_rel_offset $26, 128
97 .cfi_rel_offset $27, 136
98.endm
99
100.macro RESTORE_ALL
101 lda $19, alpha_mv
102 ldq $0, 0($sp)
103 ldq $1, 8($sp)
104 ldq $2, 16($sp)
105 ldq $3, 24($sp)
106 ldq $21, 152($sp)
107 ldq $20, HAE_CACHE($19)
108 ldq $4, 32($sp)
109 ldq $5, 40($sp)
110 ldq $6, 48($sp)
111 ldq $7, 56($sp)
112 subq $20, $21, $20
113 ldq $8, 64($sp)
114 beq $20, 99f
115 ldq $20, HAE_REG($19)
116 stq $21, HAE_CACHE($19)
117 stq $21, 0($20)
11899: ldq $19, 72($sp)
119 ldq $20, 80($sp)
120 ldq $21, 88($sp)
121 ldq $22, 96($sp)
122 ldq $23, 104($sp)
123 ldq $24, 112($sp)
124 ldq $25, 120($sp)
125 ldq $26, 128($sp)
126 ldq $27, 136($sp)
127 ldq $28, 144($sp)
1da177e4 128 addq $sp, SP_OFF, $sp
231b0bed
RH
129 .cfi_restore $0
130 .cfi_restore $1
131 .cfi_restore $2
132 .cfi_restore $3
133 .cfi_restore $4
134 .cfi_restore $5
135 .cfi_restore $6
136 .cfi_restore $7
137 .cfi_restore $8
138 .cfi_restore $19
139 .cfi_restore $20
140 .cfi_restore $21
141 .cfi_restore $22
142 .cfi_restore $23
143 .cfi_restore $24
144 .cfi_restore $25
145 .cfi_restore $26
146 .cfi_restore $27
147 .cfi_restore $28
148 .cfi_adjust_cfa_offset -SP_OFF
149.endm
150
151.macro DO_SWITCH_STACK
152 bsr $1, do_switch_stack
153 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE
154 .cfi_rel_offset $9, 0
155 .cfi_rel_offset $10, 8
156 .cfi_rel_offset $11, 16
157 .cfi_rel_offset $12, 24
158 .cfi_rel_offset $13, 32
159 .cfi_rel_offset $14, 40
160 .cfi_rel_offset $15, 48
161 /* We don't really care about the FP registers for debugging. */
162.endm
163
164.macro UNDO_SWITCH_STACK
165 bsr $1, undo_switch_stack
166 .cfi_restore $9
167 .cfi_restore $10
168 .cfi_restore $11
169 .cfi_restore $12
170 .cfi_restore $13
171 .cfi_restore $14
172 .cfi_restore $15
173 .cfi_adjust_cfa_offset -SWITCH_STACK_SIZE
174.endm
1da177e4
LT
175
176/*
177 * Non-syscall kernel entry points.
178 */
179
231b0bed 180CFI_START_OSF_FRAME entInt
1da177e4
LT
181 SAVE_ALL
182 lda $8, 0x3fff
183 lda $26, ret_from_sys_call
184 bic $sp, $8, $8
185 mov $sp, $19
186 jsr $31, do_entInt
231b0bed 187CFI_END_OSF_FRAME entInt
1da177e4 188
231b0bed 189CFI_START_OSF_FRAME entArith
1da177e4
LT
190 SAVE_ALL
191 lda $8, 0x3fff
192 lda $26, ret_from_sys_call
193 bic $sp, $8, $8
194 mov $sp, $18
195 jsr $31, do_entArith
231b0bed 196CFI_END_OSF_FRAME entArith
1da177e4 197
231b0bed 198CFI_START_OSF_FRAME entMM
1da177e4
LT
199 SAVE_ALL
200/* save $9 - $15 so the inline exception code can manipulate them. */
201 subq $sp, 56, $sp
231b0bed 202 .cfi_adjust_cfa_offset 56
1da177e4
LT
203 stq $9, 0($sp)
204 stq $10, 8($sp)
205 stq $11, 16($sp)
206 stq $12, 24($sp)
207 stq $13, 32($sp)
208 stq $14, 40($sp)
209 stq $15, 48($sp)
231b0bed
RH
210 .cfi_rel_offset $9, 0
211 .cfi_rel_offset $10, 8
212 .cfi_rel_offset $11, 16
213 .cfi_rel_offset $12, 24
214 .cfi_rel_offset $13, 32
215 .cfi_rel_offset $14, 40
216 .cfi_rel_offset $15, 48
1da177e4
LT
217 addq $sp, 56, $19
218/* handle the fault */
219 lda $8, 0x3fff
220 bic $sp, $8, $8
221 jsr $26, do_page_fault
222/* reload the registers after the exception code played. */
223 ldq $9, 0($sp)
224 ldq $10, 8($sp)
225 ldq $11, 16($sp)
226 ldq $12, 24($sp)
227 ldq $13, 32($sp)
228 ldq $14, 40($sp)
229 ldq $15, 48($sp)
230 addq $sp, 56, $sp
231b0bed
RH
231 .cfi_restore $9
232 .cfi_restore $10
233 .cfi_restore $11
234 .cfi_restore $12
235 .cfi_restore $13
236 .cfi_restore $14
237 .cfi_restore $15
238 .cfi_adjust_cfa_offset -56
1da177e4
LT
239/* finish up the syscall as normal. */
240 br ret_from_sys_call
231b0bed 241CFI_END_OSF_FRAME entMM
1da177e4 242
231b0bed 243CFI_START_OSF_FRAME entIF
1da177e4
LT
244 SAVE_ALL
245 lda $8, 0x3fff
246 lda $26, ret_from_sys_call
247 bic $sp, $8, $8
248 mov $sp, $17
249 jsr $31, do_entIF
231b0bed 250CFI_END_OSF_FRAME entIF
1da177e4 251
231b0bed 252CFI_START_OSF_FRAME entUna
1da177e4 253 lda $sp, -256($sp)
231b0bed 254 .cfi_adjust_cfa_offset 256
1da177e4 255 stq $0, 0($sp)
231b0bed
RH
256 .cfi_rel_offset $0, 0
257 .cfi_remember_state
1da177e4
LT
258 ldq $0, 256($sp) /* get PS */
259 stq $1, 8($sp)
260 stq $2, 16($sp)
261 stq $3, 24($sp)
262 and $0, 8, $0 /* user mode? */
263 stq $4, 32($sp)
264 bne $0, entUnaUser /* yup -> do user-level unaligned fault */
265 stq $5, 40($sp)
266 stq $6, 48($sp)
267 stq $7, 56($sp)
268 stq $8, 64($sp)
269 stq $9, 72($sp)
270 stq $10, 80($sp)
271 stq $11, 88($sp)
272 stq $12, 96($sp)
273 stq $13, 104($sp)
274 stq $14, 112($sp)
275 stq $15, 120($sp)
276 /* 16-18 PAL-saved */
277 stq $19, 152($sp)
278 stq $20, 160($sp)
279 stq $21, 168($sp)
280 stq $22, 176($sp)
281 stq $23, 184($sp)
282 stq $24, 192($sp)
283 stq $25, 200($sp)
284 stq $26, 208($sp)
285 stq $27, 216($sp)
286 stq $28, 224($sp)
d70ddac1 287 mov $sp, $19
1da177e4 288 stq $gp, 232($sp)
231b0bed
RH
289 .cfi_rel_offset $1, 1*8
290 .cfi_rel_offset $2, 2*8
291 .cfi_rel_offset $3, 3*8
292 .cfi_rel_offset $4, 4*8
293 .cfi_rel_offset $5, 5*8
294 .cfi_rel_offset $6, 6*8
295 .cfi_rel_offset $7, 7*8
296 .cfi_rel_offset $8, 8*8
297 .cfi_rel_offset $9, 9*8
298 .cfi_rel_offset $10, 10*8
299 .cfi_rel_offset $11, 11*8
300 .cfi_rel_offset $12, 12*8
301 .cfi_rel_offset $13, 13*8
302 .cfi_rel_offset $14, 14*8
303 .cfi_rel_offset $15, 15*8
304 .cfi_rel_offset $19, 19*8
305 .cfi_rel_offset $20, 20*8
306 .cfi_rel_offset $21, 21*8
307 .cfi_rel_offset $22, 22*8
308 .cfi_rel_offset $23, 23*8
309 .cfi_rel_offset $24, 24*8
310 .cfi_rel_offset $25, 25*8
311 .cfi_rel_offset $26, 26*8
312 .cfi_rel_offset $27, 27*8
313 .cfi_rel_offset $28, 28*8
314 .cfi_rel_offset $29, 29*8
1da177e4
LT
315 lda $8, 0x3fff
316 stq $31, 248($sp)
317 bic $sp, $8, $8
318 jsr $26, do_entUna
319 ldq $0, 0($sp)
320 ldq $1, 8($sp)
321 ldq $2, 16($sp)
322 ldq $3, 24($sp)
323 ldq $4, 32($sp)
324 ldq $5, 40($sp)
325 ldq $6, 48($sp)
326 ldq $7, 56($sp)
327 ldq $8, 64($sp)
328 ldq $9, 72($sp)
329 ldq $10, 80($sp)
330 ldq $11, 88($sp)
331 ldq $12, 96($sp)
332 ldq $13, 104($sp)
333 ldq $14, 112($sp)
334 ldq $15, 120($sp)
335 /* 16-18 PAL-saved */
336 ldq $19, 152($sp)
337 ldq $20, 160($sp)
338 ldq $21, 168($sp)
339 ldq $22, 176($sp)
340 ldq $23, 184($sp)
341 ldq $24, 192($sp)
342 ldq $25, 200($sp)
343 ldq $26, 208($sp)
344 ldq $27, 216($sp)
345 ldq $28, 224($sp)
346 ldq $gp, 232($sp)
347 lda $sp, 256($sp)
231b0bed
RH
348 .cfi_restore $1
349 .cfi_restore $2
350 .cfi_restore $3
351 .cfi_restore $4
352 .cfi_restore $5
353 .cfi_restore $6
354 .cfi_restore $7
355 .cfi_restore $8
356 .cfi_restore $9
357 .cfi_restore $10
358 .cfi_restore $11
359 .cfi_restore $12
360 .cfi_restore $13
361 .cfi_restore $14
362 .cfi_restore $15
363 .cfi_restore $19
364 .cfi_restore $20
365 .cfi_restore $21
366 .cfi_restore $22
367 .cfi_restore $23
368 .cfi_restore $24
369 .cfi_restore $25
370 .cfi_restore $26
371 .cfi_restore $27
372 .cfi_restore $28
373 .cfi_restore $29
374 .cfi_adjust_cfa_offset -256
1da177e4 375 call_pal PAL_rti
1da177e4
LT
376
377 .align 4
1da177e4 378entUnaUser:
231b0bed 379 .cfi_restore_state
1da177e4
LT
380 ldq $0, 0($sp) /* restore original $0 */
381 lda $sp, 256($sp) /* pop entUna's stack frame */
231b0bed
RH
382 .cfi_restore $0
383 .cfi_adjust_cfa_offset -256
1da177e4
LT
384 SAVE_ALL /* setup normal kernel stack */
385 lda $sp, -56($sp)
231b0bed 386 .cfi_adjust_cfa_offset 56
1da177e4
LT
387 stq $9, 0($sp)
388 stq $10, 8($sp)
389 stq $11, 16($sp)
390 stq $12, 24($sp)
391 stq $13, 32($sp)
392 stq $14, 40($sp)
393 stq $15, 48($sp)
231b0bed
RH
394 .cfi_rel_offset $9, 0
395 .cfi_rel_offset $10, 8
396 .cfi_rel_offset $11, 16
397 .cfi_rel_offset $12, 24
398 .cfi_rel_offset $13, 32
399 .cfi_rel_offset $14, 40
400 .cfi_rel_offset $15, 48
1da177e4
LT
401 lda $8, 0x3fff
402 addq $sp, 56, $19
403 bic $sp, $8, $8
404 jsr $26, do_entUnaUser
405 ldq $9, 0($sp)
406 ldq $10, 8($sp)
407 ldq $11, 16($sp)
408 ldq $12, 24($sp)
409 ldq $13, 32($sp)
410 ldq $14, 40($sp)
411 ldq $15, 48($sp)
412 lda $sp, 56($sp)
231b0bed
RH
413 .cfi_restore $9
414 .cfi_restore $10
415 .cfi_restore $11
416 .cfi_restore $12
417 .cfi_restore $13
418 .cfi_restore $14
419 .cfi_restore $15
420 .cfi_adjust_cfa_offset -56
1da177e4 421 br ret_from_sys_call
231b0bed 422CFI_END_OSF_FRAME entUna
1da177e4 423
231b0bed 424CFI_START_OSF_FRAME entDbg
1da177e4
LT
425 SAVE_ALL
426 lda $8, 0x3fff
427 lda $26, ret_from_sys_call
428 bic $sp, $8, $8
429 mov $sp, $16
430 jsr $31, do_entDbg
231b0bed 431CFI_END_OSF_FRAME entDbg
1da177e4
LT
432\f
433/*
434 * The system call entry point is special. Most importantly, it looks
435 * like a function call to userspace as far as clobbered registers. We
436 * do preserve the argument registers (for syscall restarts) and $26
437 * (for leaf syscall functions).
438 *
439 * So much for theory. We don't take advantage of this yet.
440 *
441 * Note that a0-a2 are not saved by PALcode as with the other entry points.
442 */
443
444 .align 4
445 .globl entSys
231b0bed
RH
446 .type entSys, @function
447 .cfi_startproc simple
448 .cfi_return_column 64
449 .cfi_def_cfa $sp, 48
450 .cfi_rel_offset 64, 8
451 .cfi_rel_offset $gp, 16
1da177e4
LT
452entSys:
453 SAVE_ALL
454 lda $8, 0x3fff
455 bic $sp, $8, $8
456 lda $4, NR_SYSCALLS($31)
457 stq $16, SP_OFF+24($sp)
458 lda $5, sys_call_table
459 lda $27, sys_ni_syscall
460 cmpult $0, $4, $4
461 ldl $3, TI_FLAGS($8)
462 stq $17, SP_OFF+32($sp)
463 s8addq $0, $5, $5
464 stq $18, SP_OFF+40($sp)
231b0bed
RH
465 .cfi_rel_offset $16, SP_OFF+24
466 .cfi_rel_offset $17, SP_OFF+32
467 .cfi_rel_offset $18, SP_OFF+40
a9302e84 468#ifdef CONFIG_AUDITSYSCALL
469 lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
470 and $3, $6, $3
471#endif
472 bne $3, strace
1da177e4
LT
473 beq $4, 1f
474 ldq $27, 0($5)
4751: jsr $26, ($27), alpha_ni_syscall
476 ldgp $gp, 0($26)
477 blt $0, $syscall_error /* the call failed */
478 stq $0, 0($sp)
479 stq $31, 72($sp) /* a3=0 => no error */
480
481 .align 4
231b0bed 482 .globl ret_from_sys_call
1da177e4 483ret_from_sys_call:
cb450766 484 cmovne $26, 0, $18 /* $18 = 0 => non-restartable */
1da177e4
LT
485 ldq $0, SP_OFF($sp)
486 and $0, 8, $0
77edffb6 487 beq $0, ret_to_kernel
494486a1 488ret_to_user:
1da177e4
LT
489 /* Make sure need_resched and sigpending don't change between
490 sampling and the rti. */
491 lda $16, 7
492 call_pal PAL_swpipl
cb450766
AV
493 ldl $17, TI_FLAGS($8)
494 and $17, _TIF_WORK_MASK, $2
494486a1 495 bne $2, work_pending
1da177e4 496restore_all:
231b0bed 497 .cfi_remember_state
1da177e4
LT
498 RESTORE_ALL
499 call_pal PAL_rti
500
77edffb6 501ret_to_kernel:
231b0bed 502 .cfi_restore_state
77edffb6
AV
503 lda $16, 7
504 call_pal PAL_swpipl
505 br restore_all
506
1da177e4
LT
507 .align 3
508$syscall_error:
509 /*
510 * Some system calls (e.g., ptrace) can return arbitrary
511 * values which might normally be mistaken as error numbers.
512 * Those functions must zero $0 (v0) directly in the stack
513 * frame to indicate that a negative return value wasn't an
514 * error number..
515 */
cb450766
AV
516 ldq $18, 0($sp) /* old syscall nr (zero if success) */
517 beq $18, $ret_success
1da177e4 518
cb450766 519 ldq $19, 72($sp) /* .. and this a3 */
1da177e4
LT
520 subq $31, $0, $0 /* with error in v0 */
521 addq $31, 1, $1 /* set a3 for errno return */
522 stq $0, 0($sp)
523 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
524 stq $1, 72($sp) /* a3 for return */
525 br ret_from_sys_call
526
527$ret_success:
528 stq $0, 0($sp)
529 stq $31, 72($sp) /* a3=0 => no error */
530 br ret_from_sys_call
1da177e4
LT
531
532/*
533 * Do all cleanup when returning from all interrupts and system calls.
534 *
535 * Arguments:
1da177e4 536 * $8: current.
cb450766
AV
537 * $17: TI_FLAGS.
538 * $18: The old syscall number, or zero if this is not a return
1da177e4 539 * from a syscall that errored and is possibly restartable.
cb450766 540 * $19: The old a3 value
1da177e4
LT
541 */
542
543 .align 4
231b0bed 544 .type work_pending, @function
1da177e4 545work_pending:
cb450766 546 and $17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2
7721d3c2 547 bne $2, $work_notifysig
1da177e4
LT
548
549$work_resched:
7721d3c2
AV
550 /*
551 * We can get here only if we returned from syscall without SIGPENDING
552 * or got through work_notifysig already. Either case means no syscall
cb450766 553 * restarts for us, so let $18 and $19 burn.
7721d3c2 554 */
1da177e4 555 jsr $26, schedule
cb450766 556 mov 0, $18
7721d3c2 557 br ret_to_user
1da177e4
LT
558
559$work_notifysig:
b927b3e2 560 mov $sp, $16
231b0bed 561 DO_SWITCH_STACK
6972d6f2 562 jsr $26, do_work_pending
231b0bed 563 UNDO_SWITCH_STACK
6972d6f2 564 br restore_all
1da177e4
LT
565
566/*
567 * PTRACE syscall handler
568 */
569
570 .align 4
231b0bed 571 .type strace, @function
1da177e4
LT
572strace:
573 /* set up signal stack, call syscall_trace */
231b0bed 574 DO_SWITCH_STACK
12f79be9 575 jsr $26, syscall_trace_enter /* returns the syscall number */
231b0bed 576 UNDO_SWITCH_STACK
1da177e4 577
12f79be9 578 /* get the arguments back.. */
1da177e4
LT
579 ldq $16, SP_OFF+24($sp)
580 ldq $17, SP_OFF+32($sp)
581 ldq $18, SP_OFF+40($sp)
582 ldq $19, 72($sp)
583 ldq $20, 80($sp)
584 ldq $21, 88($sp)
585
586 /* get the system call pointer.. */
587 lda $1, NR_SYSCALLS($31)
588 lda $2, sys_call_table
589 lda $27, alpha_ni_syscall
590 cmpult $0, $1, $1
591 s8addq $0, $2, $2
592 beq $1, 1f
593 ldq $27, 0($2)
5941: jsr $26, ($27), sys_gettimeofday
53293638 595ret_from_straced:
1da177e4
LT
596 ldgp $gp, 0($26)
597
598 /* check return.. */
599 blt $0, $strace_error /* the call failed */
600 stq $31, 72($sp) /* a3=0 => no error */
601$strace_success:
602 stq $0, 0($sp) /* save return value */
603
231b0bed 604 DO_SWITCH_STACK
12f79be9 605 jsr $26, syscall_trace_leave
231b0bed 606 UNDO_SWITCH_STACK
1da177e4
LT
607 br $31, ret_from_sys_call
608
609 .align 3
610$strace_error:
cb450766
AV
611 ldq $18, 0($sp) /* old syscall nr (zero if success) */
612 beq $18, $strace_success
613 ldq $19, 72($sp) /* .. and this a3 */
1da177e4
LT
614
615 subq $31, $0, $0 /* with error in v0 */
616 addq $31, 1, $1 /* set a3 for errno return */
617 stq $0, 0($sp)
618 stq $1, 72($sp) /* a3 for return */
619
231b0bed 620 DO_SWITCH_STACK
cb450766
AV
621 mov $18, $9 /* save old syscall number */
622 mov $19, $10 /* save old a3 */
12f79be9 623 jsr $26, syscall_trace_leave
cb450766
AV
624 mov $9, $18
625 mov $10, $19
231b0bed 626 UNDO_SWITCH_STACK
1da177e4
LT
627
628 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
629 br ret_from_sys_call
231b0bed 630CFI_END_OSF_FRAME entSys
1da177e4
LT
631\f
632/*
633 * Save and restore the switch stack -- aka the balance of the user context.
634 */
635
636 .align 4
231b0bed
RH
637 .type do_switch_stack, @function
638 .cfi_startproc simple
639 .cfi_return_column 64
640 .cfi_def_cfa $sp, 0
641 .cfi_register 64, $1
1da177e4
LT
642do_switch_stack:
643 lda $sp, -SWITCH_STACK_SIZE($sp)
231b0bed 644 .cfi_adjust_cfa_offset SWITCH_STACK_SIZE
1da177e4
LT
645 stq $9, 0($sp)
646 stq $10, 8($sp)
647 stq $11, 16($sp)
648 stq $12, 24($sp)
649 stq $13, 32($sp)
650 stq $14, 40($sp)
651 stq $15, 48($sp)
652 stq $26, 56($sp)
653 stt $f0, 64($sp)
654 stt $f1, 72($sp)
655 stt $f2, 80($sp)
656 stt $f3, 88($sp)
657 stt $f4, 96($sp)
658 stt $f5, 104($sp)
659 stt $f6, 112($sp)
660 stt $f7, 120($sp)
661 stt $f8, 128($sp)
662 stt $f9, 136($sp)
663 stt $f10, 144($sp)
664 stt $f11, 152($sp)
665 stt $f12, 160($sp)
666 stt $f13, 168($sp)
667 stt $f14, 176($sp)
668 stt $f15, 184($sp)
669 stt $f16, 192($sp)
670 stt $f17, 200($sp)
671 stt $f18, 208($sp)
672 stt $f19, 216($sp)
673 stt $f20, 224($sp)
674 stt $f21, 232($sp)
675 stt $f22, 240($sp)
676 stt $f23, 248($sp)
677 stt $f24, 256($sp)
678 stt $f25, 264($sp)
679 stt $f26, 272($sp)
680 stt $f27, 280($sp)
681 mf_fpcr $f0 # get fpcr
682 stt $f28, 288($sp)
683 stt $f29, 296($sp)
684 stt $f30, 304($sp)
685 stt $f0, 312($sp) # save fpcr in slot of $f31
686 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
687 ret $31, ($1), 1
231b0bed
RH
688 .cfi_endproc
689 .size do_switch_stack, .-do_switch_stack
1da177e4
LT
690
691 .align 4
231b0bed
RH
692 .type undo_switch_stack, @function
693 .cfi_startproc simple
694 .cfi_def_cfa $sp, 0
695 .cfi_register 64, $1
1da177e4
LT
696undo_switch_stack:
697 ldq $9, 0($sp)
698 ldq $10, 8($sp)
699 ldq $11, 16($sp)
700 ldq $12, 24($sp)
701 ldq $13, 32($sp)
702 ldq $14, 40($sp)
703 ldq $15, 48($sp)
704 ldq $26, 56($sp)
705 ldt $f30, 312($sp) # get saved fpcr
706 ldt $f0, 64($sp)
707 ldt $f1, 72($sp)
708 ldt $f2, 80($sp)
709 ldt $f3, 88($sp)
710 mt_fpcr $f30 # install saved fpcr
711 ldt $f4, 96($sp)
712 ldt $f5, 104($sp)
713 ldt $f6, 112($sp)
714 ldt $f7, 120($sp)
715 ldt $f8, 128($sp)
716 ldt $f9, 136($sp)
717 ldt $f10, 144($sp)
718 ldt $f11, 152($sp)
719 ldt $f12, 160($sp)
720 ldt $f13, 168($sp)
721 ldt $f14, 176($sp)
722 ldt $f15, 184($sp)
723 ldt $f16, 192($sp)
724 ldt $f17, 200($sp)
725 ldt $f18, 208($sp)
726 ldt $f19, 216($sp)
727 ldt $f20, 224($sp)
728 ldt $f21, 232($sp)
729 ldt $f22, 240($sp)
730 ldt $f23, 248($sp)
731 ldt $f24, 256($sp)
732 ldt $f25, 264($sp)
733 ldt $f26, 272($sp)
734 ldt $f27, 280($sp)
735 ldt $f28, 288($sp)
736 ldt $f29, 296($sp)
737 ldt $f30, 304($sp)
738 lda $sp, SWITCH_STACK_SIZE($sp)
739 ret $31, ($1), 1
231b0bed
RH
740 .cfi_endproc
741 .size undo_switch_stack, .-undo_switch_stack
1da177e4
LT
742\f
743/*
744 * The meat of the context switch code.
745 */
746
747 .align 4
748 .globl alpha_switch_to
231b0bed
RH
749 .type alpha_switch_to, @function
750 .cfi_startproc
1da177e4 751alpha_switch_to:
231b0bed 752 DO_SWITCH_STACK
1da177e4
LT
753 call_pal PAL_swpctx
754 lda $8, 0x3fff
231b0bed 755 UNDO_SWITCH_STACK
1da177e4
LT
756 bic $sp, $8, $8
757 mov $17, $0
758 ret
231b0bed
RH
759 .cfi_endproc
760 .size alpha_switch_to, .-alpha_switch_to
1da177e4
LT
761
762/*
763 * New processes begin life here.
764 */
765
766 .globl ret_from_fork
767 .align 4
768 .ent ret_from_fork
769ret_from_fork:
770 lda $26, ret_from_sys_call
771 mov $17, $16
772 jmp $31, schedule_tail
773.end ret_from_fork
774
775/*
cba1ec7e 776 * ... and new kernel threads - here
1da177e4
LT
777 */
778 .align 4
cba1ec7e
AV
779 .globl ret_from_kernel_thread
780 .ent ret_from_kernel_thread
781ret_from_kernel_thread:
782 mov $17, $16
783 jsr $26, schedule_tail
784 mov $9, $27
785 mov $10, $16
786 jsr $26, ($9)
44f4b56b
AV
787 mov $31, $19 /* to disable syscall restarts */
788 br $31, ret_to_user
5522be6a 789.end ret_from_kernel_thread
44f4b56b 790
1da177e4
LT
791\f
792/*
793 * Special system calls. Most of these are special in that they either
794 * have to play switch_stack games or in some way use the pt_regs struct.
795 */
dfe09ae0
AV
796
797.macro fork_like name
1da177e4 798 .align 4
dfe09ae0
AV
799 .globl alpha_\name
800 .ent alpha_\name
801alpha_\name:
1da177e4 802 .prologue 0
1da177e4 803 bsr $1, do_switch_stack
dfe09ae0 804 jsr $26, sys_\name
e0e431aa
AV
805 ldq $26, 56($sp)
806 lda $sp, SWITCH_STACK_SIZE($sp)
1da177e4 807 ret
dfe09ae0
AV
808.end alpha_\name
809.endm
1da177e4 810
dfe09ae0
AV
811fork_like fork
812fork_like vfork
813fork_like clone
1da177e4
LT
814
815 .align 4
816 .globl sys_sigreturn
817 .ent sys_sigreturn
818sys_sigreturn:
819 .prologue 0
53293638
AV
820 lda $9, ret_from_straced
821 cmpult $26, $9, $9
1da177e4
LT
822 lda $sp, -SWITCH_STACK_SIZE($sp)
823 jsr $26, do_sigreturn
53293638 824 bne $9, 1f
12f79be9 825 jsr $26, syscall_trace_leave
53293638 8261: br $1, undo_switch_stack
1da177e4
LT
827 br ret_from_sys_call
828.end sys_sigreturn
829
830 .align 4
831 .globl sys_rt_sigreturn
832 .ent sys_rt_sigreturn
833sys_rt_sigreturn:
834 .prologue 0
53293638
AV
835 lda $9, ret_from_straced
836 cmpult $26, $9, $9
1da177e4
LT
837 lda $sp, -SWITCH_STACK_SIZE($sp)
838 jsr $26, do_rt_sigreturn
53293638 839 bne $9, 1f
12f79be9 840 jsr $26, syscall_trace_leave
53293638 8411: br $1, undo_switch_stack
1da177e4
LT
842 br ret_from_sys_call
843.end sys_rt_sigreturn
844
1da177e4
LT
845 .align 4
846 .globl alpha_ni_syscall
847 .ent alpha_ni_syscall
848alpha_ni_syscall:
849 .prologue 0
850 /* Special because it also implements overflow handling via
851 syscall number 0. And if you recall, zero is a special
852 trigger for "not an error". Store large non-zero there. */
853 lda $0, -ENOSYS
854 unop
855 stq $0, 0($sp)
856 ret
857.end alpha_ni_syscall