patch-1.3.4 linux/arch/sparc/kernel/entry.S
Next file: linux/arch/sparc/kernel/head.S
Previous file: linux/arch/sparc/kernel/c_mp.c
Back to the patch index
Back to the overall index
- Lines: 1881
- Date:
Sat Jun 17 11:36:33 1995
- Orig file:
v1.3.3/linux/arch/sparc/kernel/entry.S
- Orig date:
Mon Feb 20 08:59:51 1995
diff -u --recursive --new-file v1.3.3/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
@@ -5,18 +5,52 @@
* the trap table and how it works, this will show you how we get
* to these routines.
*
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
+
#include <asm/head.h>
#include <asm/asi.h>
+#include <asm/contregs.h>
#include <asm/psr.h>
#include <asm/cprefix.h>
#include <asm/vaddrs.h>
+#include <asm/memreg.h>
+#include <asm/page.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.
+ * without making the code look real ugly. Well, the macro looks ugly too
+ * but makes the trap entry code easier to understand.
*/
/* I really don't like synthetic instructions. So I avoid them like the
@@ -27,14 +61,13 @@
* 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.
- *
- * XXX must do some checking on the assumption that kernel stack is always ok
*/
/* I will document how this works real soon. TODO */
@@ -62,6 +95,8 @@
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 */ \
@@ -69,6 +104,8 @@
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. */ \
@@ -136,366 +173,193 @@
* 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 \
+#define ENTER_TRAP(label) \
rd %wim, %l4; \
or %g0, 0x1, %l5; \
sll %l5, %l0, %l5; \
- andcc %l0, 0x40, %g0; \
- bz 1f; \
+ andcc %l0, PSR_PS, %g0; \
+ bz CONCAT1(label, 1); \
andcc %l4, %l5, %g0; \
- bz,a 3f; \
+ bz,a CONCAT1(label, 3); \
sub %fp, 0xb0, %sp; \
TRAP_WIN_CLEAN \
- b 3f; \
+ b CONCAT1(label, 3); \
sub %fp, 0xb0, %sp; \
-1: sethi %hi( C_LABEL(current) ), %l6; \
+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 4f; \
+ ble,a CONCAT1(label, 4); \
sethi %hi( C_LABEL(nwindowsm1) ), %l4; \
sub %l5, %l3, %l3; \
- b 5f; \
+ b CONCAT1(label, 5); \
sub %l3, 0x1, %l5; \
-4: ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4; \
+CONCAT1(label, 4): \
+ ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4; \
sub %l4, %l3, %l4; \
add %l5, %l4, %l5; \
-5: st %l5, [%l6 + THREAD_UWINDOWS]; \
- bz,a 2f; \
- sethi %hi(TASK_SIZE-176), %l5; \
- TRAP_WIN_CLEAN; \
- sethi %hi( C_LABEL(current) ), %l6; \
- ld [%l6 + %lo( C_LABEL(current) )], %l6; \
- sethi %hi(TASK_SIZE-176), %l5; \
-2: or %l5, %lo(TASK_SIZE-176), %l5; \
- add %l6, %l5, %sp; \
-3: \
+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):
-#define ENTER_IRQ \
+/* What needs to be executed upon entry to an interrupt.
+ *
+ * See asm-sparc/cprefix.h to see how the CONCAT macros work.
+ */
+
+#define ENTER_IRQ(label) \
rd %wim, %l4; \
or %g0, 0x1, %l5; \
sll %l5, %l0, %l5; \
- andcc %l0, 0x40, %g0; \
- bz 1f; \
+ andcc %l0, PSR_PS, %g0; \
+ bz CONCAT1(label, 1); \
andcc %l4, %l5, %g0; \
+ bz,a CONCAT1(label, 0); \
sethi %hi( C_LABEL(eintstack) ), %l7; \
- or %l7, %lo( C_LABEL(eintstack) ), %l7; \
- bz 0f; \
- nop; \
TRAP_WIN_CLEAN \
sethi %hi( C_LABEL(eintstack) ), %l7; \
- or %l7, %lo( C_LABEL(eintstack) ), %l7; \
-0: subcc %fp, %l7, %g0; \
- bg,a 3f; \
+CONCAT1(label, 0): \
+ subcc %fp, %l7, %g0; \
+ bge,a CONCAT1(label, 3); \
sub %l7, 0xb0, %sp; \
- b 3f; \
+ b CONCAT1(label, 3); \
sub %fp, 0xb0, %sp; \
-1: sethi %hi( C_LABEL(current) ), %l6; \
+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 4f; \
+ ble,a CONCAT1(label, 4); \
sethi %hi( C_LABEL(nwindowsm1) ), %l4; \
sub %l5, %l7, %l7; \
- b 5f; \
+ b CONCAT1(label, 5); \
sub %l7, 0x1, %l5; \
-4: ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4; \
+CONCAT1(label, 4): \
+ ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4; \
sub %l4, %l7, %l4; \
add %l5, %l4, %l5; \
-5: st %l5, [%l6 + THREAD_UWINDOWS]; \
- bz,a 2f; \
+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; \
-2: \
+CONCAT1(label, 2): \
sub %l7, 0xb0, %sp; \
-3:
+CONCAT1(label, 3):
.text
.align 4
-/* Default trap handler */
- .globl my_trap_handler
-my_trap_handler:
-#if 1
- jmp %l1
- rett %l2
- nop
-#else
- rd %wim, %l4
- or %g0, 0x1, %l5
- sll %l5, %l0, %l5
- cmp %l4, %l5 ! are we in the invalid window?
-
- TRAP_WIN_CLEAN
+/* Bad trap handler */
+ .globl bad_trap_handler
+bad_trap_handler:
+ ENTER_TRAP(bad_trap_handler)
- nop
- or %g0, %l3, %o0
- call C_LABEL(do_hw_interrupt)
- or %g0, %g0, %o1
- wr %l0, 0x20, %psr ! re-enable traps and reset the condition codes
- nop
- nop
- nop ! click our heels three times, "no place like home"
- jmp %l1
- rett %l2
-#endif /* bogon */
+ or %g0, %l3, %o0
+ or %g0, %l0, %o1
+ call C_LABEL(do_hw_interrupt)
+ or %g0, %l1, %o2
+
+ jmp %l1
+ rett % l2
.align 4
.globl sparc_timer
sparc_timer:
- sethi %hi(TIMER_VADDR), %l4
- or %l4, %lo(TIMER_VADDR), %l4 ! read the limit register
- ld [%l4 + 0xc], %l4 ! to clear the interrupt
- rd %wim, %l4
- or %g0, 0x1, %l5
- sll %l5, %l0, %l5
- andcc %l0, 0x40, %g0
- bz st1
- sethi %hi( C_LABEL(eintstack) ), %l7
- andcc %l4, %l5, %g0
- bz st0
- or %l7, %lo( C_LABEL(eintstack) ), %l7
- TRAP_WIN_CLEAN
- sethi %hi( C_LABEL(eintstack) ), %l7
- or %l7, %lo( C_LABEL(eintstack) ), %l7
-st0: subcc %fp, %l7, %g0
- bg,a st3
- sub %l7, 0xb0, %sp
- b st3
- sub %fp, 0xb0, %sp
-st1: 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 st4
- sethi %hi( C_LABEL(nwindowsm1) ), %l4
- sub %l5, %l7, %l7
- b st5
- sub %l7, 0x1, %l5
-st4: ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
- sub %l4, %l7, %l4
- add %l5, %l4, %l5
-st5: st %l5, [%l6 + THREAD_UWINDOWS]
- sethi %hi( C_LABEL(eintstack) ), %l7
- bz,a st2
- or %l7, %lo( C_LABEL(eintstack) ), %l7
- TRAP_WIN_CLEAN
- sethi %hi( C_LABEL(eintstack) ), %l7
- or %l7, %lo( C_LABEL(eintstack) ), %l7
-st2: sub %l7, 0xb0, %sp
+ 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
-st3: std %g2, [%sp + 96 + 24]
+ std %g2, [%sp + C_STACK + PT_G2]
or %g0, %g1, %l7
rd %y, %l6
- std %g4, [%sp + 96 + 32]
+ std %g4, [%sp + C_STACK + PT_G4]
andn %l0, PSR_PIL, %l4
- sll %l3, 0x8, %l5
- std %g6, [%sp + 96 + 40]
- or %l5, %l4, %l4
-
- wr %l4, 0x0, %psr
+/* sll %l3, 0x8, %l5 */
+ std %g6, [%sp + C_STACK + PT_G6]
+/* or %l5, %l4, %l4 */
+
+ /* Magic, we can't increase PIL and set ET at the same
+ * time or the chip calls prom_panic().
+ */
+/* wr %l4, 0x0, %psr */
wr %l4, PSR_ET, %psr
- std %l0, [%sp + 96 + 0]
- std %l2, [%sp + 96 + 8]
- st %fp, [%sp + 96 + 16]
-
- or %g0, 14, %o0
- or %g0, %g0, %o1
- call C_LABEL(do_sparc_timer)
+ 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 + 96 + 24], %g2
- ldd [%sp + 96 + 32], %g4
- ldd [%sp + 96 + 40], %g6
- wr %l0, 0x0, %psr
- nop
- nop
- nop
+ ldd [%sp + C_STACK + PT_G2], %g2
+ ldd [%sp + C_STACK + PT_G4], %g4
+ ldd [%sp + C_STACK + PT_G6], %g6
- and %l0, 31, %l5
- sethi %hi(lnx_winmask), %l6
- or %l6, %lo(lnx_winmask), %l6
- ldub [%l6 + %l5], %l5
- andcc %l0, PSR_PS, %g0
- bnz 1f
- rd %wim, %l4
-
-1: andcc %l5, %l4, %g0
- bnz 2f
+ b ret_trap_entry
wr %l0, 0x0, %psr
- nop
- nop
- nop
-
- jmp %l1
- rett %l2
-2: wr %g0, 0x0, %wim
- nop
- nop
- nop
-
- restore
- restore %g0, 0x1, %l1
- rd %psr, %l0
- and %l0, 31, %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
-
- save %g0, %g0, %g0
-
- jmp %l1
- rett %l2
-
-
-/* For now all IRQ's not registered get sent here so I can see
- * what is poking the chip.
+/* 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 stray_irq_entry
-stray_irq_entry:
- rd %wim, %l4
- or %g0, 0x1, %l5
- sll %l5, %l0, %l5
- andcc %l0, 0x40, %g0
- bz tt1
- sethi %hi( C_LABEL(eintstack) ), %l7
- andcc %l4, %l5, %g0
- bz tt0
- or %l7, %lo( C_LABEL(eintstack) ), %l7
- TRAP_WIN_CLEAN
- sethi %hi( C_LABEL(eintstack) ), %l7
- or %l7, %lo( C_LABEL(eintstack) ), %l7
-tt0: subcc %fp, %l7, %g0
- bg,a tt3
- sub %l7, 0xb0, %sp
- b tt3
- sub %fp, 0xb0, %sp
-tt1: 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 tt4
- sethi %hi( C_LABEL(nwindowsm1) ), %l4
- sub %l5, %l7, %l7
- b tt5
- sub %l7, 0x1, %l5
-tt4: ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
- sub %l4, %l7, %l4
- add %l5, %l4, %l5
-tt5: st %l5, [%l6 + THREAD_UWINDOWS]
- sethi %hi( C_LABEL(eintstack) ), %l7
- bz,a tt2
- or %l7, %lo( C_LABEL(eintstack) ), %l7
- TRAP_WIN_CLEAN
- sethi %hi( C_LABEL(eintstack) ), %l7
- or %l7, %lo( C_LABEL(eintstack) ), %l7
-tt2: sub %l7, 0xb0, %sp
-
-tt3: std %g2, [%sp + 96 + 24]
+ .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 + 96 + 32]
+ std %g4, [%sp + C_STACK + PT_G4]
andn %l0, PSR_PIL, %l4
sll %l3, 0x8, %l5
- std %g6, [%sp + 96 + 40]
+ std %g6, [%sp + C_STACK + PT_G6]
or %l5, %l4, %l4
wr %l4, 0x0, %psr
wr %l4, PSR_ET, %psr
- std %l0, [%sp + 96 + 0]
- std %l2, [%sp + 96 + 8]
- st %fp, [%sp + 96 + 16]
+ std %l0, [%sp + C_STACK + PT_PSR]
+ std %l2, [%sp + C_STACK + PT_NPC]
or %g0, %l3, %o0
- or %g0, %g0, %o1
- call C_LABEL(unexpected_irq)
+ add %sp, C_STACK, %o1
+ call C_LABEL(handler_irq)
nop
or %g0, %l7, %g1
wr %l6, 0x0, %y
- ldd [%sp + 96 + 24], %g2
- ldd [%sp + 96 + 32], %g4
- ldd [%sp + 96 + 40], %g6
+ 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
- nop
- nop
- nop
-
- and %l0, 31, %l5
- sethi %hi(lnx_winmask), %l6
- or %l6, %lo(lnx_winmask), %l6
- ldub [%l6 + %l5], %l5
- andcc %l0, PSR_PS, %g0
- bnz 1f
- rd %wim, %l4
-
-1: andcc %l5, %l4, %g0
- bnz 2f
- wr %l0, 0x0, %psr
- nop
- nop
- nop
-
- jmp %l1
- rett %l2
-
-2: wr %g0, 0x0, %wim
- nop
- nop
- nop
-
- restore
- restore %g0, 0x1, %l1
- rd %psr, %l0
- and %l0, 31, %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
-
- save %g0, %g0, %g0
-
- jmp %l1
- rett %l2
-
/* This routine is optimized for kernel window fills. User fills take about two
@@ -503,14 +367,14 @@
*/
/* 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 spills are worse,
+ * 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, 0x40, %g0 ! see if this is a user window fill
+ andcc %l0, PSR_PS, %g0 ! see if this is a user window fill
bz,a spill_from_user
nop
@@ -535,10 +399,12 @@
sub %l5, %l3, %l3
b 2f
sub %l3, 0x1, %l5
-1: ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
+1:
+ ld [%l4 + %lo( C_LABEL(nwindowsm1) )], %l4
sub %l4, %l3, %l4
add %l5, %l4, %l5
-2: st %l5, [%l6 + THREAD_UWINDOWS]
+2:
+ st %l5, [%l6 + THREAD_UWINDOWS]
TRAP_WIN_CLEAN /* danger, danger... */
sethi %hi( C_LABEL(current) ), %l6
@@ -607,7 +473,8 @@
cmp %l7, -1
bne fill_bad_stack
andn %sp, 0xfff, %l7
-1: lda [%l7] ASI_PTE, %l7
+1:
+ lda [%l7] ASI_PTE, %l7
srl %l7, 0x1d, %l7
andn %l7, 0x2, %l7
cmp %l7, 0x4
@@ -624,7 +491,8 @@
cmp %l7, -1
bne fill_bad_stack
andn %sp, 0xfff, %l7
-1: lda [%l7] ASI_PTE, %l7
+1:
+ lda [%l7] ASI_PTE, %l7
srl %l7, 0x1d, %l7
andn %l7, 0x2, %l7
cmp %l7, 0x4
@@ -641,8 +509,8 @@
sll %l4, %l5, %l4
wr %l4, 0x0, %wim
ld [%l6 + THREAD_KSP], %sp ! set to kernel stack pointer
- wr %l0, 0x20, %psr ! turn off traps
- std %l0, [%sp + C_STACK] ! set up thread_frame on stack
+ 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
@@ -656,7 +524,7 @@
std %i0, [%sp + C_STACK + 0x30]
std %i2, [%sp + C_STACK + 0x38]
std %i4, [%sp + C_STACK + 0x40]
- call sparc_trap
+ nop /* SHould trap here */
std %i6, [%sp + C_STACK + 0x48]
ldd [%sp + C_STACK], %l0
@@ -677,9 +545,10 @@
cmp %l7, 0x0
bl,a 1f
wr %g0, 0x0, %wim
- b,a leave_trap
+ /* Should trap here */
-1: or %g0, %g6, %l3
+1:
+ or %g0, %g6, %l3
or %g0, %l6, %g6
st %g0, [%g6 + THREAD_W_SAVED]
restore %g0, %g0, %g0
@@ -739,46 +608,1120 @@
jmp %l1
rett %l2
+ /* This routine handles illegal isntructions and privileged
+ * instruction attempts from user code.
+ */
.align 4
- .globl trap_entry
-trap_entry:
- TRAP_WIN_CLEAN
- jmp %l1
- rett %l2
+ .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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %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
+
+1:
+ 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
+
+ /* This routine handles unaligned data accesses.
+ */
+ .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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %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
+
+ /* 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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %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
+
+ /* 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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %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
+
+ /* 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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %o0
+ mov %l1, %o1
+ mov %l2, %o2
+ call C_LABEL(handle_tag_overflow)
+ 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
+
+ /* 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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %o0
+ mov %l1, %o1
+ mov %l2, %o2
+ call C_LABEL(handle_watchpoint)
+ 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
+
+ /* 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]
+ 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
+
+ /* 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
+ 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
+
+ /* 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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %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
+
+ /* 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]
+ wr %l0, PSR_ET, %psr ! re-enable traps
+ add %sp, C_STACK, %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
+
+ /* 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]
+ 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
+
+ /* 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
+ 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
+
+ /* 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]
+ 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
+
+ /* 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
+ mov %l1, %o1
+ mov %l2, %o2
+ call C_LABEL(handle_dstore_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
+
+ /* 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
+
+ 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 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
+
+ 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
+
+ /* The getcc software trap. The user wants the condition codes from
+ * the %psr in register %g1.
+ */
+
+ .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
+
+ /* 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!
+ */
+
+ .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
+
+ .align 4
+NMI_STRING: .asciz "NMI received, dazed and confused, halting...\n"
.align 4
.globl linux_trap_nmi
+ .globl C_LABEL(interrupt_enable)
linux_trap_nmi:
- TRAP_WIN_CLEAN
+ 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 */
+ 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 [%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
+
+ .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
+ 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
+ wr %l0, PSR_ET, %psr
+
+ 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
+
+ /* 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
+
+ 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
+
+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
+
+ b ret_trap_entry
+ wr %l0, 0x0, %psr
+
+
+ .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 ret_trap_entry
+ wr %l0, 0x0, %psr
+
+ .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 ret_trap_entry
+ wr %l0, 0x0, %psr
+
+/* Normal Linux system calls enter here... */
+/* Trying to make this as generic and simple as possible. */
+
+ .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
+ * modify its value.
+ */
+ ENTER_TRAP(linux_sparc_syscall)
+
+ /* 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
+ 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
+
+ or %l5, 0x0, %l1 /* pc = npc */
+ add %l5, 0x4, %l2 /* npc= npc+4 */
+
+ 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
- .align 4
- .globl sparc_trap
-sparc_trap:
- TRAP_WIN_CLEAN
+ret_trap_kernel:
+ andcc %l4, %l5, %g0
+ bnz 1f
+ wr %l0, 0x0, %psr ! reset condition codes
+ nop
jmp %l1
rett %l2
- .align 4
- .globl leave_trap
-leave_trap:
+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
+
+ save %g0, %g0, %g0
+ jmp %l1
+ rett %l2
+
+ret_trap_user:
+ andcc %l4, %l5, %g0
+ bnz 1f
+ wr %l0, 0x0, %psr
+ nop
+ jmp %l1
+ rett %l2
+
+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.
+ */
+
+ /* 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.
+ */
+ 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.
-*/
+ * 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.
+ */
-/* For now these are static tables geared for a 7 window sparc. */
.data
.align 4
-lnx_winmask: .byte 2, 4, 8, 16, 32, 64, 128, 1 ! lnx_winmask[0..7]
-
+ .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)
@@ -918,10 +1861,90 @@
.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_sysfs) /* 135 */
.long C_LABEL(sys_personality)
- .long 0 /* for afs_syscall */
+ .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
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