patch-1.3.44 linux/arch/sparc/kernel/entry.S
Next file: linux/arch/sparc/kernel/errtbls.c
Previous file: linux/arch/sparc/kernel/c_mp.c
Back to the patch index
Back to the overall index
- Lines: 2657
- Date:
Sat Nov 25 02:57:55 1995
- Orig file:
v1.3.43/linux/arch/sparc/kernel/entry.S
- Orig date:
Tue Jun 27 14:11:31 1995
diff -u --recursive --new-file v1.3.43/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
@@ -1,1950 +1,887 @@
-/* arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
- *
- * Sparc traps are so ugly, this code is going to go through a lot
- * of changes as I find out more interesting things. See head.S for
- * the trap table and how it works, this will show you how we get
- * to these routines.
+/* $Id: entry.S,v 1.64 1995/11/25 00:57:53 davem Exp $
+ * arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/config.h>
#include <asm/head.h>
#include <asm/asi.h>
+#include <asm/kgdb.h>
#include <asm/contregs.h>
+#include <asm/ptrace.h>
#include <asm/psr.h>
#include <asm/cprefix.h>
#include <asm/vaddrs.h>
#include <asm/memreg.h>
#include <asm/page.h>
+#include <asm/winmacro.h>
+#include <asm/signal.h>
+#include <asm/errno.h>
#define NR_SYSCALLS 255 /* Each OS is different... */
-/* A debugging macro, it just prints a dot on the screen. For now
- * it is only used in the context switch code since it is so delicate
- * I need to use the prom putchar() routines and reload the pointers
- * every time. This clobbers %l7 and %o0.
- */
-#define DO_SPARC_DOT \
- sethi %hi(C_LABEL(romvec)), %l7; \
- ld [%l7 + %lo(C_LABEL(romvec))], %l7; \
- ld [%l7 + 0x54], %l7; \
- or %g0, '.', %o0; \
- call %l7; \
- nop; \
- nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; \
-
-/* Another macro, the name speaks for itself. */
-#define DROP_THE_BOMB \
- sethi %hi(C_LABEL(romvec)), %l7; \
- ld [%l7 + %lo(C_LABEL(romvec))], %l7; \
- ld [%l7 + 0x74], %l7; \
- call %l7; \
- nop; \
-
-/* Turn off interrupts while we change contexts. Clobbers %l7 */
-#define TRAPS_OFF \
- rd %psr, %l7; \
- andn %l7, (PSR_ET), %l7; \
- wr %l7, 0x0, %psr; \
-
-/* Here are macros for routines we do often, this allows me to inline this
- * without making the code look real ugly. Well, the macro looks ugly too
- * but makes the trap entry code easier to understand.
+/* All trap entry points _must_ begin with this macro or else you
+ * lose. It makes sure the kernel has a proper window so that
+ * c-code can be called. Some day for SMP we'll grab klock here.
+ */
+#define SAVE_ALL \
+ sethi %hi(trap_setup), %l4; \
+ jmpl %l4 + %lo(trap_setup), %l6; \
+ nop;
+
+/* All traps low-level code here must end with this macro.
+ * For SMP configurations the ret_trap_entry routine will
+ * have to appropriate code to actually release the kernel
+ * entry lock.
+ */
+#define RESTORE_ALL \
+ b ret_trap_entry; \
+ nop;
+
+/* First, KGDB low level things. This is a rewrite
+ * of the routines found in the sparc-stub.c asm() statement
+ * from the gdb distribution. This is also dual-purpose
+ * as a software trap for userlevel programs.
*/
+ .data
+ .align 4
-/* I really don't like synthetic instructions. So I avoid them like the
- * plague.
- */
+in_trap_handler:
+ .word 0
-/* Note that when I have to write a window out, and it is a user's window, I
- * have to check that the pages of memory that I am going to throw the window(s)
- * onto are valid and are writable by the user (this is %sp to %sp + 64) before
- * I start dumping stuff there. We always assume that kernels stack is ok.
- * XXX Will change on MP's XXX
- *
- * If we have to save a kernel window, only one branch is taken. This should
- * make trap handlers quicker in this scenario.
- *
- * Once 'current' is loaded into %g6, it stays there until we leave
- * this macro.
- */
+ .text
+ .align 4
-/* I will document how this works real soon. TODO */
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
-#define TRAP_WIN_CLEAN \
- or %g0, %g5, %l5; /* we need the globals to do our work */ \
- or %g0, %g6, %l6; /* and %l0 to %l4 are loaded with important */ \
- or %g0, %g7, %l7; /* information like the psr and pc's to return to */ \
- sethi %hi( C_LABEL(current) ), %g6; \
- ld [%g6 + %lo( C_LABEL(current) )], %g6; \
- ld [%g6 + THREAD_UWINDOWS], %g7; /* how many user wins are active? */ \
- subcc %g7, 0x0, %g0; \
- bne 2f; /* If there are any, branch. */ \
- save %g0, %g0, %g0; /* Save into that window either way. */ \
- std %l0, [%sp]; /* If above shows only kernel windows */ \
-1: std %l2, [%sp + 0x8]; /* then we get here. */ \
- std %l4, [%sp + 0x10]; \
- std %l6, [%sp + 0x18]; \
- std %i0, [%sp + 0x20]; \
- std %i2, [%sp + 0x28]; \
- std %i4, [%sp + 0x30]; \
- std %i6, [%sp + 0x38]; \
- or %g0, 0x1, %g5; \
- rd %psr, %g7; \
- sll %g5, %g7, %g5; \
- wr %g5, 0x0, %wim; /* update %wim to 'now' invalid */ \
- and %g7, 0x1f, %g7; \
- sethi %hi( C_LABEL(current) ), %g6; \
- ld [%g6 + %lo( C_LABEL(current) )], %g6; \
- st %g7, [%g6 + THREAD_WIM]; /* save 'this' threads mask */ \
- restore %g0, %g0, %g0; \
- or %g0, %l5, %g5; /* restore the globals we used */ \
- or %g0, %l6, %g6; \
- b 8f; /* we are done */ \
- or %g0, %l7, %g7; \
-2: sub %g7, 0x1, %g7; \
- sethi %hi( C_LABEL(current) ), %g6; \
- ld [%g6 + %lo( C_LABEL(current) )], %g6; \
- st %g7, [%g6 + THREAD_UWINDOWS]; /* There are user windows if we */ \
- andcc %sp, 0x7, %g0; /* get here. Check for stack alignment. */ \
- bne 5f; /* Stack is unaligned, yuck. */ \
- sra %sp, 0x1e, %g7; /* This stuff checks to see if top 3-bits */ \
- subcc %g7, 0x0, %g0; /* of stack pointer address are ok. */ \
- be,a 3f; \
- andn %sp, 0xfff, %g7; \
- subcc %g7, -1, %g0; \
- bne 5f; /* bad stack pointer, ugh */ \
- andn %sp, 0xfff, %g7; \
-3: lda [%g7] ASI_PTE, %g7; /* Ok, user stack is a valid address */ \
- srl %g7, 0x1d, %g7; \
- subcc %g7, 0x6, %g0; /* Can the user write to it? */ \
- bne 5f; \
- and %sp, 0xfff, %g7; \
- subcc %g7, 0xfc1, %g0; /* Is our save area on one page? */ \
- bl,a 1b; \
- std %l0, [%sp]; \
- add %sp, 0x38, %g5; /* Nope, have to check both pages */ \
- sra %g5, 0x1e, %g7; \
- subcc %g7, 0x0, %g0; \
- be,a 4f; \
- andn %g5, 0xfff, %g7; \
- subcc %g7, -1, %g0; \
- bne 5f; \
- andn %g5, 0xfff, %g7; \
-4: lda [%g7] ASI_PTE, %g7; /* Stack space in 2nd page is valid */ \
- srl %g7, 0x1d, %g7; \
- subcc %g7, 0x6, %g0; /* Can user write here too? */ \
- be,a 1b; \
- std %l0, [%sp]; \
-5: ld [%g6 + THREAD_UWINDOWS], %g7; /* This is due to either bad page perms */ \
- add %g6, THREAD_REG_WINDOW, %g5; /* for the users stack area, or the stack */ \
-6: std %l0, [%g5]; /* pointer is misaligned. See above. */ \
- std %l2, [%g5 + 0x8]; \
- std %l4, [%g5 + 0x10]; \
- std %l6, [%g5 + 0x18]; \
- std %i0, [%g5 + 0x20]; \
- std %i2, [%g5 + 0x28]; \
- std %i4, [%g5 + 0x30]; \
- std %i6, [%g5 + 0x38]; \
- subcc %g7, 0x1, %g7; \
- bge,a 6b; /* while(uwindows>=0) { write_win(); */ \
- save %g5, 0x40, %g5; /* uwindows--; } */ \
- st %sp, [%g6 + THREAD_USP]; \
- or %g0, 0x1, %g5; \
- rd %psr, %g7; \
- sll %g5, %g7, %g5; \
- wr %g5, 0x0, %wim; \
- and %g7, 0x1f, %g7; \
- st %g7, [%g6 + THREAD_WIM]; /* Update thread_struct fields */ \
- ld [%g6 + THREAD_UWINDOWS], %g7; \
- add %g7, 0x1, %g5; \
- st %g5, [%g6 + THREAD_W_SAVED]; \
- st %g0, [%g6 + THREAD_UWINDOWS]; \
-7: subcc %g7, 0x1, %g7; /* Restore back to where we started. */ \
- bge 7b; \
- restore %g0, %g0, %g0; \
- or %g0, %l5, %g5; /* Restore the globals. */ \
- or %g0, %l6, %g6; \
- or %g0, %l7, %g7; \
-8: nop; /* We are done when we get here. */ \
-
-/* As if the last macro wasn't enough, we have to go through a very similar routine
- * upon entry to most traps and interrupts. This is save away the current window
- * if it is the trap window, clean it, and adjust the stack for the handler c-code
- * to work.
- *
- * See asm-sparc/cprefix.h to see how the CONCAT macros work.
- */
-/* NOTE: The system call entry code ASSUMES that the ENTER_TRAP macro
- * does NOT touch register %l7 and leaves the same contents after
- * the macro is done. Keep in mind if you change this code.
- */
-
-#define ENTER_TRAP(label) \
- rd %wim, %l4; \
- or %g0, 0x1, %l5; \
- sll %l5, %l0, %l5; \
- andcc %l0, PSR_PS, %g0; \
- bz CONCAT1(label, 1); \
- andcc %l4, %l5, %g0; \
- bz,a CONCAT1(label, 3); \
- sub %fp, 0xb0, %sp; \
- TRAP_WIN_CLEAN \
- b CONCAT1(label, 3); \
- sub %fp, 0xb0, %sp; \
-CONCAT1(label, 1): \
- sethi %hi( C_LABEL(current) ), %l6; \
- ld [%l6 + %lo( C_LABEL(current) )], %l6; \
- ld [%l6 + THREAD_WIM], %l5; \
- and %l0, 0x1f, %l4; \
- cmp %l5, %l3; \
- ble,a CONCAT1(label, 4); \
- sethi %hi( C_LABEL(nwindowsm1) ), %l4; \
- sub %l5, %l3, %l3; \
- b CONCAT1(label, 5); \
- sub %l3, 0x1, %l5; \
-CONCAT1(label, 4): \
- ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4; \
- sub %l4, %l3, %l4; \
- add %l5, %l4, %l5; \
-CONCAT1(label, 5): \
- st %l5, [%l6 + THREAD_UWINDOWS]; \
- bz,a CONCAT1(label, 2); \
- sethi %hi(C_LABEL(current)), %l6; \
- TRAP_WIN_CLEAN \
- sethi %hi(C_LABEL(current)), %l6; \
-CONCAT1(label, 2): \
- ld [%l6 + %lo(C_LABEL(current))], %l6; \
- ld [%l6 + TASK_KSTACK_PG], %l6; \
- add %l6, (PAGE_SIZE - 96 - 80), %l6; \
- andn %l6, 0x7, %l6; \
- or %g0, %l6, %sp; \
-CONCAT1(label, 3):
+ .globl C_LABEL(trap_low)
+C_LABEL(trap_low):
+ rd %wim, %l3
+ SAVE_ALL
-/* What needs to be executed upon entry to an interrupt.
- *
- * See asm-sparc/cprefix.h to see how the CONCAT macros work.
- */
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ inc %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ /* Make sure kgdb sees the same state we just saved. */
+ LOAD_PT_GLOBALS(sp)
+ LOAD_PT_INS(sp)
+ ld [%sp + STACKFRAME_SZ + PT_Y], %l4
+ ld [%sp + STACKFRAME_SZ + PT_WIM], %l3
+ ld [%sp + STACKFRAME_SZ + PT_PSR], %l0
+ ld [%sp + STACKFRAME_SZ + PT_PC], %l1
+ ld [%sp + STACKFRAME_SZ + PT_NPC], %l2
+ rd %tbr, %l5 /* Never changes... */
+
+ /* Make kgdb exception frame. */
+ sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[72] local var
+ SAVE_KGDB_GLOBALS(sp)
+ SAVE_KGDB_INS(sp)
+ SAVE_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)
+
+ /* We are increasing PIL, so two writes. */
+ or %l0, PSR_PIL, %l0
+ wr %l0, 0, %psr
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
-#define ENTER_IRQ(label) \
- rd %wim, %l4; \
- or %g0, 0x1, %l5; \
- sll %l5, %l0, %l5; \
- andcc %l0, PSR_PS, %g0; \
- bz CONCAT1(label, 1); \
- andcc %l4, %l5, %g0; \
- bz,a CONCAT1(label, 0); \
- sethi %hi( C_LABEL(eintstack) ), %l7; \
- TRAP_WIN_CLEAN \
- sethi %hi( C_LABEL(eintstack) ), %l7; \
-CONCAT1(label, 0): \
- subcc %fp, %l7, %g0; \
- bge,a CONCAT1(label, 3); \
- sub %l7, 0xb0, %sp; \
- b CONCAT1(label, 3); \
- sub %fp, 0xb0, %sp; \
-CONCAT1(label, 1): \
- sethi %hi( C_LABEL(current) ), %l6; \
- ld [%l6 + %lo( C_LABEL(current) )], %l6; \
- ld [%l6 + THREAD_WIM], %l5; \
- and %l0, 0x1f, %l7; \
- cmp %l5, %l7; \
- ble,a CONCAT1(label, 4); \
- sethi %hi( C_LABEL(nwindowsm1) ), %l4; \
- sub %l5, %l7, %l7; \
- b CONCAT1(label, 5); \
- sub %l7, 0x1, %l5; \
-CONCAT1(label, 4): \
- ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4; \
- sub %l4, %l7, %l4; \
- add %l5, %l4, %l5; \
-CONCAT1(label, 5): \
- st %l5, [%l6 + THREAD_UWINDOWS]; \
- bz,a CONCAT1(label, 2); \
- sethi %hi( C_LABEL(eintstack) ), %l7; \
- TRAP_WIN_CLEAN \
- sethi %hi( C_LABEL(eintstack) ), %l7; \
-CONCAT1(label, 2): \
- sub %l7, 0xb0, %sp; \
-CONCAT1(label, 3):
+ call C_LABEL(handle_exception)
+ add %sp, STACKFRAME_SZ, %o0 ! Pass address of registers
+ /* Load new kgdb register set. */
+ LOAD_KGDB_GLOBALS(sp)
+ LOAD_KGDB_INS(sp)
+ LOAD_KGDB_SREGS(sp, l0, l2)
+ ld [%sp + STACKFRAME_SZ + KGDB_WIM], %l6
+ wr %l0, 0x0, %y
+
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ add %sp,(16+1+6+1+72)*4,%sp ! Undo the kgdb trap frame.
+
+ /* Now take what kgdb did and place it into the pt_regs
+ * frame which SparcLinux RESTORE_ALL understands.,
+ */
+ STORE_PT_INS(sp)
+ STORE_PT_GLOBALS(sp)
+ STORE_PT_YREG(sp, g2)
+ STORE_PT_PRIV(sp, l1, l2, l3, l6)
+
+ /* Cross your fingers... */
+ RESTORE_ALL
+
+
+#ifdef CONFIG_BLK_DEV_FD
+ .align 4
+ .globl C_LABEL(floppy_hardint)
+C_LABEL(floppy_hardint):
+ /* Can only use regs %l3->%l7:
+ * %l3 -- base address of fdc registers
+ * %l4 -- doing_pdma upon entry, AUXIO reg vaddr after
+ * %l5 -- pdma_vaddr
+ * %l6 -- pdma_size
+ * %l7 -- floppy_softint
+ */
+
+ /* Do we have work to do? */
+ sethi %hi(C_LABEL(doing_pdma)), %l4
+ ld [%l4 + %lo(C_LABEL(doing_pdma))], %l4
+ cmp %l4, 0
+ be floppy_dosoftint
+ nop
+
+ /* Load fdc register base */
+ sethi %hi(C_LABEL(fdc_status)), %l3
+ ld [%l3 + %lo(C_LABEL(fdc_status))], %l3
+
+ /* Setup register addresses */
+ sethi %hi(C_LABEL(pdma_vaddr)), %l5 ! transfer buffer
+ ld [%l5 + %lo(C_LABEL(pdma_vaddr))], %l4
+ sethi %hi(C_LABEL(pdma_size)), %l5 ! bytes to go
+ ld [%l5 + %lo(C_LABEL(pdma_size))], %l6
+next_byte:
+ ldub [%l3], %l7
+ andcc %l7, 0x80, %g0 ! Does fifo still have data
+ bz floppy_fifo_emptied ! fifo has been emptied...
+ andcc %l7, 0x20, %g0 ! in non-dma mode still?
+ bz floppy_overrun ! nope, overrun
+ andcc %l7, 0x40, %g0 ! 0=write 1=read
+ bz floppy_write
+ sub %l6, 0x1, %l6
+
+ /* Ok, actually read this byte */
+ ldub [%l3 + 1], %l7
+ orcc %g0, %l6, %g0
+ stb %l7, [%l4]
+ bne next_byte
+ add %l4, 0x1, %l4
+
+ b floppy_tdone
+ nop
+
+floppy_write:
+ /* Ok, actually write this byte */
+ ldub [%l4], %l7
+ orcc %g0, %l6, %g0
+ stb %l7, [%l3 + 1]
+ bne next_byte
+ add %l4, 0x1, %l4
+
+ /* fall through... */
+floppy_tdone:
+ sethi %hi(C_LABEL(pdma_vaddr)), %l5
+ st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
+ sethi %hi(C_LABEL(pdma_size)), %l5
+ st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
+ /* Flip terminal count pin */
+ sethi %hi(AUXIO_VADDR), %l4
+ ldub [%l4 + %lo(AUXIO_VADDR) + 0x3], %l5
+ or %l5, 0xf4, %l5
+ stb %l5, [%l4 + %lo(AUXIO_VADDR) + 0x3]
+
+ /* Kill some time so the bits set */
+ WRITE_PAUSE
+ WRITE_PAUSE
+
+ ldub [%l4 + %lo(AUXIO_VADDR) + 0x3], %l5
+ andn %l5, 0x04, %l5
+ or %l5, 0xf0, %l5
+ stb %l5, [%l4 + %lo(AUXIO_VADDR) + 0x3]
+
+ /* Prevent recursion */
+ sethi %hi(C_LABEL(doing_pdma)), %l4
+ b floppy_dosoftint
+ st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
+
+ /* We emptied the FIFO, but we haven't read everything
+ * as of yet. Store the current transfer address and
+ * bytes left to read so we can continue when the next
+ * fast IRQ comes in.
+ */
+floppy_fifo_emptied:
+ sethi %hi(C_LABEL(pdma_vaddr)), %l5
+ st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
+ sethi %hi(C_LABEL(pdma_size)), %l7
+ st %l6, [%l7 + %lo(C_LABEL(pdma_size))]
- .text
- .align 4
+ /* Restore condition codes */
+ wr %l0, 0x0, %psr
+ WRITE_PAUSE
-/* Bad trap handler */
- .globl bad_trap_handler
-bad_trap_handler:
- ENTER_TRAP(bad_trap_handler)
+ jmp %l1
+ rett %l2
- or %g0, %l3, %o0
- or %g0, %l0, %o1
- call C_LABEL(do_hw_interrupt)
- or %g0, %l1, %o2
+floppy_overrun:
+ sethi %hi(C_LABEL(pdma_vaddr)), %l5
+ st %l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]
+ sethi %hi(C_LABEL(pdma_size)), %l5
+ st %l6, [%l5 + %lo(C_LABEL(pdma_size))]
+ /* Prevent recursion */
+ sethi %hi(C_LABEL(doing_pdma)), %l4
+ st %g0, [%l4 + %lo(C_LABEL(doing_pdma))]
- jmp %l1
- rett % l2
-
- .align 4
- .globl sparc_timer
-sparc_timer:
- ENTER_IRQ(sparc_timer)
-
- sethi %hi(C_LABEL(master_l10_limit)), %l4
- ld [%l4 + %lo(C_LABEL(master_l10_limit))], %l4
- ld [%l4], %g0 ! read the limit register
-
- std %g2, [%sp + C_STACK + PT_G2]
- or %g0, %g1, %l7
- rd %y, %l6
- std %g4, [%sp + C_STACK + PT_G4]
- andn %l0, PSR_PIL, %l4
-/* sll %l3, 0x8, %l5 */
- std %g6, [%sp + C_STACK + PT_G6]
-/* or %l5, %l4, %l4 */
+ /* fall through... */
+floppy_dosoftint:
+ rd %wim, %l3
+ SAVE_ALL
- /* Magic, we can't increase PIL and set ET at the same
- * time or the chip calls prom_panic().
- */
-/* wr %l4, 0x0, %psr */
+ /* Set all IRQs off. */
+ or %l0, PSR_PIL, %l4
+ wr %l4, 0x0, %psr
wr %l4, PSR_ET, %psr
+ WRITE_PAUSE
- or %g0, 10, %o0
- add %sp, C_STACK, %o1
- call C_LABEL(do_IRQ)
- nop
-
- or %g0, %l7, %g1
- wr %l6, 0x0, %y
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
+ mov 11, %o0 ! floppy irq level
+ call C_LABEL(floppy_interrupt)
+ add %sp, STACKFRAME_SZ, %o1 ! struct pt_regs *regs
- b ret_trap_entry
- wr %l0, 0x0, %psr
+ RESTORE_ALL
+
+#endif /* (CONFIG_BLK_DEV_FD) */
+
+ /* Bad trap handler */
+ .globl bad_trap_handler
+bad_trap_handler:
+ SAVE_ALL
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
+ mov %l7, %o0 ! trap number
+ mov %l0, %o1 ! psr
+ call C_LABEL(do_hw_interrupt)
+ mov %l1, %o2 ! pc
+ RESTORE_ALL
+
/* For now all IRQ's not registered get sent here. handler_irq() will
* see if a routine is registered to handle this interrupt and if not
* it will say so on the console.
*/
- .align 4
- .globl real_irq_entry
+ .align 4
+ .globl real_irq_entry
real_irq_entry:
- ENTER_IRQ(real_irq_entry)
- std %g2, [%sp + C_STACK + PT_G2]
- or %g0, %g1, %l7
- rd %y, %l6
- std %g4, [%sp + C_STACK + PT_G4]
- andn %l0, PSR_PIL, %l4
- sll %l3, 0x8, %l5
- std %g6, [%sp + C_STACK + PT_G6]
- or %l5, %l4, %l4
+ SAVE_ALL
+ /* start atomic operation with respect to software interrupts */
+ sethi %hi(C_LABEL(intr_count)), %l4
+ ld [%l4 + %lo(C_LABEL(intr_count))], %l5
+ add %l5, 0x1, %l5
+ st %l5, [%l4 + %lo(C_LABEL(intr_count))]
+
+ /* Enable traps w/IRQs off, so we can call c-code properly.
+ * Note how we are increasing PIL so we need to do two writes
+ * to work around a MicroSPARC bug of sorts.
+ */
+ or %l0, PSR_PIL, %l4
wr %l4, 0x0, %psr
wr %l4, PSR_ET, %psr
+ WRITE_PAUSE
- std %l0, [%sp + C_STACK + PT_PSR]
- std %l2, [%sp + C_STACK + PT_NPC]
-
- or %g0, %l3, %o0
- add %sp, C_STACK, %o1
+ mov %l7, %o0 ! irq level
call C_LABEL(handler_irq)
- nop
-
- or %g0, %l7, %g1
- wr %l6, 0x0, %y
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l0, 0x0, %psr
-
-
-/* This routine is optimized for kernel window fills. User fills take about two
- * or three extra jumps on the average. We'll see how this works out.
- */
-
-/* Don't use local labels, or if you do be REAL CAREFUL. TRAP_WIN_CLEAN is
- * full of them! If you think this routine is hairy, window fills are worse,
- * see below.
- */
-
- .align 4
- .globl spill_window_entry
-spill_window_entry:
- andcc %l0, PSR_PS, %g0 ! see if this is a user window fill
- bz,a spill_from_user
- nop
-
- TRAP_WIN_CLEAN /* danger, danger... */
- wr %l0, 0x0, %psr
- nop
- jmp %l1
- rett %l2
+ add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr
-spill_from_user:
- sethi %hi( C_LABEL(current) ), %l6
- ld [%l6 + %lo( C_LABEL(current) )], %l6
- ld [%l6 + THREAD_WIM], %l5
- and %l0, 0x1f, %l3
-
-/* I don't know what's worse, the extra comparison here, or an extra load
- * from a lookup table, we'll see.
- */
- cmp %l5, %l3
- ble,a 1f
- sethi %hi( C_LABEL(nwindowsm1) ), %l4
- sub %l5, %l3, %l3
- b 2f
- sub %l3, 0x1, %l5
-1:
- ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
- sub %l4, %l3, %l4
- add %l5, %l4, %l5
+rie_checkbh:
+ sethi %hi(C_LABEL(intr_count)), %l4
+ ld [%l4 + %lo(C_LABEL(intr_count))], %l5
+ subcc %l5, 0x1, %l5
+ bne 2f /* IRQ within IRQ, get out of here... */
+ nop
+ sethi %hi(C_LABEL(bh_active)), %l3
+ ld [%l3 + %lo(C_LABEL(bh_active))], %g2
+ sethi %hi(C_LABEL(bh_mask)), %l3
+ ld [%l3 + %lo(C_LABEL(bh_mask))], %g3
+ andcc %g2, %g3, %g0
+ be 2f
+ nop
+ call C_LABEL(do_bottom_half)
+ nop
+ /* Try again... */
+ b rie_checkbh
+ nop
+
2:
- st %l5, [%l6 + THREAD_UWINDOWS]
-
- TRAP_WIN_CLEAN /* danger, danger... */
- sethi %hi( C_LABEL(current) ), %l6
- ld [%l6 + %lo( C_LABEL(current) )], %l6
- ld [%l6 + THREAD_KSP], %sp
- and %l0, 0x1f, %l3
- sethi %hi(lnx_winmask), %l6
- or %l6, %lo(lnx_winmask), %l6
- ldub [%l6 + %l3], %l5
- rd %wim, %l4
- jmp %l1
- rett %l2
+ st %l5, [%l4 + %lo(C_LABEL(intr_count))]
+ RESTORE_ALL
-/* A window spill has occurred. This presents a weird situation, a restore
- * was attempted and a trap occurred. Therefore the restore attempt had no
- * effect on window movement and the trap saved, which means it went in the
- * other direction. :-( We are in a trap window which is two restores away
- * from the window we want to un-invalidate so to speak and three away from
- * the one which will become invalid after this routine. There are probably
- * bugs already this routine. Bugs suck.
- */
-
-/* This is a very complicated and hairy routine, don't expect to understand
- * it the first time. :>
- */
-
- .align 4
- .globl fill_window_entry
-fill_window_entry:
- wr %g0, 0, %wim ! Can not enter invalid register without this.
- andcc %l0, 0x40, %g0 ! From user?
- restore ! restore to where trap occurred
- bz fill_from_user
- restore ! enter invalid register, whee...
- restore %g0, 0x1, %l1 ! enter one-past invalid register
- rd %psr, %l0 ! this is the window we need to save
- and %l0, 0x1f, %l0
- sll %l1, %l0, %l1
- wr %l1, 0x0, %wim
- sethi %hi( C_LABEL(current) ), %l1
- ld [%l1 + %lo( C_LABEL(current) )], %l1
- st %l0, [%l1 + THREAD_WIM]
- save %g0, %g0, %g0 ! back to invalid register
- ldd [%sp], %l0 ! load the window from stack
- ldd [%sp + 8], %l2
- ldd [%sp + 16], %l4
- ldd [%sp + 24], %l6
- ldd [%sp + 32], %i0
- ldd [%sp + 40], %i2
- ldd [%sp + 48], %i4
- ldd [%sp + 56], %i6
- save %g0, %g0, %g0 ! to window where trap happened
- save %g0, %g0, %g0 ! back to trap window, so rett works
- wr %l0, 0x0, %psr ! load condition codes
- nop
- jmp %l1
- rett %l2 ! are you as confused as I am?
+/* Soft IRQ's are handled just like hard IRQ's except that we
+ * need to clear the IRQ line ourselves (in the interrupt reg)
+ * and we don't take care of bottom-half handlers here. We'll
+ * just deal with it at the next clock tick, and since software
+ * IRQ's relatively don't happen that often....
+ * XXX BIG XXX Turn the software IRQ bit we need to clear into
+ * XXX BIG XXX an element reference in an array that we can set
+ * XXX BIG XXX a boot time based upon arch type
+ * XXX BIG XXX OR... rewrite the appropriate IRQ trap table
+ * XXX BIG XXX entries once the arch is detected (sun4/4c or sun4m)
+ *
+ * XXX EVEN BIGGER XXX Linux has bh_handlers for software interrupts
+ * XXX EVEN BIGGER XXX so we do not even have to worry about this
+ * XXX EVEN BIGGER XXX brain damaged software interrupt mechanism.
+ */
+
+ .align 4
+ .globl soft_irq_entry
+soft_irq_entry:
+ SAVE_ALL
+
+ /* We have tucked the bit to clear in the int reg into
+ * %l4, take care of it now before we do anything else.
+ */
+ sethi %hi(INTREG_VADDR), %l5
+ ldsb [%l5 + %lo(INTREG_VADDR)], %l6
+ andn %l6, %l4, %l6
+ stb %l6, [%l5 + %lo(INTREG_VADDR)]
+
+ /* start atomic operation with respect to software interrupts */
+ sethi %hi(C_LABEL(intr_count)), %l4
+ ld [%l4 + %lo(C_LABEL(intr_count))], %l5
+ add %l5, 0x1, %l5
+ st %l5, [%l4 + %lo(C_LABEL(intr_count))]
+
+ or %l0, PSR_PIL, %l4
+ wr %l4, 0x0, %psr ! grrr!
+ wr %l4, PSR_ET, %psr ! double grrr!
-fill_from_user:
- andcc %sp, 0x7, %g0 ! check for alignment of user stack
- bne fill_bad_stack
- sra %sp, 0x1e, %l7
- cmp %l7, 0x0
- be,a 1f
- andn %sp, 0xfff, %l7
- cmp %l7, -1
- bne fill_bad_stack
- andn %sp, 0xfff, %l7
-1:
- lda [%l7] ASI_PTE, %l7
- srl %l7, 0x1d, %l7
- andn %l7, 0x2, %l7
- cmp %l7, 0x4
- bne fill_bad_stack
- and %sp, 0xfff, %l7
- cmp %l7, 0xfc1
- bl,a fill_stack_ok
- restore %g0, 1, %l1
- add %sp, 0x38, %l5
- sra %sp, 0x1e, %l7
- cmp %l7, 0x0
- be,a 1f
- andn %sp, 0xfff, %l7
- cmp %l7, -1
- bne fill_bad_stack
- andn %sp, 0xfff, %l7
-1:
- lda [%l7] ASI_PTE, %l7
- srl %l7, 0x1d, %l7
- andn %l7, 0x2, %l7
- cmp %l7, 0x4
- be,a fill_stack_ok
- restore %g0, 0x1, %l1
-
-fill_bad_stack:
- save %g0, %g0, %g0 ! save to where restore happened
- save %g0, 0x1, %l4 ! save is an add remember? to trap window
- sethi %hi( C_LABEL(current) ), %l6
- ld [%l6 + %lo( C_LABEL(current) )], %l6
- st %l4, [%l6 + THREAD_UWINDOWS] ! update current->tss values
- ld [%l6 + THREAD_WIM], %l5
- sll %l4, %l5, %l4
- wr %l4, 0x0, %wim
- ld [%l6 + THREAD_KSP], %sp ! set to kernel stack pointer
- wr %l0, PSR_ET, %psr ! turn off traps
- std %l0, [%sp + C_STACK] ! set up thread_frame XXX
- rd %y, %l3
- std %l2, [%sp + C_STACK + 0x8]
- or %g0, 0x6, %o0 ! so _sparc_trap knows what to do
- st %g1, [%sp + C_STACK + 0x14] ! no need to save %g0, always zero
- or %g0, %l0, %o1
- std %g2, [%sp + C_STACK + 0x18]
- or %g0, %l1, %o2
- std %g4, [%sp + C_STACK + 0x20]
- add %sp, C_STACK, %o3
- std %g6, [%sp + C_STACK + 0x28]
- std %i0, [%sp + C_STACK + 0x30]
- std %i2, [%sp + C_STACK + 0x38]
- std %i4, [%sp + C_STACK + 0x40]
- nop /* SHould trap here */
- std %i6, [%sp + C_STACK + 0x48]
-
- ldd [%sp + C_STACK], %l0
- ldd [%sp + C_STACK + 0x8], %l2
- wr %l3, 0, %y
- ld [%sp + C_STACK + 0x14], %g1
- ldd [%sp + C_STACK + 0x18], %g2
- ldd [%sp + C_STACK + 0x20], %g4
- ldd [%sp + C_STACK + 0x28], %g6
- ldd [%sp + C_STACK + 0x30], %i0
- ldd [%sp + C_STACK + 0x38], %i2
- ldd [%sp + C_STACK + 0x40], %i4
- wr %l0, 0, %psr ! disable traps again
- ldd [%sp + C_STACK + 0x48], %i6
- sethi %hi( C_LABEL(current) ), %l6
- ld [%l6 + %lo( C_LABEL(current) )], %l6
- ld [%l6 + THREAD_W_SAVED], %l7
- cmp %l7, 0x0
- bl,a 1f
- wr %g0, 0x0, %wim
- /* Should trap here */
+ mov %l7, %o0
+ add %sp, STACKFRAME_SZ, %o1
+ call C_LABEL(handler_irq)
+ nop
-1:
- or %g0, %g6, %l3
- or %g0, %l6, %g6
- st %g0, [%g6 + THREAD_W_SAVED]
- restore %g0, %g0, %g0
- restore %g0, %g0, %g0
- restore %g0, 0x1, %l1
- rd %psr, %l0
- sll %l1, %l0, %l1
- wr %l1, 0x0, %wim
- and %l0, 0x1f, %l0
- st %l0, [%g6 + THREAD_WIM]
- nop
- save %g0, %g0, %g0
- ldd [%sp], %l0 ! load number one
- ldd [%sp + 0x8], %l2
- ldd [%sp + 0x10], %l4
- ldd [%sp + 0x18], %l6
- ldd [%sp + 0x20], %i0
- ldd [%sp + 0x28], %i2
- ldd [%sp + 0x30], %i4
- ldd [%sp + 0x38], %i6
- save %g0, %g0, %g0
- ldd [%sp], %l0 ! load number two
- ldd [%sp + 0x8], %l2
- ldd [%sp + 0x10], %l4
- ldd [%sp + 0x18], %l6
- ldd [%sp + 0x20], %i0
- ldd [%sp + 0x28], %i2
- ldd [%sp + 0x30], %i4
- ldd [%sp + 0x38], %i6
- save %g0, %g0, %g0 ! re-enter trap window
- wr %l0, 0x0, %psr ! restore condition codes
- or %g0, %l3, %g6 ! restore scratch register
- jmp %l1
- rett %l2
+ sethi %hi(C_LABEL(intr_count)), %l4
+ ld [%l4 + %lo(C_LABEL(intr_count))], %l5
+ subcc %l5, 0x1, %l5
+ st %l5, [%l4 + %lo(C_LABEL(intr_count))]
-fill_stack_ok:
- rd %psr, %l0
- sll %l1, %l0, %l1
- wr %l1, 0x0, %wim
- sethi %hi( C_LABEL(current) ), %l2
- ld [%l2 + %lo( C_LABEL(current) )], %l2
- and %l0, 0x1f, %l0
- st %l0, [%l2 + THREAD_WIM]
- save %g0, %g0, %g0
- ldd [%sp], %l0 ! only one load necessary
- ldd [%sp + 0x8], %l2
- ldd [%sp + 0x10], %l4
- ldd [%sp + 0x18], %l6
- ldd [%sp + 0x20], %i0
- ldd [%sp + 0x28], %i2
- ldd [%sp + 0x30], %i4
- ldd [%sp + 0x38], %i6
- save %g0, %g0, %g0
- save %g0, %g0, %g0 ! save into trap window
- wr %l0, 0x0, %psr ! local number 0 here has cond codes
- nop
- jmp %l1
- rett %l2
+ RESTORE_ALL
/* This routine handles illegal isntructions and privileged
* instruction attempts from user code.
*/
- .align 4
- .globl bad_instruction
+ .align 4
+ .globl bad_instruction
bad_instruction:
- ENTER_TRAP(bad_instruction)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
- cmp %l3, 0x2
- bne 1f
call C_LABEL(do_illegal_instruction)
- mov %l0, %o3
- b 2f
- ld [%sp + C_STACK + PT_G1], %g1
+ mov %l0, %o3
+ RESTORE_ALL
-1:
+ .align 4
+ .globl priv_instruction
+priv_instruction:
+ SAVE_ALL
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
+ mov %l1, %o1
+ mov %l2, %o2
call C_LABEL(do_priv_instruction)
- mov %l0, %o3
- ld [%sp + C_STACK + PT_G1], %g1
-2:
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ mov %l0, %o3
+ RESTORE_ALL
/* This routine handles unaligned data accesses.
*/
- .align 4
- .globl mna_handler
+ .align 4
+ .globl mna_handler
mna_handler:
- ENTER_TRAP(mna_handler)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(do_memaccess_unaligned)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles floating point disabled traps.
- */
- .align 4
- .globl fpd_trap_handler
+ /* This routine handles floating point disabled traps. */
+ .align 4
+ .globl fpd_trap_handler
fpd_trap_handler:
- ENTER_TRAP(fpd_trap_handler)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(do_fpd_trap)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles Floating Point Exceptions.
- */
- .align 4
- .globl fpe_trap_handler
+ /* This routine handles Floating Point Exceptions. */
+ .align 4
+ .globl fpe_trap_handler
fpe_trap_handler:
- ENTER_TRAP(fpe_trap_handler)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(do_fpe_trap)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles Tag Overflow Exceptions.
- */
- .align 4
- .globl do_tag_overflow
+ /* This routine handles Tag Overflow Exceptions. */
+ .align 4
+ .globl do_tag_overflow
do_tag_overflow:
- ENTER_TRAP(do_tag_overflow)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(handle_tag_overflow)
- mov %l0, %o3
+ mov %l0, %o3
+ RESTORE_ALL
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
-
- /* This routine handles Watchpoint Exceptions.
- */
- .align 4
- .globl do_watchpoint
+ /* This routine handles Watchpoint Exceptions. */
+ .align 4
+ .globl do_watchpoint
do_watchpoint:
- ENTER_TRAP(do_watchpoint)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(handle_watchpoint)
- mov %l0, %o3
+ mov %l0, %o3
+ RESTORE_ALL
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
-
- /* This routine handles Register Access Exceptions.
- */
- .align 4
- .globl do_reg_access
+ /* This routine handles Register Access Exceptions. */
+ .align 4
+ .globl do_reg_access
do_reg_access:
- ENTER_TRAP(do_reg_access)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
- mov %l1, %o1
- mov %l2, %o2
- call C_LABEL(handle_reg_access)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ WRITE_PAUSE
- /* This routine handles Instruction Access Errors.
- */
- .align 4
- .globl do_iacc_error
-do_iacc_error:
- ENTER_TRAP(do_iacc_error)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
- call C_LABEL(handle_iacc_error)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ call C_LABEL(handle_reg_access)
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles Co-Processor Disabled Exceptions.
- */
- .align 4
- .globl do_cp_disabled
+ /* This routine handles Co-Processor Disabled Exceptions. */
+ .align 4
+ .globl do_cp_disabled
do_cp_disabled:
- ENTER_TRAP(do_cp_disabled)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(handle_cp_disabled)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles Unimplemented FLUSH Exceptions.
- */
- .align 4
- .globl do_bad_flush
+ /* This routine handles Unimplemented FLUSH Exceptions. */
+ .align 4
+ .globl do_bad_flush
do_bad_flush:
- ENTER_TRAP(do_bad_flush)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ WRITE_PAUSE
+
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
call C_LABEL(handle_bad_flush)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles Co-Processor Exceptions.
- */
- .align 4
- .globl do_cp_exception
+ /* This routine handles Co-Processor Exceptions. */
+ .align 4
+ .globl do_cp_exception
do_cp_exception:
- ENTER_TRAP(do_cp_exception)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
- mov %l1, %o1
- mov %l2, %o2
- call C_LABEL(handle_cp_exception)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ WRITE_PAUSE
- /* This routine handles Data Access Errors.
- */
- .align 4
- .globl do_dacc_error
-do_dacc_error:
- ENTER_TRAP(do_dacc_error)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
- call C_LABEL(handle_dacc_error)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ call C_LABEL(handle_cp_exception)
+ mov %l0, %o3
+ RESTORE_ALL
- /* This routine handles Hardware Divide By Zero Exceptions.
- */
- .align 4
- .globl do_hw_divzero
+ /* This routine handles Hardware Divide By Zero Exceptions. */
+ .align 4
+ .globl do_hw_divzero
do_hw_divzero:
- ENTER_TRAP(do_hw_divzero)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
+ SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
- mov %l1, %o1
- mov %l2, %o2
- call C_LABEL(handle_hw_divzero)
- mov %l0, %o3
-
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ WRITE_PAUSE
- /* This routine handles Data Store Errors.
- */
- .align 4
- .globl do_dstore_err
-do_dstore_err:
- ENTER_TRAP(do_dstore_err)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
+ add %sp, STACKFRAME_SZ, %o0
mov %l1, %o1
mov %l2, %o2
- call C_LABEL(handle_dstore_error)
- mov %l0, %o3
+ call C_LABEL(handle_hw_divzero)
+ mov %l0, %o3
+ RESTORE_ALL
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ .align 4
+ .globl do_flush_windows
+do_flush_windows:
+ SAVE_ALL
- /* This routine handles Data Access MMU-Miss Exceptions.
- */
- .align 4
- .globl do_dacc_mmu_miss
-do_dacc_mmu_miss:
- ENTER_TRAP(do_dacc_mmu_miss)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
- mov %l1, %o1
- mov %l2, %o2
- call C_LABEL(handle_dacc_mmu_miss)
- mov %l0, %o3
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ call C_LABEL(flush_user_windows)
+ nop
- /* This routine handles Instruction Access MMU-Miss Exceptions.
- */
- .align 4
- .globl do_iacc_mmu_miss
-do_iacc_mmu_miss:
- ENTER_TRAP(do_iacc_mmu_miss)
- st %g1, [%sp + C_STACK + PT_G1]
- rd %y, %l4
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- wr %l0, PSR_ET, %psr ! re-enable traps
- add %sp, C_STACK, %o0
- mov %l1, %o1
- mov %l2, %o2
- call C_LABEL(handle_iacc_mmu_miss)
- mov %l0, %o3
+ /* Advance over the trap instruction. */
+ ld [%sp + STACKFRAME_SZ + PT_NPC], %l1
+ add %l1, 0x4, %l2
+ st %l1, [%sp + STACKFRAME_SZ + PT_PC]
+ st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- b ret_trap_entry
- wr %l4, 0, %y
+ RESTORE_ALL
/* The getcc software trap. The user wants the condition codes from
* the %psr in register %g1.
*/
- .align 4
- .globl getcc_trap_handler
+ .align 4
+ .globl getcc_trap_handler
getcc_trap_handler:
- /* Shit, one more instruction and I could do this inline. */
- sll %l0, 0x8, %g1
- srl %g1, 28, %g1
- jmp %l2
- rett %l2+0x4
+ srl %l0, 20, %g1 ! give user
+ and %g1, 0xf, %g1 ! only ICC bits in %psr
+ jmp %l2 ! advance over trap instruction
+ rett %l2 + 0x4 ! like this...
/* The setcc software trap. The user has condition codes in %g1
* that it would like placed in the %psr. Be careful not to flip
- * any unintention bits!
+ * any unintentional bits!
*/
- .align 4
- .globl setcc_trap_handler
+ .align 4
+ .globl setcc_trap_handler
setcc_trap_handler:
sll %g1, 0x14, %l4
set PSR_ICC, %l5
- andn %l0, %l5, %l0
- or %l4, %l0, %l4
- wr %l4, 0x0, %psr
- WRITE_PAUSE
- jmp %l2
- rett %l2+0x4
+ andn %l0, %l5, %l0 ! clear ICC bits in current %psr
+ and %l4, %l5, %l4 ! clear non-ICC bits in user value
+ or %l4, %l0, %l4 ! or them in... mix mix mix
+ wr %l4, 0x0, %psr ! set new %psr
+ WRITE_PAUSE ! TI scumbags...
- .align 4
-NMI_STRING: .asciz "NMI received, dazed and confused, halting...\n"
+ jmp %l2 ! advance over trap instruction
+ rett %l2 + 0x4 ! like this...
- .align 4
- .globl linux_trap_nmi
- .globl C_LABEL(interrupt_enable)
+ .align 4
+ .globl linux_trap_nmi
linux_trap_nmi:
- sethi %hi(C_LABEL(prom_vector_p)), %o0
- ld [%o0 + %lo(C_LABEL(prom_vector_p))], %o0
- ld [%o0 + 0x74], %o0
- /* Ugh, until I figure out how to clear the IRQ line ;( */
- call %o0
- nop
-
- .align 4
- .globl sparc_text_fault
-sparc_text_fault:
- ENTER_TRAP(sparc_text_fault)
- st %g1, [%sp + C_STACK + PT_G1]
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- rd %y, %l4
- sethi %hi(AC_SYNC_ERR), %o0
- lda [%o0] ASI_CONTROL, %o1
- add %o0, 0x4, %o0 ! go to sync vaddr
- lda [%o0] ASI_CONTROL, %o2
- andcc %o1, SUN4C_SYNC_NOMEM, %g0
- bz,a normal_page_fault
- wr %l0, PSR_ET, %psr ! re-enable traps
-
- add %o0, 0x4, %o0 ! go to async error register
- lda [%o0] ASI_CONTROL, %o3
- add %o0, 0x4, %o0 ! go to async vaddr
- subcc %o4, %o2, %g0
- be,a is_sync_fault ! not an async fault
- wr %l0, PSR_ET, %psr
-
- /* crap, an asynchronous error has occurred */
+ SAVE_ALL
+ /* Ugh, we need to clear the IRQ line. This is now
+ * a very sun4c specific trap hanler...
+ */
sethi %hi(C_LABEL(interrupt_enable)), %l5
- ldub [%l5 + %lo(C_LABEL(interrupt_enable))], %o0
- andn %o0, INTS_ENAB, %o0
- stb %o0, [%l5 + %lo(C_LABEL(interrupt_enable))]
- wr %l0, PSR_ET, %psr ! enable traps
- call C_LABEL(sparc_txtmem_error) ! call high level c-code
- or %g0, FAULT_ASYNC, %o0
+ ld [%l5 + %lo(C_LABEL(interrupt_enable))], %l5
+ ldub [%l5], %l6
+ andn %l6, INTS_ENAB, %l6
+ stb %l6, [%l5]
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldub [%l5 + %lo(C_LABEL(interrupt_enable))], %o1
- or %o1, INTS_ENAB, %o1
- stb %o1, [%l5 + %lo(C_LABEL(interrupt_enable))]
- b ret_trap_entry
- wr %l4, 0, %y
-
-is_sync_fault:
- call C_LABEL(sparc_txtmem_error) ! call high level c-code
- or %g0, FAULT_SYNC, %o0
-
- ld [%sp + C_STACK + PT_G1], %g1
- ld [%sp + C_STACK + PT_G2], %g2
- ld [%sp + C_STACK + PT_G4], %g4
- ld [%sp + C_STACK + PT_G6], %g6
- wr %l4, 0x0, %y
- b ret_trap_entry
- wr %l0, 0x0, %psr
-
-normal_page_fault:
- std %l0, [%sp + C_STACK + PT_PSR]
- or %g0, %l3, %o0
- st %l2, [%sp + C_STACK + PT_NPC]
- st %l4, [%sp + C_STACK + PT_Y]
- or %g0, %l1, %o3
- std %i0, [%sp + C_STACK + PT_I0]
- std %i2, [%sp + C_STACK + PT_I2]
- or %g0, %l0, %o4
- std %i4, [%sp + C_STACK + PT_I4]
- std %i6, [%sp + C_STACK + PT_I6]
- call C_LABEL(sparc_text_access_fault)
- add %sp, C_STACK, %o5
-
- ldd [%sp + C_STACK + PT_PSR], %l0
- ldd [%sp + C_STACK + PT_NPC], %l2
- wr %l3, 0x0, %y
- ld [%sp + C_STACK + PT_G1], %g1
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldd [%sp + C_STACK + PT_I0], %i0
- ldd [%sp + C_STACK + PT_I2], %i2
- ldd [%sp + C_STACK + PT_I4], %i4
- ldd [%sp + C_STACK + PT_I6], %i6
-
- b ret_trap_entry
- wr %l0, 0x0, %psr
+ /* Now it is safe to re-enable traps without recursion. */
+ or %l0, PSR_PIL, %l0
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
- .align 4
- .globl sparc_data_fault
-sparc_data_fault:
- ENTER_TRAP(sparc_data_fault)
- st %g1, [%sp + C_STACK + PT_G1]
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- rd %y, %l4
+ /* Now call the c-code with the pt_regs frame ptr and the
+ * memory error registers as arguments. The ordering chosen
+ * here is due to unlatching semantics.
+ */
sethi %hi(AC_SYNC_ERR), %o0
- lda [%o0] ASI_CONTROL, %o1
- add %o0, 0x4, %o0 ! go to sync vaddr
- lda [%o0] ASI_CONTROL, %o2
- andcc %o1, SUN4C_SYNC_NOMEM, %g0
- bz,a normal_data_page_fault
+ add %o0, 0x4, %o0
+ lda [%o0] ASI_CONTROL, %o2 ! sync vaddr
+ sub %o0, 0x4, %o0
+ lda [%o0] ASI_CONTROL, %o1 ! sync error
+ add %o0, 0xc, %o0
+ lda [%o0] ASI_CONTROL, %o4 ! async vaddr
+ sub %o0, 0x4, %o0
+ lda [%o0] ASI_CONTROL, %o3 ! async error
+ call C_LABEL(sparc_lvl15_nmi)
+ add %sp, STACKFRAME_SZ, %o0
+
+ RESTORE_ALL
+
+ .align 4
+ .globl sparc_fault
+sparc_fault:
+ SAVE_ALL
+ rd %tbr, %o1
wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
- add %o0, 0x4, %o0 ! go to async error register
- lda [%o0] ASI_CONTROL, %o3
- add %o0, 0x4, %o0 ! go to async vaddr
- subcc %o4, %o2, %g0
- be,a is_data_sync_fault ! not an async fault
- wr %l0, PSR_ET, %psr
+ call C_LABEL(do_sparc_fault)
+ add %sp, STACKFRAME_SZ, %o0
+ RESTORE_ALL
+
+ /* SunOS uses syscall zero as the 'indirect syscall' it looks
+ * like indir_syscall(scall_num, arg0, arg1, arg2...); etc.
+ * This is complete brain damage.
+ */
+ .globl C_LABEL(sunos_indir)
+C_LABEL(sunos_indir):
+ ld [%sp + STACKFRAME_SZ + PT_I0], %g1
+ cmp %g1, NR_SYSCALLS
+ bleu,a 1f
+ sll %g1, 0x2, %g1
- /* crap, an asynchronous error has occurred */
- sethi %hi(C_LABEL(interrupt_enable)), %l5
- ldub [%l5 + %lo(C_LABEL(interrupt_enable))], %o0
- andn %o0, INTS_ENAB, %o0
- stb %o0, [%l5 + %lo(C_LABEL(interrupt_enable))]
- wr %l0, PSR_ET, %psr
- call C_LABEL(sparc_datamem_error) ! call high level c-code
- or %g0, FAULT_ASYNC, %o0
+ set C_LABEL(sunos_nosys), %l6
+ b 2f
+ nop
- ld [%sp + C_STACK + PT_G1], %g1
- wr %l0, 0x0, %psr
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldub [%l5 + %lo(C_LABEL(interrupt_enable))], %o1
- or %o1, INTS_ENAB, %o1
- stb %o1, [%l5 + %lo(C_LABEL(interrupt_enable))]
- b ret_trap_entry
- wr %l4, 0, %y
-
-is_data_sync_fault:
- call C_LABEL(sparc_datamem_error) ! call high level c-code
- or %g0, FAULT_SYNC, %o0
-
- ld [%sp + C_STACK + PT_G1], %g1
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- wr %l4, 0x0, %y
- b ret_trap_entry
- wr %l0, 0x0, %psr
+1:
+ set C_LABEL(sunos_sys_table), %l7
+ ld [%l7 + %g1], %l6
-normal_data_page_fault:
- std %l0, [%sp + C_STACK + PT_PSR] ! store %psr and pc
- or %g0, %l3, %o0
- st %l2, [%sp + C_STACK + PT_NPC] ! store npc
- st %l4, [%sp + C_STACK + PT_Y] ! store %y
- or %g0, %l1, %o3
-
- /* The globals have already been placed on the stack */
- std %i0, [%sp + C_STACK + PT_I0] ! store ins
- std %i2, [%sp + C_STACK + PT_I2]
- or %g0, %l0, %o4
- std %i4, [%sp + C_STACK + PT_I4]
- std %i6, [%sp + C_STACK + PT_I6]
- call C_LABEL(sparc_data_access_fault)
- add %sp, C_STACK, %o5
-
- ldd [%sp + C_STACK + PT_PSR], %l0
- ldd [%sp + C_STACK + PT_NPC], %l2
- wr %l3, 0x0, %y
- ld [%sp + C_STACK + PT_G1], %g1
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldd [%sp + C_STACK + PT_I0], %i0
- ldd [%sp + C_STACK + PT_I2], %i2
- ldd [%sp + C_STACK + PT_I4], %i4
- ldd [%sp + C_STACK + PT_I6], %i6
+2:
+ ld [%sp + STACKFRAME_SZ + PT_I1], %o0
+ ld [%sp + STACKFRAME_SZ + PT_I2], %o1
+ ld [%sp + STACKFRAME_SZ + PT_I3], %o2
+ ld [%sp + STACKFRAME_SZ + PT_I4], %o3
+ call %l6
+ ld [%sp + STACKFRAME_SZ + PT_I5], %o4
+
+ b scall_store_args /* so stupid... */
+ nop
+
+ .align 4
+ .globl C_LABEL(sys_execve)
+C_LABEL(sys_execve):
+ call C_LABEL(sparc_execve)
+ add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg
+
+ b scall_store_args
+ nop
+
+ .align 4
+ .globl C_LABEL(sys_pipe)
+C_LABEL(sys_pipe):
+ call C_LABEL(sparc_pipe)
+ add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg
- b ret_trap_entry
- wr %l0, 0x0, %psr
+ b C_LABEL(ret_sys_call)
+ nop
+ .align 4
+ .globl C_LABEL(sys_sigreturn)
+C_LABEL(sys_sigreturn):
+ call C_LABEL(do_sigreturn)
+ add %sp, STACKFRAME_SZ, %o0
+
+ /* We don't want to muck with user registers like a
+ * normal syscall, just return.
+ */
+ RESTORE_ALL
+
+ /* Now that we have a real sys_clone, sys_fork() is
+ * implemented in terms of it. Our _real_ implementation
+ * of SunOS vfork() will use sys_clone() instead.
+ */
+ .align 4
+ .globl C_LABEL(sys_fork), C_LABEL(sys_vfork)
+C_LABEL(sys_vfork):
+C_LABEL(sys_fork):
+ /* Save the kernel state as of now. */
+ FLUSH_ALL_KERNEL_WINDOWS;
+ STORE_WINDOW(sp)
+ LOAD_CURRENT(g6)
+ rd %psr, %g4
+ rd %wim, %g5
+ std %g4, [%g6 + THREAD_KPSR]
+ std %sp, [%g6 + THREAD_KSP]
+
+ mov SIGCHLD, %o0 ! arg0: clone flags
+ mov %fp, %o1 ! arg1: usp
+ call C_LABEL(do_fork)
+ add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
- .align 4
- .globl C_LABEL(srmmu_text_fault)
-C_LABEL(srmmu_text_fault):
- ENTER_TRAP(srmmu_text_fault)
- st %g1, [%sp + C_STACK + PT_G1]
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- rd %y, %l4
- set 0x300, %o0
- lda [%o0] ASI_M_MMUREGS, %o1 ! fault status
- set 0x400, %o0
- lda [%o0] ASI_M_MMUREGS, %o2 ! fault address
- wr %l0, PSR_ET, %psr ! traps back on
- WRITE_PAUSE
- std %l0, [%sp + C_STACK + PT_PSR]
- or %g0, %l3, %o0
- st %l2, [%sp + C_STACK + PT_NPC]
- st %l4, [%sp + C_STACK + PT_Y]
- or %g0, %l1, %o3
- std %i0, [%sp + C_STACK + PT_I0]
- std %i2, [%sp + C_STACK + PT_I2]
- or %g0, %l0, %o4
- std %i4, [%sp + C_STACK + PT_I4]
- std %i6, [%sp + C_STACK + PT_I6]
- call C_LABEL(srmmu_text_access_fault)
- add %sp, C_STACK, %o5
-
- ldd [%sp + C_STACK + PT_PSR], %l0
- ldd [%sp + C_STACK + PT_NPC], %l2
- wr %l3, 0x0, %y
- ld [%sp + C_STACK + PT_G1], %g1
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldd [%sp + C_STACK + PT_I0], %i0
- ldd [%sp + C_STACK + PT_I2], %i2
- ldd [%sp + C_STACK + PT_I4], %i4
- ldd [%sp + C_STACK + PT_I6], %i6
+ b scall_store_args
+ nop
+
+ /* Whee, kernel threads! */
+ .globl C_LABEL(sys_clone)
+C_LABEL(sys_clone):
+ /* Save the kernel state as of now. */
+ FLUSH_ALL_KERNEL_WINDOWS;
+ STORE_WINDOW(sp)
+ LOAD_CURRENT(g6)
+ rd %psr, %g4
+ rd %wim, %g5
+ std %g4, [%g6 + THREAD_KPSR]
+ std %sp, [%g6 + THREAD_KSP]
- b ret_trap_entry
- wr %l0, 0x0, %psr
+ ldd [%sp + STACKFRAME_SZ + PT_I0], %o0 ! arg0,1: flags,usp
+ cmp %o1, 0x0 ! Is new_usp NULL?
+ be,a 1f
+ mov %fp, %o1 ! yes, use current usp
+1:
+ call C_LABEL(do_fork)
+ add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
- .align 4
- .globl C_LABEL(srmmu_data_fault)
-C_LABEL(srmmu_data_fault):
- ENTER_TRAP(srmmu_data_fault)
- st %g1, [%sp + C_STACK + PT_G1]
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- rd %y, %l4
-
- set AC_M_SFSR, %o0
- lda [%o0] ASI_M_MMUREGS, %o1 ! fault status
- set AC_M_SFAR, %o0
- lda [%o0] ASI_M_MMUREGS, %o2 ! fault address
- set AC_M_AFSR, %o0
- lda [%o0] ASI_M_MMUREGS, %o3
- set AC_M_AFAR, %o0
- lda [%o0] ASI_M_MMUREGS, %o4
- wr %l0, PSR_ET, %psr ! traps back on
- WRITE_PAUSE
- std %l0, [%sp + C_STACK + PT_PSR]
- or %g0, %l3, %o0
- st %l2, [%sp + C_STACK + PT_NPC]
- st %l4, [%sp + C_STACK + PT_Y]
- std %i0, [%sp + C_STACK + PT_I0]
- std %i2, [%sp + C_STACK + PT_I2]
- std %i4, [%sp + C_STACK + PT_I4]
- std %i6, [%sp + C_STACK + PT_I6]
- call C_LABEL(srmmu_data_access_fault)
- add %sp, C_STACK, %o5
-
- ldd [%sp + C_STACK + PT_PSR], %l0
- ldd [%sp + C_STACK + PT_NPC], %l2
- wr %l3, 0x0, %y
- ld [%sp + C_STACK + PT_G1], %g1
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldd [%sp + C_STACK + PT_I0], %i0
- ldd [%sp + C_STACK + PT_I2], %i2
- ldd [%sp + C_STACK + PT_I4], %i4
- ldd [%sp + C_STACK + PT_I6], %i6
+ b scall_store_args
+ nop
- b ret_trap_entry
- wr %l0, 0x0, %psr
+#if 0 /* XXX Much later... XXX */
+ /* Whee, vfork... */
+ .globl C_LABEL(sys_vfork)
+C_LABEL(sys_vfork):
+ /* Save the kernel state as of now. */
+ FLUSH_ALL_KERNEL_WINDOWS;
+ STORE_WINDOW(sp)
+ LOAD_CURRENT(g6)
+ rd %psr, %g4
+ rd %wim, %g5
+ std %g4, [%g6 + THREAD_KPSR]
+ std %sp, [%g6 + THREAD_KSP]
-/* Normal Linux system calls enter here... */
-/* Trying to make this as generic and simple as possible. */
+ set (0x2100 | SIGCHLD), %o0 ! CLONE_VFORK,CLONE_VM,SIGCHLD
+ mov %fp, %o1 ! use current usp
+1:
+ call C_LABEL(do_fork)
+ add %sp, STACKFRAME_SZ, %o2 ! arg2: pt_regs ptr
- .align 4
- .globl linux_sparc_syscall
+ b scall_store_args
+ nop
+#endif
+
+ /* All system calls enter here... */
+ .align 4
+ .globl linux_sparc_syscall
linux_sparc_syscall:
/* Don't dork with %l7, it holds the pointer to the
- * system call vector table. ENTER_TRAP does not
+ * system call vector table. SAVE_ALL does not
* modify its value.
*/
- ENTER_TRAP(linux_sparc_syscall)
+ rd %wim, %l3
+ SAVE_ALL
- /* setup pt_regs stack frame, leave ints off...
- * First save all but the current window onto the stack.
- * This means nwindows-2 saves and nwindows-2 restores.
- */
- andn %l0, PSR_PIL, %l5
- wr %l5, 0xf00, %psr
- wr %l5, 0xf20, %psr ! no ints, traps on
+ wr %l0, PSR_ET, %psr /* Turn on traps + interrupts */
WRITE_PAUSE
-
- .globl nop7
- /* Flush windows */
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
-nop7: save %sp, -C_STACK, %sp
- restore
- restore
- restore
- restore
- restore
- restore
-
- rd %psr, %l6
- and %l6, PSR_CWP, %l6 ! only care about CWP
- andn %l0, PSR_CWP, %l0
- or %l0, %l6, %l0 ! %l0 is now the new %psr
-
- std %l0, [%sp + C_STACK + PT_PSR] ! save it away
- rd %y, %l3
- std %l2, [%sp + C_STACK + PT_NPC]
-
- /* Put %wim in %g0 slot, a hack. This way we ensure that %wim
- * sits right behind the current window in %psr, which is what
- * we want.
- */
- rd %wim, %l4
- st %l4, [%sp + C_STACK + PT_G0]
- st %g1, [%sp + C_STACK + PT_G1]
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- std %i0, [%sp + C_STACK + PT_I0]
- std %i2, [%sp + C_STACK + PT_I2]
- std %i4, [%sp + C_STACK + PT_I4]
- std %i6, [%sp + C_STACK + PT_I6]
-
- wr %l0, PSR_ET, %psr /* Turn on traps + interrupts */
- WRITE_PAUSE
-
- cmp %i0, NR_SYSCALLS
- bgu,a C_LABEL(ret_sys_call)
- or %g0, -1, %i0
-
- cmp %i0, 0x2 ! fork? Same number for all OSs
- bne not_fork
- nop
- call C_LABEL(sys_fork) ! yep, load pt_regs into first arg
- add %sp, C_STACK, %o0
- b C_LABEL(ret_sys_call)
- nop
-not_fork:
- /* Remember, trap table entry loaded syscall table ptr in %l7 */
- sll %i0, 0x2, %o0
- add %l7, %o0, %l7
- ld [%l7], %o5 ! load up ptr to syscall handler
-
- mov %i1, %o0 ! load up arguments
- mov %i2, %o1
- mov %i3, %o2
- mov %i4, %o3
- jmpl %o5, %o7 ! Make syscall
- mov %i5, %o4
-
- .globl C_LABEL(ret_sys_call) /* exported for copy_process() */
-C_LABEL(ret_sys_call): /* Child of a fork returns here */
- /* dump the pt_regs back into their rightful places */
- ldd [%sp + C_STACK + PT_PSR], %l0
- ldd [%sp + C_STACK + PT_NPC], %l2
- wr %l3, 0x0, %y
-
- ld [%sp + C_STACK + PT_G1], %g1
- ldd [%sp + C_STACK + PT_G2], %g2
- ldd [%sp + C_STACK + PT_G4], %g4
- ldd [%sp + C_STACK + PT_G6], %g6
- ldd [%sp + C_STACK + PT_I0], %i0
- ldd [%sp + C_STACK + PT_I2], %i2
- ldd [%sp + C_STACK + PT_I4], %i4
- ldd [%sp + C_STACK + PT_I6], %i6
- /* %i6 is our frame pointer, the restore done by the rett
- * instruction will automatically put us back on the users
- * stack.
- * Advance the pc and npc past the trap instruction, the copy_process()
- * code for fork() depends on this being done right before trap return.
- */
- or %l2, 0x0, %l5
+#if 0 /* Trace all system calls... */
+ add %sp, STACKFRAME_SZ, %o0
+ call C_LABEL(syscall_trace_entry)
+ nop
+#endif
- or %l5, 0x0, %l1 /* pc = npc */
- add %l5, 0x4, %l2 /* npc= npc+4 */
+ /* SAVE_ALL may have blown away %g1, reload it. */
+ ld [%sp + STACKFRAME_SZ + PT_G1], %g1
+ cmp %g1, NR_SYSCALLS
+ bleu,a 1f
+ sll %g1, 0x2, %g1
- wr %l0, 0x0, %psr
- WRITE_PAUSE
-
- /* Fall through to ret_trap_entry */
-
-/* Return from trap code. I realized that I was duplicating a lot
- * of logic in the various trap handlers. Traps are off upon entry.
- */
-
-ret_trap_entry:
- and %l0, 0x1f, %l5
- sethi %hi(lnx_winmask), %l6
- or %l6, %lo(lnx_winmask), %l6
- ldub [%l6 + %l5], %l5
- andcc %l0, PSR_PS, %g0
- bnz ret_trap_kernel
- rd %wim, %l4
-
- sethi %hi(C_LABEL(current)), %l6
- ld [%l6 + %lo(C_LABEL(current))], %l6
- ld [%l6 + THREAD_W_SAVED], %l7
- subcc %g0, %l7, %g0
- bz,a ret_trap_user
- nop
-
- wr %g0, 0, %wim
- or %g0, %g6, %l3
- or %g0, %l6, %g6
- st %g0, [%g6 + THREAD_W_SAVED]
- restore
- restore %g0, 1, %l1
- rd %psr, %l0
- sll %l1, %l0, %l1
- wr %l1, 0x0, %wim
- and %l0, 0x1f, %l0
- st %l0, [%g6 + THREAD_WIM]
- nop
- save %g0, %g0, %g0
- add %g6, THREAD_REG_WINDOW, %g6
- ldd [%g6], %l0
- ldd [%g6 + 0x8], %l2
- ldd [%g6 + 0x10], %l4
- ldd [%g6 + 0x18], %l6
- ldd [%g6 + 0x20], %i0
- ldd [%g6 + 0x28], %i2
- ldd [%g6 + 0x30], %i4
- ldd [%g6 + 0x38], %i6
-
- save %g0, %g0, %g0
- wr %l0, 0x0, %psr
- or %g0, %l3, %g6
- jmp %l1
- rett %l2
-
-ret_trap_kernel:
- andcc %l4, %l5, %g0
- bnz 1f
- wr %l0, 0x0, %psr ! reset condition codes
- nop
- jmp %l1
- rett %l2
+ set C_LABEL(sys_ni_syscall), %l6
+ b 2f
+ nop
1:
- wr %g0, 0x0, %wim
- WRITE_PAUSE
- restore
- restore %g0, 0x1, %l1
- rd %psr, %l0
- and %l0, 0x1f, %l0
- sll %l1, %l0, %l1
- wr %l1, 0x0, %wim
- sethi %hi(C_LABEL(current)), %l1
- ld [%l1 + %lo(C_LABEL(current))], %l1
- st %l0, [%l1 + THREAD_WIM]
- save %g0, %g0, %g0
- ldd [%sp], %l0
- ldd [%sp + 0x8], %l2
- ldd [%sp + 0x10], %l4
- ldd [%sp + 0x18], %l6
- ldd [%sp + 0x20], %i0
- ldd [%sp + 0x28], %i2
- ldd [%sp + 0x30], %i4
- ldd [%sp + 0x38], %i6
+ /* Syscall table ptr is in %l7. */
+ ld [%l7 + %g1], %l6 ! load up ptr to syscall handler
- save %g0, %g0, %g0
- jmp %l1
- rett %l2
+ /* Pt_regs is your friend... Make the syscall... */
+2:
+ ldd [%sp + STACKFRAME_SZ + PT_I0], %o0
+ ldd [%sp + STACKFRAME_SZ + PT_I2], %o2
+ ldd [%sp + STACKFRAME_SZ + PT_I4], %o4
+ call %l6
+ nop
+
+scall_store_args:
+ st %o0, [%sp + STACKFRAME_SZ + PT_I0]
+
+ .globl C_LABEL(ret_sys_call)
+C_LABEL(ret_sys_call):
+ ld [%sp + STACKFRAME_SZ + PT_I0], %o0
+ set PSR_C, %l6
+ cmp %o0, -ELIBSCN
+ bgeu 1f
+ ld [%sp + STACKFRAME_SZ + PT_PSR], %l5
-ret_trap_user:
- andcc %l4, %l5, %g0
- bnz 1f
- wr %l0, 0x0, %psr
- nop
- jmp %l1
- rett %l2
+ /* System call success, clear Carry condition code. */
+ andn %l5, %l6, %l5
+ b 2f
+ st %l5, [%sp + STACKFRAME_SZ + PT_PSR]
1:
- wr %g0, 0x0, %wim
- wr %l0, 0x0, %psr
- WRITE_PAUSE
- restore
- restore %g0, 0x1, %l1
- rd %psr, %l0
- sll %l1, %l0, %l1
- wr %l1, 0x0, %wim
- sethi %hi(C_LABEL(current)), %l1
- ld [%l1 + %lo(C_LABEL(current))], %l1
- and %l0, 0x1f, %l0
- st %l0, [%l1 + THREAD_WIM]
- save %g0, %g0, %g0
- ldd [%sp], %l0
- ldd [%sp + 0x8], %l2
- ldd [%sp + 0x10], %l4
- ldd [%sp + 0x18], %l6
- ldd [%sp + 0x20], %i0
- ldd [%sp + 0x28], %i2
- ldd [%sp + 0x30], %i4
- ldd [%sp + 0x38], %i6
- save %g0, %g0, %g0
- jmp %l1
- rett %l2
-
-/* Context switch code. I don't feel like playing around with
- * inline gcc-assembly to do this right, so here it is. The new
- * process's task_struct ptr is passed in %o0.
- *
- * This is still work in progress.
- * ONLY MAKE PROM CALLS FOR DIAGNOSTICS WHEN TRAPS ARE ON!!!!!
- *
- * First successful task switch 05/13/95 21:52:37
- *
- */
- .align 4
- .globl C_LABEL(sparc_switch_to)
-C_LABEL(sparc_switch_to):
- or %g0, %o0, %l5
- sethi %hi(C_LABEL(current)), %l6
- ld [%l6 + %lo(C_LABEL(current))], %l6
- rd %psr, %l0
-
- or %g0, %l0, %l4
- andn %l0, PSR_PIL, %l0 /* turn off IRQ level bits leave PSR_ET on */
-
- wr %l0, 0xf00, %psr /* NO interrupts */
- WRITE_PAUSE
-
- /* Save state of old process */
- .globl rnop7
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
- save %sp, -C_STACK, %sp
-rnop7: save %sp, -C_STACK, %sp
- restore
- restore
- restore
- restore
- restore
- restore
-
- rd %psr, %l3
- and %l3, PSR_CWP, %l3 ! only care about CWP bits now
- andn %l0, PSR_CWP, %l0 ! integrate with old %psr
- or %l3, %l0, %l0
-
- st %l0, [%sp + C_STACK + PT_PSR] ! save new %psr
- /* ??? We backtrack the PC two instructions due to retl's semantics ??? */
- /*sub %o7, 0x8, %o7 */
- st %o7, [%sp + C_STACK + PT_PC] ! save return PC
- add %o7, 0x4, %l3
- st %l3, [%sp + C_STACK + PT_NPC] ! and NPC
-
- rd %y, %l3
- st %l3, [%sp + C_STACK + PT_Y] ! save %y
-
- /* Save the %wim into %g0 slot, ensures that it sits behind CWP */
- rd %wim, %l3
- st %l3, [%sp + C_STACK + PT_G0] ! save new %wim
- st %g1, [%sp + C_STACK + PT_G1]
- std %g2, [%sp + C_STACK + PT_G2]
- std %g4, [%sp + C_STACK + PT_G4]
- std %g6, [%sp + C_STACK + PT_G6]
- std %i0, [%sp + C_STACK + PT_I0]
- std %i2, [%sp + C_STACK + PT_I2]
- std %i4, [%sp + C_STACK + PT_I4]
- std %i6, [%sp + C_STACK + PT_I6]
-
- wr %l0, (0xf20), %psr ! no traps, no intrs
- WRITE_PAUSE
-
- /* TRAPS ARE OFF, NO PROM CALLS WHATSOEVER FOR DEBUGGING!!! */
- /* SO what we do is we put an imperical constant in %g2 and
- * a 'counter' in %g1 which we increment after every instruction
- * so we can figure out where the thing prom panics. Then at the
- * prom prompt we print out the saved registers. To drop into the
- * prom and look at the registers just execute 7 saves since that
- * will induce a window trap before the last one and traps are off,
- * thus a watchdog reset will occur.
- */
-
- /* Grrr, this is hairy... be careful, again NO PROM CALLS YET! */
- /* Load up the new 'current' */
- sethi %hi(C_LABEL(current)), %g1
- st %l5, [%g1 + %lo(C_LABEL(current))]
-
- /* Load up new processes stack, we always switch onto the kernel stack */
- /* Be CAREFUL, use globals for temporaries, because after we change the
- * %psr the window could change and you will most likely be accessing
- * different outs, ins, and locals than you origionally were.
- */
- or %g0, %l5, %g6
- ld [%l5 + THREAD_KSP], %g3
-
- /* New procs %psr */
- ld [%g3 + C_STACK + PT_PSR], %g4
- wr %g4, 0xf00, %psr /* No ints, no traps */
- WRITE_PAUSE
-
- /* We could be in a different window NOW. Assume nothing about the
- * current set of in, out and local registers.
+ /* System call failure, set Carry condition code.
+ * Also, get abs(errno) to return to the process.
*/
+ sub %g0, %o0, %o0
+ st %o0, [%sp + STACKFRAME_SZ + PT_I0]
+ or %l5, %l6, %l5
+ st %l5, [%sp + STACKFRAME_SZ + PT_PSR]
- /* New procs %wim */
- ld [%g3 + C_STACK + PT_G0], %l4 /* %wim is here */
- st %l4, [%g6 + THREAD_WIM] /* Update tss */
- wr %l4, 0x0, %wim /* Use it */
- WRITE_PAUSE
-
- /* Finally, load the stack */
- or %g0, %g3, %sp
-
- /* We are now sane, we have a good stack and our state is reflected
- * properly in 'current'. Let it rip.
- */
- /* Remember, you can't increase PIL and turn on traps at the
- * same time.
+ /* %i6 is our frame pointer, the restore done by the rett
+ * instruction will automatically put us back on the users
+ * stack. Advance the pc and npc past the trap instruction.
*/
- wr %g4, 0xf00, %psr /* Traps on, no interrupts. */
- wr %g4, 0xf20, %psr
- WRITE_PAUSE
-
- sethi %hi(C_LABEL(current)), %o0
- ld [%o0 + %lo(C_LABEL(current))], %o0
- ld [%o0 + THREAD_PC], %o7 /* Setup return address */
-
- /* cross fingers */
- retl
- nop
-
-/* The following two things point to window management tables. The first
- * one is used to quickly look up how many user windows there are from
- * trap-land. The second is used in a trap handler to determine if a rett
- * instruction will land us smack inside the invalid window that possibly
- * the trap was called to fix-up.
- */
-
-/* For now these are static tables geared for a 7 window sparc.
- * But in head.S after we calculate this table based upon the
- * nwindows value. This table is big enough for a 16 window sparc.
- */
-
+2:
+ ld [%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
+ add %l1, 0x4, %l2 /* npc = npc+4 */
+ st %l1, [%sp + STACKFRAME_SZ + PT_PC]
+ st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
+
+#if 0 /* Trace all system calls... */
+ add %sp, STACKFRAME_SZ, %o0
+ call C_LABEL(syscall_trace_exit)
+ nop
+#endif
+
+ RESTORE_ALL
+
+ .globl C_LABEL(flush_user_windows)
+C_LABEL(flush_user_windows):
+ LOAD_CURRENT(g2)
+ ld [%g2 + THREAD_UMASK], %g1
+ orcc %g0, %g1, %g0
+ be 3f
+ clr %g3
+1:
+ _SV
+ LOAD_CURRENT(g2)
+ ld [%g2 + THREAD_UMASK], %g1
+ orcc %g0, %g1, %g0
+ bne 1b
+ add %g3, 1, %g3
+2:
+ subcc %g3, 1, %g3
+ bne 2b
+ _RS
+3:
+ jmp %o7 + 0x8
+ nop
- .data
- .align 4
- .globl lnx_winmask
-lnx_winmask:
- .byte 2, 4, 8, 16, 32, 64, 1, 0
- .byte 0, 0, 0, 0, 0, 0, 0, 0
-
- .align 4
- .globl C_LABEL(sys_call_table)
-C_LABEL(sys_call_table):
- .long C_LABEL(sys_setup) /* 0 */
- .long C_LABEL(sys_exit)
- .long C_LABEL(sys_fork)
- .long C_LABEL(sys_read)
- .long C_LABEL(sys_write)
- .long C_LABEL(sys_open) /* 5 */
- .long C_LABEL(sys_close)
- .long C_LABEL(sys_waitpid)
- .long C_LABEL(sys_creat)
- .long C_LABEL(sys_link)
- .long C_LABEL(sys_unlink) /* 10 */
- .long C_LABEL(sys_execve)
- .long C_LABEL(sys_chdir)
- .long C_LABEL(sys_time)
- .long C_LABEL(sys_mknod)
- .long C_LABEL(sys_chmod) /* 15 */
- .long C_LABEL(sys_chown)
- .long C_LABEL(sys_break)
- .long C_LABEL(sys_stat)
- .long C_LABEL(sys_lseek)
- .long C_LABEL(sys_getpid) /* 20 */
- .long C_LABEL(sys_mount)
- .long C_LABEL(sys_umount)
- .long C_LABEL(sys_setuid)
- .long C_LABEL(sys_getuid)
- .long C_LABEL(sys_stime) /* 25 */
- .long C_LABEL(sys_ni_syscall) /* this will be sys_ptrace() */
- .long C_LABEL(sys_alarm)
- .long C_LABEL(sys_fstat)
- .long C_LABEL(sys_pause)
- .long C_LABEL(sys_utime) /* 30 */
- .long C_LABEL(sys_stty)
- .long C_LABEL(sys_gtty)
- .long C_LABEL(sys_access)
- .long C_LABEL(sys_nice)
- .long C_LABEL(sys_ftime) /* 35 */
- .long C_LABEL(sys_sync)
- .long C_LABEL(sys_kill)
- .long C_LABEL(sys_rename)
- .long C_LABEL(sys_mkdir)
- .long C_LABEL(sys_rmdir) /* 40 */
- .long C_LABEL(sys_dup)
- .long C_LABEL(sys_pipe)
- .long C_LABEL(sys_times)
- .long C_LABEL(sys_prof)
- .long C_LABEL(sys_brk) /* 45 */
- .long C_LABEL(sys_setgid)
- .long C_LABEL(sys_getgid)
- .long C_LABEL(sys_signal)
- .long C_LABEL(sys_geteuid)
- .long C_LABEL(sys_getegid) /* 50 */
- .long C_LABEL(sys_acct)
- .long C_LABEL(sys_phys)
- .long C_LABEL(sys_lock)
- .long C_LABEL(sys_ioctl)
- .long C_LABEL(sys_fcntl) /* 55 */
- .long C_LABEL(sys_mpx)
- .long C_LABEL(sys_setpgid)
- .long C_LABEL(sys_ulimit)
- .long C_LABEL(sys_olduname)
- .long C_LABEL(sys_umask) /* 60 */
- .long C_LABEL(sys_chroot)
- .long C_LABEL(sys_ustat)
- .long C_LABEL(sys_dup2)
- .long C_LABEL(sys_getppid)
- .long C_LABEL(sys_getpgrp) /* 65 */
- .long C_LABEL(sys_setsid)
- .long C_LABEL(sys_sigaction)
- .long C_LABEL(sys_sgetmask)
- .long C_LABEL(sys_ssetmask)
- .long C_LABEL(sys_setreuid) /* 70 */
- .long C_LABEL(sys_setregid)
- .long C_LABEL(sys_sigsuspend)
- .long C_LABEL(sys_sigpending)
- .long C_LABEL(sys_sethostname)
- .long C_LABEL(sys_setrlimit) /* 75 */
- .long C_LABEL(sys_getrlimit)
- .long C_LABEL(sys_getrusage)
- .long C_LABEL(sys_gettimeofday)
- .long C_LABEL(sys_settimeofday)
- .long C_LABEL(sys_getgroups) /* 80 */
- .long C_LABEL(sys_setgroups)
- .long C_LABEL(sys_select)
- .long C_LABEL(sys_symlink)
- .long C_LABEL(sys_lstat)
- .long C_LABEL(sys_readlink) /* 85 */
- .long C_LABEL(sys_uselib)
- .long C_LABEL(sys_swapon)
- .long C_LABEL(sys_reboot)
- .long C_LABEL(sys_readdir)
- .long C_LABEL(sys_mmap) /* 90 */
- .long C_LABEL(sys_munmap)
- .long C_LABEL(sys_truncate)
- .long C_LABEL(sys_ftruncate)
- .long C_LABEL(sys_fchmod)
- .long C_LABEL(sys_fchown) /* 95 */
- .long C_LABEL(sys_getpriority)
- .long C_LABEL(sys_setpriority)
- .long C_LABEL(sys_profil)
- .long C_LABEL(sys_statfs)
- .long C_LABEL(sys_fstatfs) /* 100 */
- .long C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_socketcall)
- .long C_LABEL(sys_syslog)
- .long C_LABEL(sys_setitimer)
- .long C_LABEL(sys_getitimer) /* 105 */
- .long C_LABEL(sys_newstat)
- .long C_LABEL(sys_newlstat)
- .long C_LABEL(sys_newfstat)
- .long C_LABEL(sys_uname)
- .long C_LABEL(sys_ni_syscall) /* 110 */
- .long C_LABEL(sys_vhangup)
- .long C_LABEL(sys_idle)
- .long C_LABEL(sys_ni_syscall) /* was vm86, meaningless on Sparc */
- .long C_LABEL(sys_wait4)
- .long C_LABEL(sys_swapoff) /* 115 */
- .long C_LABEL(sys_sysinfo)
- .long C_LABEL(sys_ipc)
- .long C_LABEL(sys_fsync)
- .long C_LABEL(sys_sigreturn)
- .long C_LABEL(sys_ni_syscall) /* 120 */
- .long C_LABEL(sys_setdomainname)
- .long C_LABEL(sys_newuname)
- .long C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_adjtimex)
- .long C_LABEL(sys_mprotect) /* 125 */
- .long C_LABEL(sys_sigprocmask)
- .long C_LABEL(sys_create_module)
- .long C_LABEL(sys_init_module)
- .long C_LABEL(sys_delete_module)
- .long C_LABEL(sys_get_kernel_syms) /* 130 */
- .long C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_getpgid)
- .long C_LABEL(sys_fchdir)
- .long C_LABEL(sys_bdflush)
- .long C_LABEL(sys_sysfs) /* 135 */
- .long C_LABEL(sys_personality)
- .long C_LABEL(sys_ni_syscall) /* for afs_syscall */
- .long C_LABEL(sys_setfsuid)
- .long C_LABEL(sys_setfsgid)
- .long C_LABEL(sys_llseek) /* 140 */
- .long C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 150 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 160 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 170 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 180 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 190 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 200 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 210 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 220 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 230 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 240 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
-
- /* 250 */
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall), C_LABEL(sys_ni_syscall)
- .long C_LABEL(sys_ni_syscall) /* 255 */
- .align 4
+/* End of entry.S */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this