1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
|
/*
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1994 - 2000, 2001 by Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2001 MIPS Technologies, Inc.
*/
#include <linux/config.h>
#include <linux/sys.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
#include <asm/current.h>
#include <asm/errno.h>
#include <asm/mipsregs.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/stackframe.h>
#include <asm/processor.h>
#include <asm/regdef.h>
#include <asm/fpregdef.h>
#include <asm/unistd.h>
#include <asm/isadep.h>
/* This duplicates the definition from <linux/sched.h> */
#define PT_TRACESYS 0x00000002 /* tracing system calls */
.text
.align 4
.set push
.set reorder
EXPORT(ret_from_fork)
move a0, v0 # prev
jal schedule_tail
lw t0, TASK_PTRACE($28) # syscall tracing enabled?
andi t0, PT_TRACESYS
bnez t0, tracesys_exit
j ret_from_sys_call
tracesys_exit: jal syscall_trace
b ret_from_sys_call
EXPORT(ret_from_irq)
EXPORT(ret_from_exception)
lw t0, PT_STATUS(sp) # returning to kernel mode?
andi t0, t0, KU_USER
bnez t0, ret_from_sys_call
j restore_all
reschedule: jal schedule
EXPORT(ret_from_sys_call)
.type ret_from_irq,@function
mfc0 t0, CP0_STATUS # need_resched and signals atomic test
ori t0, t0, 1
xori t0, t0, 1
mtc0 t0, CP0_STATUS
nop; nop; nop
lw v0, TASK_NEED_RESCHED($28)
lw v1, TASK_SIGPENDING($28)
bnez v0, reschedule
bnez v1, signal_return
restore_all: .set noat
RESTORE_ALL_AND_RET
.set at
/* Put this behind restore_all for the sake of the branch prediction. */
signal_return:
.type signal_return, @function
mfc0 t0, CP0_STATUS
ori t0, t0, 1
mtc0 t0, CP0_STATUS
move a0, zero
move a1, sp
jal do_signal
b restore_all
/*
* Common spurious interrupt handler.
*/
.text
.align 5
LEAF(spurious_interrupt)
/*
* Someone tried to fool us by sending an interrupt but we
* couldn't find a cause for it.
*/
lui t1,%hi(spurious_count)
.set reorder
lw t0,%lo(spurious_count)(t1)
.set noreorder
addiu t0,1
sw t0,%lo(spurious_count)(t1)
j ret_from_irq
END(spurious_interrupt)
/*
* Build a default exception handler for the exceptions that don't need
* special handlers. If you didn't know yet - I *like* playing games with
* the C preprocessor ...
*/
#define __BUILD_clear_none(exception)
#define __BUILD_clear_sti(exception) \
STI
#define __BUILD_clear_cli(exception) \
CLI
#define __BUILD_clear_fpe(exception) \
cfc1 a1,fcr31; \
li a2,~(0x3f<<12); \
and a2,a1; \
ctc1 a2,fcr31; \
STI
#define __BUILD_clear_ade(exception) \
.set reorder; \
MFC0 t0,CP0_BADVADDR; \
.set noreorder; \
REG_S t0,PT_BVADDR(sp); \
KMODE
#define __BUILD_silent(exception)
#define fmt "Got %s at %08lx.\n"
#define __BUILD_verbose(exception) \
la a1,8f; \
TEXT (#exception); \
REG_L a2,PT_EPC(sp); \
PRINT(fmt)
#define __BUILD_count(exception) \
.set reorder; \
lw t0,exception_count_##exception; \
.set noreorder; \
addiu t0, 1; \
sw t0,exception_count_##exception; \
.data; \
EXPORT(exception_count_##exception); \
.word 0; \
.previous;
#define BUILD_HANDLER(exception,handler,clear,verbose) \
.align 5; \
NESTED(handle_##exception, PT_SIZE, sp); \
.set noat; \
SAVE_ALL; \
__BUILD_clear_##clear(exception); \
.set at; \
__BUILD_##verbose(exception); \
jal do_##handler; \
move a0, sp; \
j ret_from_exception; \
nop; \
END(handle_##exception)
BUILD_HANDLER(adel,ade,ade,silent) /* #4 */
BUILD_HANDLER(ades,ade,ade,silent) /* #5 */
BUILD_HANDLER(ibe,ibe,cli,verbose) /* #6 */
BUILD_HANDLER(dbe,dbe,cli,silent) /* #7 */
BUILD_HANDLER(bp,bp,sti,silent) /* #9 */
BUILD_HANDLER(ri,ri,sti,silent) /* #10 */
BUILD_HANDLER(cpu,cpu,sti,silent) /* #11 */
BUILD_HANDLER(ov,ov,sti,silent) /* #12 */
BUILD_HANDLER(tr,tr,sti,silent) /* #13 */
BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */
BUILD_HANDLER(watch,watch,sti,verbose) /* #23 */
BUILD_HANDLER(reserved,reserved,sti,verbose) /* others */
.set pop
/*
* Table of syscalls
*/
.data
.align PTRLOG
EXPORT(sys_call_table)
#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
*/
EXPORT(sys_narg_table)
#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"
|