]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/alpha/kernel/entry.S
Merge branch 'for-linus/i2c/2636-rc5' of git://git.fluff.org/bjdooks/linux
[net-next-2.6.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
15
16/* Stack offsets. */
17#define SP_OFF 184
18#define SWITCH_STACK_SIZE 320
19
20/*
21 * This defines the normal kernel pt-regs layout.
22 *
23 * regs 9-15 preserved by C code
24 * regs 16-18 saved by PAL-code
25 * regs 29-30 saved and set up by PAL-code
26 * JRP - Save regs 16-18 in a special area of the stack, so that
27 * the palcode-provided values are available to the signal handler.
28 */
29
30#define SAVE_ALL \
31 subq $sp, SP_OFF, $sp; \
32 stq $0, 0($sp); \
33 stq $1, 8($sp); \
34 stq $2, 16($sp); \
35 stq $3, 24($sp); \
36 stq $4, 32($sp); \
37 stq $28, 144($sp); \
38 lda $2, alpha_mv; \
39 stq $5, 40($sp); \
40 stq $6, 48($sp); \
41 stq $7, 56($sp); \
42 stq $8, 64($sp); \
43 stq $19, 72($sp); \
44 stq $20, 80($sp); \
45 stq $21, 88($sp); \
46 ldq $2, HAE_CACHE($2); \
47 stq $22, 96($sp); \
48 stq $23, 104($sp); \
49 stq $24, 112($sp); \
50 stq $25, 120($sp); \
51 stq $26, 128($sp); \
52 stq $27, 136($sp); \
53 stq $2, 152($sp); \
54 stq $16, 160($sp); \
55 stq $17, 168($sp); \
56 stq $18, 176($sp)
57
58#define RESTORE_ALL \
59 lda $19, alpha_mv; \
60 ldq $0, 0($sp); \
61 ldq $1, 8($sp); \
62 ldq $2, 16($sp); \
63 ldq $3, 24($sp); \
64 ldq $21, 152($sp); \
65 ldq $20, HAE_CACHE($19); \
66 ldq $4, 32($sp); \
67 ldq $5, 40($sp); \
68 ldq $6, 48($sp); \
69 ldq $7, 56($sp); \
70 subq $20, $21, $20; \
71 ldq $8, 64($sp); \
72 beq $20, 99f; \
73 ldq $20, HAE_REG($19); \
74 stq $21, HAE_CACHE($19); \
75 stq $21, 0($20); \
1da177e4
LT
7699:; \
77 ldq $19, 72($sp); \
78 ldq $20, 80($sp); \
79 ldq $21, 88($sp); \
80 ldq $22, 96($sp); \
81 ldq $23, 104($sp); \
82 ldq $24, 112($sp); \
83 ldq $25, 120($sp); \
84 ldq $26, 128($sp); \
85 ldq $27, 136($sp); \
86 ldq $28, 144($sp); \
87 addq $sp, SP_OFF, $sp
88
89/*
90 * Non-syscall kernel entry points.
91 */
92
93 .align 4
94 .globl entInt
95 .ent entInt
96entInt:
97 SAVE_ALL
98 lda $8, 0x3fff
99 lda $26, ret_from_sys_call
100 bic $sp, $8, $8
101 mov $sp, $19
102 jsr $31, do_entInt
103.end entInt
104
105 .align 4
106 .globl entArith
107 .ent entArith
108entArith:
109 SAVE_ALL
110 lda $8, 0x3fff
111 lda $26, ret_from_sys_call
112 bic $sp, $8, $8
113 mov $sp, $18
114 jsr $31, do_entArith
115.end entArith
116
117 .align 4
118 .globl entMM
119 .ent entMM
120entMM:
121 SAVE_ALL
122/* save $9 - $15 so the inline exception code can manipulate them. */
123 subq $sp, 56, $sp
124 stq $9, 0($sp)
125 stq $10, 8($sp)
126 stq $11, 16($sp)
127 stq $12, 24($sp)
128 stq $13, 32($sp)
129 stq $14, 40($sp)
130 stq $15, 48($sp)
131 addq $sp, 56, $19
132/* handle the fault */
133 lda $8, 0x3fff
134 bic $sp, $8, $8
135 jsr $26, do_page_fault
136/* reload the registers after the exception code played. */
137 ldq $9, 0($sp)
138 ldq $10, 8($sp)
139 ldq $11, 16($sp)
140 ldq $12, 24($sp)
141 ldq $13, 32($sp)
142 ldq $14, 40($sp)
143 ldq $15, 48($sp)
144 addq $sp, 56, $sp
145/* finish up the syscall as normal. */
146 br ret_from_sys_call
147.end entMM
148
149 .align 4
150 .globl entIF
151 .ent entIF
152entIF:
153 SAVE_ALL
154 lda $8, 0x3fff
155 lda $26, ret_from_sys_call
156 bic $sp, $8, $8
157 mov $sp, $17
158 jsr $31, do_entIF
159.end entIF
160
161 .align 4
162 .globl entUna
163 .ent entUna
164entUna:
165 lda $sp, -256($sp)
166 stq $0, 0($sp)
167 ldq $0, 256($sp) /* get PS */
168 stq $1, 8($sp)
169 stq $2, 16($sp)
170 stq $3, 24($sp)
171 and $0, 8, $0 /* user mode? */
172 stq $4, 32($sp)
173 bne $0, entUnaUser /* yup -> do user-level unaligned fault */
174 stq $5, 40($sp)
175 stq $6, 48($sp)
176 stq $7, 56($sp)
177 stq $8, 64($sp)
178 stq $9, 72($sp)
179 stq $10, 80($sp)
180 stq $11, 88($sp)
181 stq $12, 96($sp)
182 stq $13, 104($sp)
183 stq $14, 112($sp)
184 stq $15, 120($sp)
185 /* 16-18 PAL-saved */
186 stq $19, 152($sp)
187 stq $20, 160($sp)
188 stq $21, 168($sp)
189 stq $22, 176($sp)
190 stq $23, 184($sp)
191 stq $24, 192($sp)
192 stq $25, 200($sp)
193 stq $26, 208($sp)
194 stq $27, 216($sp)
195 stq $28, 224($sp)
d70ddac1 196 mov $sp, $19
1da177e4
LT
197 stq $gp, 232($sp)
198 lda $8, 0x3fff
199 stq $31, 248($sp)
200 bic $sp, $8, $8
201 jsr $26, do_entUna
202 ldq $0, 0($sp)
203 ldq $1, 8($sp)
204 ldq $2, 16($sp)
205 ldq $3, 24($sp)
206 ldq $4, 32($sp)
207 ldq $5, 40($sp)
208 ldq $6, 48($sp)
209 ldq $7, 56($sp)
210 ldq $8, 64($sp)
211 ldq $9, 72($sp)
212 ldq $10, 80($sp)
213 ldq $11, 88($sp)
214 ldq $12, 96($sp)
215 ldq $13, 104($sp)
216 ldq $14, 112($sp)
217 ldq $15, 120($sp)
218 /* 16-18 PAL-saved */
219 ldq $19, 152($sp)
220 ldq $20, 160($sp)
221 ldq $21, 168($sp)
222 ldq $22, 176($sp)
223 ldq $23, 184($sp)
224 ldq $24, 192($sp)
225 ldq $25, 200($sp)
226 ldq $26, 208($sp)
227 ldq $27, 216($sp)
228 ldq $28, 224($sp)
229 ldq $gp, 232($sp)
230 lda $sp, 256($sp)
231 call_pal PAL_rti
232.end entUna
233
234 .align 4
235 .ent entUnaUser
236entUnaUser:
237 ldq $0, 0($sp) /* restore original $0 */
238 lda $sp, 256($sp) /* pop entUna's stack frame */
239 SAVE_ALL /* setup normal kernel stack */
240 lda $sp, -56($sp)
241 stq $9, 0($sp)
242 stq $10, 8($sp)
243 stq $11, 16($sp)
244 stq $12, 24($sp)
245 stq $13, 32($sp)
246 stq $14, 40($sp)
247 stq $15, 48($sp)
248 lda $8, 0x3fff
249 addq $sp, 56, $19
250 bic $sp, $8, $8
251 jsr $26, do_entUnaUser
252 ldq $9, 0($sp)
253 ldq $10, 8($sp)
254 ldq $11, 16($sp)
255 ldq $12, 24($sp)
256 ldq $13, 32($sp)
257 ldq $14, 40($sp)
258 ldq $15, 48($sp)
259 lda $sp, 56($sp)
260 br ret_from_sys_call
261.end entUnaUser
262
263 .align 4
264 .globl entDbg
265 .ent entDbg
266entDbg:
267 SAVE_ALL
268 lda $8, 0x3fff
269 lda $26, ret_from_sys_call
270 bic $sp, $8, $8
271 mov $sp, $16
272 jsr $31, do_entDbg
273.end entDbg
274\f
275/*
276 * The system call entry point is special. Most importantly, it looks
277 * like a function call to userspace as far as clobbered registers. We
278 * do preserve the argument registers (for syscall restarts) and $26
279 * (for leaf syscall functions).
280 *
281 * So much for theory. We don't take advantage of this yet.
282 *
283 * Note that a0-a2 are not saved by PALcode as with the other entry points.
284 */
285
286 .align 4
287 .globl entSys
288 .globl ret_from_sys_call
289 .ent entSys
290entSys:
291 SAVE_ALL
292 lda $8, 0x3fff
293 bic $sp, $8, $8
294 lda $4, NR_SYSCALLS($31)
295 stq $16, SP_OFF+24($sp)
296 lda $5, sys_call_table
297 lda $27, sys_ni_syscall
298 cmpult $0, $4, $4
299 ldl $3, TI_FLAGS($8)
300 stq $17, SP_OFF+32($sp)
301 s8addq $0, $5, $5
302 stq $18, SP_OFF+40($sp)
303 blbs $3, strace
304 beq $4, 1f
305 ldq $27, 0($5)
3061: jsr $26, ($27), alpha_ni_syscall
307 ldgp $gp, 0($26)
308 blt $0, $syscall_error /* the call failed */
309 stq $0, 0($sp)
310 stq $31, 72($sp) /* a3=0 => no error */
311
312 .align 4
313ret_from_sys_call:
314 cmovne $26, 0, $19 /* $19 = 0 => non-restartable */
315 ldq $0, SP_OFF($sp)
316 and $0, 8, $0
77edffb6 317 beq $0, ret_to_kernel
494486a1 318ret_to_user:
1da177e4
LT
319 /* Make sure need_resched and sigpending don't change between
320 sampling and the rti. */
321 lda $16, 7
322 call_pal PAL_swpipl
323 ldl $5, TI_FLAGS($8)
324 and $5, _TIF_WORK_MASK, $2
494486a1 325 bne $2, work_pending
1da177e4
LT
326restore_all:
327 RESTORE_ALL
328 call_pal PAL_rti
329
77edffb6
AV
330ret_to_kernel:
331 lda $16, 7
332 call_pal PAL_swpipl
333 br restore_all
334
1da177e4
LT
335 .align 3
336$syscall_error:
337 /*
338 * Some system calls (e.g., ptrace) can return arbitrary
339 * values which might normally be mistaken as error numbers.
340 * Those functions must zero $0 (v0) directly in the stack
341 * frame to indicate that a negative return value wasn't an
342 * error number..
343 */
344 ldq $19, 0($sp) /* old syscall nr (zero if success) */
345 beq $19, $ret_success
346
347 ldq $20, 72($sp) /* .. and this a3 */
348 subq $31, $0, $0 /* with error in v0 */
349 addq $31, 1, $1 /* set a3 for errno return */
350 stq $0, 0($sp)
351 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
352 stq $1, 72($sp) /* a3 for return */
353 br ret_from_sys_call
354
355$ret_success:
356 stq $0, 0($sp)
357 stq $31, 72($sp) /* a3=0 => no error */
358 br ret_from_sys_call
359.end entSys
360
361/*
362 * Do all cleanup when returning from all interrupts and system calls.
363 *
364 * Arguments:
365 * $5: TI_FLAGS.
366 * $8: current.
367 * $19: The old syscall number, or zero if this is not a return
368 * from a syscall that errored and is possibly restartable.
494486a1 369 * $20: The old a3 value
1da177e4
LT
370 */
371
372 .align 4
373 .ent work_pending
374work_pending:
375 and $5, _TIF_NEED_RESCHED, $2
376 beq $2, $work_notifysig
377
378$work_resched:
379 subq $sp, 16, $sp
380 stq $19, 0($sp) /* save syscall nr */
381 stq $20, 8($sp) /* and error indication (a3) */
382 jsr $26, schedule
383 ldq $19, 0($sp)
384 ldq $20, 8($sp)
385 addq $sp, 16, $sp
386 /* Make sure need_resched and sigpending don't change between
387 sampling and the rti. */
388 lda $16, 7
389 call_pal PAL_swpipl
390 ldl $5, TI_FLAGS($8)
391 and $5, _TIF_WORK_MASK, $2
392 beq $2, restore_all
393 and $5, _TIF_NEED_RESCHED, $2
394 bne $2, $work_resched
395
396$work_notifysig:
b927b3e2 397 mov $sp, $16
494486a1 398 bsr $1, do_switch_stack
b927b3e2
RH
399 mov $sp, $17
400 mov $5, $18
494486a1
AV
401 mov $19, $9 /* save old syscall number */
402 mov $20, $10 /* save old a3 */
403 and $5, _TIF_SIGPENDING, $2
404 cmovne $2, 0, $9 /* we don't want double syscall restarts */
1da177e4 405 jsr $26, do_notify_resume
494486a1
AV
406 mov $9, $19
407 mov $10, $20
1da177e4 408 bsr $1, undo_switch_stack
494486a1 409 br ret_to_user
1da177e4
LT
410.end work_pending
411
412/*
413 * PTRACE syscall handler
414 */
415
416 .align 4
417 .ent strace
418strace:
419 /* set up signal stack, call syscall_trace */
420 bsr $1, do_switch_stack
421 jsr $26, syscall_trace
422 bsr $1, undo_switch_stack
423
424 /* get the system call number and the arguments back.. */
425 ldq $0, 0($sp)
426 ldq $16, SP_OFF+24($sp)
427 ldq $17, SP_OFF+32($sp)
428 ldq $18, SP_OFF+40($sp)
429 ldq $19, 72($sp)
430 ldq $20, 80($sp)
431 ldq $21, 88($sp)
432
433 /* get the system call pointer.. */
434 lda $1, NR_SYSCALLS($31)
435 lda $2, sys_call_table
436 lda $27, alpha_ni_syscall
437 cmpult $0, $1, $1
438 s8addq $0, $2, $2
439 beq $1, 1f
440 ldq $27, 0($2)
4411: jsr $26, ($27), sys_gettimeofday
53293638 442ret_from_straced:
1da177e4
LT
443 ldgp $gp, 0($26)
444
445 /* check return.. */
446 blt $0, $strace_error /* the call failed */
447 stq $31, 72($sp) /* a3=0 => no error */
448$strace_success:
449 stq $0, 0($sp) /* save return value */
450
451 bsr $1, do_switch_stack
452 jsr $26, syscall_trace
453 bsr $1, undo_switch_stack
454 br $31, ret_from_sys_call
455
456 .align 3
457$strace_error:
458 ldq $19, 0($sp) /* old syscall nr (zero if success) */
459 beq $19, $strace_success
460 ldq $20, 72($sp) /* .. and this a3 */
461
462 subq $31, $0, $0 /* with error in v0 */
463 addq $31, 1, $1 /* set a3 for errno return */
464 stq $0, 0($sp)
465 stq $1, 72($sp) /* a3 for return */
466
467 bsr $1, do_switch_stack
468 mov $19, $9 /* save old syscall number */
469 mov $20, $10 /* save old a3 */
470 jsr $26, syscall_trace
471 mov $9, $19
472 mov $10, $20
473 bsr $1, undo_switch_stack
474
475 mov $31, $26 /* tell "ret_from_sys_call" we can restart */
476 br ret_from_sys_call
477.end strace
478\f
479/*
480 * Save and restore the switch stack -- aka the balance of the user context.
481 */
482
483 .align 4
484 .ent do_switch_stack
485do_switch_stack:
486 lda $sp, -SWITCH_STACK_SIZE($sp)
487 stq $9, 0($sp)
488 stq $10, 8($sp)
489 stq $11, 16($sp)
490 stq $12, 24($sp)
491 stq $13, 32($sp)
492 stq $14, 40($sp)
493 stq $15, 48($sp)
494 stq $26, 56($sp)
495 stt $f0, 64($sp)
496 stt $f1, 72($sp)
497 stt $f2, 80($sp)
498 stt $f3, 88($sp)
499 stt $f4, 96($sp)
500 stt $f5, 104($sp)
501 stt $f6, 112($sp)
502 stt $f7, 120($sp)
503 stt $f8, 128($sp)
504 stt $f9, 136($sp)
505 stt $f10, 144($sp)
506 stt $f11, 152($sp)
507 stt $f12, 160($sp)
508 stt $f13, 168($sp)
509 stt $f14, 176($sp)
510 stt $f15, 184($sp)
511 stt $f16, 192($sp)
512 stt $f17, 200($sp)
513 stt $f18, 208($sp)
514 stt $f19, 216($sp)
515 stt $f20, 224($sp)
516 stt $f21, 232($sp)
517 stt $f22, 240($sp)
518 stt $f23, 248($sp)
519 stt $f24, 256($sp)
520 stt $f25, 264($sp)
521 stt $f26, 272($sp)
522 stt $f27, 280($sp)
523 mf_fpcr $f0 # get fpcr
524 stt $f28, 288($sp)
525 stt $f29, 296($sp)
526 stt $f30, 304($sp)
527 stt $f0, 312($sp) # save fpcr in slot of $f31
528 ldt $f0, 64($sp) # dont let "do_switch_stack" change fp state.
529 ret $31, ($1), 1
530.end do_switch_stack
531
532 .align 4
533 .ent undo_switch_stack
534undo_switch_stack:
535 ldq $9, 0($sp)
536 ldq $10, 8($sp)
537 ldq $11, 16($sp)
538 ldq $12, 24($sp)
539 ldq $13, 32($sp)
540 ldq $14, 40($sp)
541 ldq $15, 48($sp)
542 ldq $26, 56($sp)
543 ldt $f30, 312($sp) # get saved fpcr
544 ldt $f0, 64($sp)
545 ldt $f1, 72($sp)
546 ldt $f2, 80($sp)
547 ldt $f3, 88($sp)
548 mt_fpcr $f30 # install saved fpcr
549 ldt $f4, 96($sp)
550 ldt $f5, 104($sp)
551 ldt $f6, 112($sp)
552 ldt $f7, 120($sp)
553 ldt $f8, 128($sp)
554 ldt $f9, 136($sp)
555 ldt $f10, 144($sp)
556 ldt $f11, 152($sp)
557 ldt $f12, 160($sp)
558 ldt $f13, 168($sp)
559 ldt $f14, 176($sp)
560 ldt $f15, 184($sp)
561 ldt $f16, 192($sp)
562 ldt $f17, 200($sp)
563 ldt $f18, 208($sp)
564 ldt $f19, 216($sp)
565 ldt $f20, 224($sp)
566 ldt $f21, 232($sp)
567 ldt $f22, 240($sp)
568 ldt $f23, 248($sp)
569 ldt $f24, 256($sp)
570 ldt $f25, 264($sp)
571 ldt $f26, 272($sp)
572 ldt $f27, 280($sp)
573 ldt $f28, 288($sp)
574 ldt $f29, 296($sp)
575 ldt $f30, 304($sp)
576 lda $sp, SWITCH_STACK_SIZE($sp)
577 ret $31, ($1), 1
578.end undo_switch_stack
579\f
580/*
581 * The meat of the context switch code.
582 */
583
584 .align 4
585 .globl alpha_switch_to
586 .ent alpha_switch_to
587alpha_switch_to:
588 .prologue 0
589 bsr $1, do_switch_stack
590 call_pal PAL_swpctx
591 lda $8, 0x3fff
592 bsr $1, undo_switch_stack
593 bic $sp, $8, $8
594 mov $17, $0
595 ret
596.end alpha_switch_to
597
598/*
599 * New processes begin life here.
600 */
601
602 .globl ret_from_fork
603 .align 4
604 .ent ret_from_fork
605ret_from_fork:
606 lda $26, ret_from_sys_call
607 mov $17, $16
608 jmp $31, schedule_tail
609.end ret_from_fork
610
611/*
612 * kernel_thread(fn, arg, clone_flags)
613 */
614 .align 4
615 .globl kernel_thread
616 .ent kernel_thread
617kernel_thread:
618 /* We can be called from a module. */
619 ldgp $gp, 0($27)
620 .prologue 1
621 subq $sp, SP_OFF+6*8, $sp
622 br $1, 2f /* load start address */
623
624 /* We've now "returned" from a fake system call. */
625 unop
626 blt $0, 1f /* error? */
627 ldi $1, 0x3fff
628 beq $20, 1f /* parent or child? */
629
630 bic $sp, $1, $8 /* in child. */
631 jsr $26, ($27)
632 ldgp $gp, 0($26)
633 mov $0, $16
634 mov $31, $26
635 jmp $31, sys_exit
636
6371: ret /* in parent. */
638
639 .align 4
6402: /* Fake a system call stack frame, as we can't do system calls
641 from kernel space. Note that we store FN and ARG as they
642 need to be set up in the child for the call. Also store $8
643 and $26 for use in the parent. */
644 stq $31, SP_OFF($sp) /* ps */
645 stq $1, SP_OFF+8($sp) /* pc */
646 stq $gp, SP_OFF+16($sp) /* gp */
647 stq $16, 136($sp) /* $27; FN for child */
648 stq $17, SP_OFF+24($sp) /* $16; ARG for child */
649 stq $8, 64($sp) /* $8 */
650 stq $26, 128($sp) /* $26 */
651 /* Avoid the HAE being gratuitously wrong, to avoid restoring it. */
652 ldq $2, alpha_mv+HAE_CACHE
653 stq $2, 152($sp) /* HAE */
654
655 /* Shuffle FLAGS to the front; add CLONE_VM. */
656 ldi $1, CLONE_VM|CLONE_UNTRACED
657 or $18, $1, $16
658 bsr $26, sys_clone
659
660 /* We don't actually care for a3 success widgetry in the kernel.
661 Not for positive errno values. */
662 stq $0, 0($sp) /* $0 */
77edffb6 663 br ret_to_kernel
1da177e4
LT
664.end kernel_thread
665
666/*
3db03b4a 667 * kernel_execve(path, argv, envp)
1da177e4
LT
668 */
669 .align 4
3db03b4a
AB
670 .globl kernel_execve
671 .ent kernel_execve
672kernel_execve:
1da177e4
LT
673 /* We can be called from a module. */
674 ldgp $gp, 0($27)
675 lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
676 .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0
677 stq $26, 0($sp)
678 stq $16, 8($sp)
679 stq $17, 16($sp)
680 stq $18, 24($sp)
681 .prologue 1
682
683 lda $16, 32($sp)
684 lda $17, 0
685 lda $18, SIZEOF_PT_REGS
686 bsr $26, memset !samegp
687
688 /* Avoid the HAE being gratuitously wrong, which would cause us
689 to do the whole turn off interrupts thing and restore it. */
690 ldq $2, alpha_mv+HAE_CACHE
691 stq $2, 152+32($sp)
692
693 ldq $16, 8($sp)
694 ldq $17, 16($sp)
695 ldq $18, 24($sp)
696 lda $19, 32($sp)
697 bsr $26, do_execve !samegp
698
699 ldq $26, 0($sp)
700 bne $0, 1f /* error! */
701
702 /* Move the temporary pt_regs struct from its current location
703 to the top of the kernel stack frame. See copy_thread for
704 details for a normal process. */
705 lda $16, 0x4000 - SIZEOF_PT_REGS($8)
706 lda $17, 32($sp)
707 lda $18, SIZEOF_PT_REGS
708 bsr $26, memmove !samegp
709
710 /* Take that over as our new stack frame and visit userland! */
711 lda $sp, 0x4000 - SIZEOF_PT_REGS($8)
712 br $31, ret_from_sys_call
713
7141: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
715 ret
3db03b4a 716.end kernel_execve
1da177e4
LT
717
718\f
719/*
720 * Special system calls. Most of these are special in that they either
721 * have to play switch_stack games or in some way use the pt_regs struct.
722 */
723 .align 4
724 .globl sys_fork
725 .ent sys_fork
726sys_fork:
727 .prologue 0
728 mov $sp, $21
729 bsr $1, do_switch_stack
730 bis $31, SIGCHLD, $16
731 mov $31, $17
732 mov $31, $18
733 mov $31, $19
734 mov $31, $20
735 jsr $26, alpha_clone
736 bsr $1, undo_switch_stack
737 ret
738.end sys_fork
739
740 .align 4
741 .globl sys_clone
742 .ent sys_clone
743sys_clone:
744 .prologue 0
745 mov $sp, $21
746 bsr $1, do_switch_stack
747 /* $16, $17, $18, $19, $20 come from the user. */
748 jsr $26, alpha_clone
749 bsr $1, undo_switch_stack
750 ret
751.end sys_clone
752
753 .align 4
754 .globl sys_vfork
755 .ent sys_vfork
756sys_vfork:
757 .prologue 0
758 mov $sp, $16
759 bsr $1, do_switch_stack
760 jsr $26, alpha_vfork
761 bsr $1, undo_switch_stack
762 ret
763.end sys_vfork
764
765 .align 4
766 .globl sys_sigreturn
767 .ent sys_sigreturn
768sys_sigreturn:
769 .prologue 0
53293638
AV
770 lda $9, ret_from_straced
771 cmpult $26, $9, $9
1da177e4
LT
772 mov $sp, $17
773 lda $18, -SWITCH_STACK_SIZE($sp)
774 lda $sp, -SWITCH_STACK_SIZE($sp)
775 jsr $26, do_sigreturn
53293638
AV
776 bne $9, 1f
777 jsr $26, syscall_trace
7781: br $1, undo_switch_stack
1da177e4
LT
779 br ret_from_sys_call
780.end sys_sigreturn
781
782 .align 4
783 .globl sys_rt_sigreturn
784 .ent sys_rt_sigreturn
785sys_rt_sigreturn:
786 .prologue 0
53293638
AV
787 lda $9, ret_from_straced
788 cmpult $26, $9, $9
1da177e4
LT
789 mov $sp, $17
790 lda $18, -SWITCH_STACK_SIZE($sp)
791 lda $sp, -SWITCH_STACK_SIZE($sp)
792 jsr $26, do_rt_sigreturn
53293638
AV
793 bne $9, 1f
794 jsr $26, syscall_trace
7951: br $1, undo_switch_stack
1da177e4
LT
796 br ret_from_sys_call
797.end sys_rt_sigreturn
798
1da177e4
LT
799 .align 4
800 .globl sys_sethae
801 .ent sys_sethae
802sys_sethae:
803 .prologue 0
804 stq $16, 152($sp)
805 ret
806.end sys_sethae
807
808 .align 4
809 .globl osf_getpriority
810 .ent osf_getpriority
811osf_getpriority:
812 lda $sp, -16($sp)
813 stq $26, 0($sp)
814 .prologue 0
815
816 jsr $26, sys_getpriority
817
818 ldq $26, 0($sp)
819 blt $0, 1f
820
821 /* Return value is the unbiased priority, i.e. 20 - prio.
822 This does result in negative return values, so signal
823 no error by writing into the R0 slot. */
824 lda $1, 20
825 stq $31, 16($sp)
826 subl $1, $0, $0
827 unop
828
8291: lda $sp, 16($sp)
830 ret
831.end osf_getpriority
832
833 .align 4
834 .globl sys_getxuid
835 .ent sys_getxuid
836sys_getxuid:
837 .prologue 0
838 ldq $2, TI_TASK($8)
b6dff3ec
DH
839 ldq $3, TASK_CRED($2)
840 ldl $0, CRED_UID($3)
841 ldl $1, CRED_EUID($3)
1da177e4
LT
842 stq $1, 80($sp)
843 ret
844.end sys_getxuid
845
846 .align 4
847 .globl sys_getxgid
848 .ent sys_getxgid
849sys_getxgid:
850 .prologue 0
851 ldq $2, TI_TASK($8)
b6dff3ec
DH
852 ldq $3, TASK_CRED($2)
853 ldl $0, CRED_GID($3)
854 ldl $1, CRED_EGID($3)
1da177e4
LT
855 stq $1, 80($sp)
856 ret
857.end sys_getxgid
858
859 .align 4
860 .globl sys_getxpid
861 .ent sys_getxpid
862sys_getxpid:
863 .prologue 0
864 ldq $2, TI_TASK($8)
865
866 /* See linux/kernel/timer.c sys_getppid for discussion
867 about this loop. */
9a5e7339
EB
868 ldq $3, TASK_GROUP_LEADER($2)
869 ldq $4, TASK_REAL_PARENT($3)
870 ldl $0, TASK_TGID($2)
8711: ldl $1, TASK_TGID($4)
1da177e4 872#ifdef CONFIG_SMP
9a5e7339 873 mov $4, $5
1da177e4 874 mb
9a5e7339
EB
875 ldq $3, TASK_GROUP_LEADER($2)
876 ldq $4, TASK_REAL_PARENT($3)
877 cmpeq $4, $5, $5
878 beq $5, 1b
1da177e4
LT
879#endif
880 stq $1, 80($sp)
1da177e4
LT
881 ret
882.end sys_getxpid
883
884 .align 4
1134723e
HC
885 .globl sys_alpha_pipe
886 .ent sys_alpha_pipe
887sys_alpha_pipe:
1da177e4
LT
888 lda $sp, -16($sp)
889 stq $26, 0($sp)
890 .prologue 0
891
10f303ae 892 mov $31, $17
1da177e4 893 lda $16, 8($sp)
10f303ae 894 jsr $26, do_pipe_flags
1da177e4
LT
895
896 ldq $26, 0($sp)
897 bne $0, 1f
898
899 /* The return values are in $0 and $20. */
900 ldl $1, 12($sp)
901 ldl $0, 8($sp)
902
903 stq $1, 80+16($sp)
9041: lda $sp, 16($sp)
905 ret
1134723e 906.end sys_alpha_pipe
1da177e4 907
1da177e4
LT
908 .align 4
909 .globl sys_execve
910 .ent sys_execve
911sys_execve:
912 .prologue 0
913 mov $sp, $19
914 jmp $31, do_sys_execve
915.end sys_execve
916
1da177e4
LT
917 .align 4
918 .globl alpha_ni_syscall
919 .ent alpha_ni_syscall
920alpha_ni_syscall:
921 .prologue 0
922 /* Special because it also implements overflow handling via
923 syscall number 0. And if you recall, zero is a special
924 trigger for "not an error". Store large non-zero there. */
925 lda $0, -ENOSYS
926 unop
927 stq $0, 0($sp)
928 ret
929.end alpha_ni_syscall