summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/entry.S
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-03-25 23:40:36 +0000
committer <ralf@linux-mips.org>1997-03-25 23:40:36 +0000
commit7206675c40394c78a90e74812bbdbf8cf3cca1be (patch)
tree251895cf5a0008e2b4ce438cb01ad4d55fb5b97b /arch/mips/kernel/entry.S
parentbeb116954b9b7f3bb56412b2494b562f02b864b1 (diff)
Import of Linux/MIPS 2.1.14.2
Diffstat (limited to 'arch/mips/kernel/entry.S')
-rw-r--r--arch/mips/kernel/entry.S180
1 files changed, 83 insertions, 97 deletions
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 6072afae2..515f9af13 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -18,8 +18,10 @@
#include <asm/asm.h>
#include <asm/errno.h>
+#include <asm/segment.h>
#include <asm/mipsregs.h>
#include <asm/mipsconfig.h>
+#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/stackframe.h>
#include <asm/processor.h>
@@ -39,115 +41,98 @@ flags = 20
errno = 24
exec_domain = 60
-#ifdef __SMP__
-#error "Fix this for SMP"
-#else
-#define current current_set
-#endif
-
/*
* Heia ... The %lo, %hi and %HI stuff is too strong for the ELF assembler
* and the ABI to cope with ...
*/
.text
.set noreorder
+ .set mips3
.align 4
handle_bottom_half:
lui s0,%hi(intr_count)
lw s1,%lo(intr_count)(s0)
mfc0 s3,CP0_STATUS # Enable IRQs
- addiu s2,s1,1
+ addiu s2,s1, 1
sw s2,%lo(intr_count)(s0)
- ori t0,s3,0x1f
+ ori t0,s3, 0x1f
xori t0,0x1e
+
jal do_bottom_half
- mtc0 t0,CP0_STATUS # delay slot
+ mtc0 t0,CP0_STATUS
+
mtc0 s3,CP0_STATUS # Restore old IRQ state
+
b 9f
- sw s1,%lo(intr_count)(s0) # delay slot
+ sw s1,%lo(intr_count)(s0)
+
+reschedule:
+ jal schedule
+ nop
-reschedule: jal schedule
- nop # delay slot
EXPORT(ret_from_sys_call)
lw t0,intr_count # bottom half
bnez t0,return
-
-9: lw t0,bh_mask # delay slot
+9:
+ lw t0,bh_mask
lw t1,bh_active # unused delay slot
and t0,t1
bnez t0,handle_bottom_half
+ lw t0,PT_STATUS(sp) # returning to kernel mode?
- lw t0,FR_STATUS(sp) # returning to kernel mode?
- andi t1,t0,0x10
+ andi t1,t0, 0x10
beqz t1,return # -> yes
+ mfc0 t0,CP0_STATUS
- mfc0 t0,CP0_STATUS # delay slot
lw t1,need_resched
ori t0,0x1f # enable irqs
xori t0,0x1e
bnez t1,reschedule
- mtc0 t0,CP0_STATUS # delay slot
+ mtc0 t0,CP0_STATUS
- lw s0,current
+ lw s0,current_set
lw t0,task
lw a0,blocked(s0)
+
beq s0,t0,return # task[0] cannot have signals
- # save blocked in a0 for
- # signal handling
- lw t0,signal(s0) # delay slot
+ lw t0,signal(s0) # save blocked in a0 for signals
+
nor t1,zero,a0
and t1,t0,t1
beqz t1,return
- nop
+ nop
jal do_signal
- move a1,sp # delay slot
+ move a1,sp
.set noat
EXPORT(return)
RESTORE_ALL
- ERET
+ eret
.set at
/*
- * Beware: timer_interrupt, interrupt, fast_interrupt and bad_interrupt
- * have unusual calling conventions to speedup the mess.
+ * Beware: interrupt, fast_interrupt and bad_interrupt have unusual
+ * calling conventions to speedup the mess.
*
* a0 - interrupt number
* s2 - destroyed
* return values:
* v0 - return routine
- *
- * The timer interrupt is handled specially to insure that the jiffies
- * variable is updated at all times. Specifically, the timer interrupt is
- * just like the complete handlers except that it is invoked with interrupts
- * disabled and should never re-enable them. If other interrupts were
- * allowed to be processed while the timer interrupt is active, then the
- * other interrupts would have to avoid using the jiffies variable for delay
- * and interval timing operations to avoid hanging the system.
*/
.text
.set at
.align 5
-NESTED(timer_interrupt, FR_SIZE, sp)
- move s2,ra
- jal do_IRQ
- move a1,sp # delay slot
- .set reorder
- la v0,ret_from_sys_call
- jr s2
- .set noreorder
- END(timer_interrupt)
-
- .align 5
-NESTED(interrupt, FR_SIZE, sp)
+NESTED(interrupt, PT_SIZE, sp)
move s2,ra
mfc0 t0,CP0_STATUS # enable IRQs
ori t0,0x1f
xori t0,0x1e
mtc0 t0,CP0_STATUS
+
jal do_IRQ
- move a1,sp # delay slot
+ move a1,sp
+
mfc0 t0,CP0_STATUS # disable IRQs
ori t0,1
xori t0,1
@@ -159,10 +144,12 @@ NESTED(interrupt, FR_SIZE, sp)
END(interrupt)
.align 5
-NESTED(fast_interrupt, FR_SIZE, sp)
- .set reorder
+NESTED(fast_interrupt, PT_SIZE, sp)
move s2,ra
jal do_fast_IRQ
+ nop
+
+ .set reorder
la v0,return
jr s2
.set noreorder
@@ -172,12 +159,11 @@ NESTED(fast_interrupt, FR_SIZE, sp)
* Don't return & unblock the pic
*/
LEAF(bad_interrupt)
- .set reorder
lw t0,%lo(intr_count)(s3)
subu t0,1
- .set noreorder
+
j return
- sw t0,%lo(intr_count)(s3) # delay slot
+ sw t0,%lo(intr_count)(s3)
END(bad_interrupt)
.text
@@ -191,8 +177,9 @@ LEAF(spurious_interrupt)
lw t0,%lo(spurious_count)(t1)
la v0,return
addiu t0,1
+
jr ra
- sw t0,%lo(spurious_count)(t1)
+ sw t0,%lo(spurious_count)(t1)
END(spurious_interrupt)
/*
@@ -200,41 +187,28 @@ LEAF(spurious_interrupt)
* special handlers. If you didn't know yet - I *like* playing games with
* the C preprocessor ...
*/
-#define __BUILD_clear_none(exception) \
- REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */
-#define __BUILD_clear_sys(exception) \
- REG_S v0,FR_ORIG_REG2(sp); \
- REG_S a3,FR_ORIG_REG7(sp);
+#define __BUILD_clear_none(exception)
#define __BUILD_clear_fpe(exception) \
- REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */ \
cfc1 a1,fcr31; \
li a2,~(0x3f<<12); \
and a2,a1; \
ctc1 a2,fcr31;
-#define __BUILD_clear_watch(exception) \
- REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */ \
- mtc0 zero,CP0_WATCHLO; \
- mtc0 zero,CP0_WATCHHI
#define __BUILD_clear_ade(exception) \
- REG_S sp,FR_ORIG_REG2(sp); /* sp < 0 */ \
MFC0 t0,CP0_BADVADDR; \
- REG_S t0,FR_BADVADDR(sp);
+ REG_S t0,PT_BVADDR(sp);
#define __BUILD_silent(exception)
-#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2)
-#define fmt "Got %s at %08x.\n"
-#endif
-#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4)
+
#define fmt "Got %s at %016Lx.\n"
-#endif
+
#define __BUILD_verbose(exception) \
la a1,8f; \
TEXT (#exception); \
- REG_L a2,FR_EPC(sp); \
+ REG_L a2,PT_EPC(sp); \
PRINT(fmt)
#define __BUILD_count(exception) \
.set reorder; \
lw t0,exception_count_##exception; \
- addiu t0,1; \
+ addiu t0, 1; \
sw t0,exception_count_##exception; \
.set noreorder; \
.data; \
@@ -244,18 +218,19 @@ EXPORT(exception_count_##exception); \
#define BUILD_HANDLER(exception,handler,clear,verbose) \
.text; \
.align 5; \
- NESTED(handle_##exception, FR_SIZE, sp); \
+ NESTED(handle_##exception, PT_SIZE, sp); \
.set noat; \
SAVE_ALL; \
__BUILD_clear_##clear(exception); \
STI; \
.set at; \
__BUILD_##verbose(exception); \
- REG_S sp,FR_ORIG_REG2(sp); /* not a sys call */ \
+ li t0,-1; /* not a sys call */ \
+ REG_S t0,PT_OR2(sp); \
jal do_##handler; \
- move a0,sp; /* delay slot */ \
+ move a0,sp; \
j ret_from_sys_call; \
- nop; /* delay slot */ \
+ nop; \
END(handle_##exception)
BUILD_HANDLER(adel,ade,ade,silent) /* #4 */
@@ -270,7 +245,7 @@ EXPORT(exception_count_##exception); \
BUILD_HANDLER(tr,tr,none,silent) /* #13 */
BUILD_HANDLER(vcei,vcei,none,verbose) /* #14 */
BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */
- BUILD_HANDLER(watch,watch,watch,verbose) /* #23 */
+ BUILD_HANDLER(watch,watch,none,verbose) /* #23 */
BUILD_HANDLER(vced,vced,none,verbose) /* #31 */
BUILD_HANDLER(reserved,reserved,none,verbose) /* others */
@@ -295,32 +270,43 @@ EXPORT(IRQ_vectors)
.data
.align PTRLOG
EXPORT(sys_call_table)
- /*
- * Reserved space for all the SVR4, SVR, BSD43 and POSIX
- * flavoured syscalls.
- */
- .space (__NR_Linux)*PTRSIZE
-
- /*
- * Linux flavoured syscalls.
- */
#define SYS(call, narg) PTR call
+
+ /* Reserved space for all SVR4 syscalls. */
+ .space (1000)*PTRSIZE
+
+#ifdef CONFIG_BINFMT_IRIX
+ /* 32bit IRIX5 system calls. */
+#include "irix5sys.h"
+#else
+ .space (1000)*PTRSIZE /* No IRIX syscalls */
+#endif
+
+ /* Reserved space for all the BSD43 and POSIX syscalls. */
+ .space (2000)*PTRSIZE
+
+ /* Linux flavoured syscalls. */
#include "syscalls.h"
/*
* Number of arguments of each syscall
- * FIXME: This table contains huge empty areas wasting memory.
*/
EXPORT(sys_narg_table)
- /*
- * Reserved space for all the SVR4, SVR, BSD43 and POSIX
- * flavoured syscalls.
- */
- .space (__NR_Linux)
-
- /*
- * Linux flavoured syscalls.
- */
#undef SYS
#define SYS(call, narg) .byte narg
+
+ /* Reserved space for all SVR4 flavoured syscalls. */
+ .space (1000)
+
+#ifdef CONFIG_BINFMT_IRIX
+ /* 32bit IRIX5 system calls. */
+#include "irix5sys.h"
+#else
+ .space (1000) /* No IRIX syscalls */
+#endif
+
+ /* Reserved space for all the BSD43 and POSIX syscalls. */
+ .space (2000)
+
+ /* Linux flavoured syscalls. */
#include "syscalls.h"