patch-2.4.8 linux/arch/cris/kernel/entry.S
Next file: linux/arch/cris/kernel/entryoffsets.c
Previous file: linux/arch/cris/kernel/Makefile
Back to the patch index
Back to the overall index
- Lines: 288
- Date:
Thu Jul 26 15:10:06 2001
- Orig file:
v2.4.7/linux/arch/cris/kernel/entry.S
- Orig date:
Wed Jul 25 17:10:17 2001
diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.27 2001/05/29 11:25:27 markusl Exp $
+/* $Id: entry.S,v 1.31 2001/07/25 16:07:42 bjornw Exp $
*
* linux/arch/cris/entry.S
*
@@ -7,6 +7,36 @@
* Authors: Bjorn Wesen (bjornw@axis.com)
*
* $Log: entry.S,v $
+ * Revision 1.31 2001/07/25 16:07:42 bjornw
+ * softirq_active/mask -> softirq_pending only
+ *
+ * Revision 1.30 2001/07/05 01:03:32 hp
+ * - include asm/errno.h to get ENOSYS.
+ * - Use ENOSYS, not local constant LENOSYS; tweak comments.
+ * - Explain why .include, not #include is used.
+ * - Make oops-register-dump if watchdog bits and it's not expected.
+ * - Don't jsr, use jump _hard_reset_now, and skip spurious nop.
+ * - Use correct section attribute for section .rodata.
+ * - Adjust sys_ni_syscall fill number.
+ *
+ * Revision 1.29 2001/06/25 14:07:00 hp
+ * Fix review comment.
+ * * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of
+ * magic numbers. Add comment that -traditional must not be used.
+ * * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation.
+ * Correct and update comment.
+ * * Makefile (.S.o): Don't use -traditional. Add comment why the
+ * toplevel rule can't be used (now that there's a reason).
+ *
+ * Revision 1.28 2001/06/21 02:00:40 hp
+ * * entry.S: Include asm/unistd.h.
+ * (_sys_call_table): Use section .rodata, not .data.
+ * (_kernel_thread): Move from...
+ * * process.c: ... here.
+ * * entryoffsets.c (VAL): Break out from...
+ * (OF): Use VAL.
+ * (LCLONE_VM): New asmified value from CLONE_VM.
+ *
* Revision 1.27 2001/05/29 11:25:27 markusl
* In case of "spurious_interrupt", do hard_reset instead of hanging system in a loop...
*
@@ -130,7 +160,9 @@
#include <linux/config.h>
#include <linux/linkage.h>
#include <linux/sys.h>
+#include <asm/unistd.h>
#include <asm/sv_addr_ag.h>
+#include <asm/errno.h>
;; functions exported from this file
@@ -151,11 +183,9 @@
.globl _sys_call_table
- ;; syscall error codes
-
-LENOSYS = 38
-
- ;; Get offsets into various structs.
+ ;; Get values and offsets into various structs. The file isn't
+ ;; suitable for consumption by the preprocessor, so don't use
+ ;; #include.
.include "entryoffsets.s"
;; process bits for ptrace. FIXME: Should be in a header file.
@@ -227,7 +257,7 @@
push r10 ; push orig_r10
clear.d [sp=sp-4] ; frametype == 0, normal stackframe
- movs.w -LENOSYS,r0
+ movs.w -ENOSYS,r0
move.d r0,[sp+LR10] ; put the default return value in r10 in the frame
;; check if this process is syscall-traced
@@ -271,9 +301,7 @@
;; check if any bottom halves need service
- move.d _irq_stat,r10
- move.d [r10+],r0 ; softirq_active
- and.d [r10],r0 ; softirq_mask
+ test.d [_irq_stat] ; softirq_pending
bne handle_softirq
nop
@@ -320,8 +348,8 @@
tracesys:
;; this first invocation of syscall_trace _requires_ that
- ;; LR10 in the frame contains -LENOSYS (as is set in the beginning
- ;; of system_call
+ ;; LR10 in the frame contains -ENOSYS (as is set in the beginning
+ ;; of system_call).
jsr _syscall_trace
@@ -333,7 +361,7 @@
;; check for sanity in the requested syscall number
move.d [sp+LR9], r9
- movs.w -LENOSYS, r10
+ movs.w -ENOSYS, r10
cmpu.w NR_syscalls,r9
bcc 1f
lslq 2,r9 ; multiply by 4, in the delay slot
@@ -344,7 +372,7 @@
;; restore r10, r11, r12, r13, mof and srp into the needed registers
- move.d [sp+LORIG_R10], r10 ; LR10 is already filled with -LENOSYS
+ move.d [sp+LORIG_R10], r10 ; LR10 is already filled with -ENOSYS.
move.d [sp+LR11], r11
move.d [sp+LR12], r12
move.d [sp+LR13], r13
@@ -484,10 +512,72 @@
#endif
_IRQ1_interrupt:
-_spurious_interrupt:
+
+#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
+;; If we receive a watchdog interrupt while it is not expected, then set
+;; up a canonical frame and dump register contents before dying.
+
+ ;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
+ move brp,[sp=sp-16] ; instruction pointer and room for a fake SBFS frame
+ push srp
+ push dccr
+ push mof
di
- jsr _hard_reset_now
+ subq 14*4,sp
+ movem r13,[sp]
+ push r10 ; push orig_r10
+ clear.d [sp=sp-4] ; frametype == 0, normal frame
+
+;; We don't check that we actually were bit by the watchdog as opposed to
+;; an external NMI, since there is currently no handler for external NMI.
+
+;; We'll see this in ksymoops dumps.
+Watchdog_bite:
+
+;; We need to extend the 3.3ms after the NMI at watchdog bite, so we have
+;; time for an oops-dump over a 115k2 serial wire. Another 100ms should do.
+
+;; Change the watchdog key to an arbitrary 3-bit value and restart the
+;; watchdog.
+#define WD_INIT 2
+ moveq IO_FIELD (R_WATCHDOG, key, WD_INIT), r10
+ move.d R_WATCHDOG, r11
+
+ move.d r10,[r11]
+ moveq IO_FIELD (R_WATCHDOG, key, \
+ IO_EXTRACT (R_WATCHDOG, key, \
+ IO_MASK (R_WATCHDOG, key)) \
+ ^ WD_INIT) \
+ | IO_STATE (R_WATCHDOG, enable, start),r10
+ move.d r10,[r11]
+
+;; Note that we don't do "setf m" here (or after two necessary NOPs),
+;; since *not* doing that saves us from re-entrancy checks. We don't want
+;; to get here again due to possible subsequent NMIs; we want the watchdog
+;; to reset us.
+
+ move.d watchdogmsg,r10
+ jsr _printk
+
+ move.d sp,r10
+ jsr _show_registers
+
+;; This nop is here so we see the "Watchdog_bite" label in ksymoops dumps
+;; rather than "_spurious_interrupt".
nop
+;; At this point we drop down into _spurious_interrupt, which will do a
+;; hard reset.
+
+ .section .rodata,"a"
+watchdogmsg:
+ .ascii "Oops: bitten by watchdog\n\0"
+ .previous
+
+#endif /* CONFIG_ETRAX_WATCHDOG and not CONFIG_SVINTO_SIM */
+
+_spurious_interrupt:
+ di
+ jump _hard_reset_now
;; this handles the case when multiple interrupts arrive at the same time
;; we jump to the first set interrupt bit in a priority fashion
@@ -579,14 +669,80 @@
_hw_bp_trig_ptr:
.dword _hw_bp_trigs
-/* Because we compile this file with -traditional, we need to redefine
- token-concatenation to the traditional trick, using an empty comment.
- Normally (in other files, with ISO C as in gcc default) this is done
- with the ## preprocessor operator. */
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process (i.e. the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ *
+ * This *can* be done in C with an single-asm-wrapped-in-a-function, but you
+ * get more or less gross code. The safer you make the asm-constraints,
+ * the grosser the code, at least with the gcc version in cris-dist-1.13.
+ */
+
+/* int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */
+/* r10 r11 r12 */
+
+ .text
+ .global _kernel_thread
+_kernel_thread:
+
+ /* Save ARG for later. */
+ move.d r11,r13
+
+ /* r11 is argument 2 to clone, the flags */
+ move.d r12,r11
+ or.w LCLONE_VM,r11
+
+ /* Save FN for later. */
+ move.d r10,r12
+
+ /* r9 contains syscall number, to sys_clone */
+ movu.w __NR_clone,r9
+
+ /* r10 is argument 1 to clone */
+ clear.d r10
+
+ /* call sys_clone, this will fork */
+ break 13
+
+ /* parent or child? child returns 0 here. */
+ test.d r10
+
+ /* jump if parent */
+ bne 1f
+ nop /* delay slot */
+
+ /* set argument to function to call */
+ move.d r13,r10
+
+ /* call specified function */
+ jsr r12
+ /* If we ever return from the function, something bad has happened. */
+
+ /* r9 is sys_exit syscall number */
+ movu.w __NR_exit,r9
+
+ /* Give a really bad exit-value */
+ moveq -1,r10
+
+ /* call sys_exit, killing the child */
+ break 13
+1:
+ ret
+ nop /* delay slot */
+
+
+/* The file include/linux/linkage.h is wrong for compiling the
+ Linux/CRIS kernel. We currently have C symbols in the kernel (only
+ the kernel) prefixed with _, hence, we need to redefine SYMBOL_NAME. */
#undef SYMBOL_NAME
-#define SYMBOL_NAME(X) _/**/X
-
+#define SYMBOL_NAME(X) _##X
+
+ .section .rodata,"a"
_sys_call_table:
.long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
.long SYMBOL_NAME(sys_exit)
@@ -819,7 +975,7 @@
* been shrunk every time we add a new system call.
*/
- .rept NR_syscalls-221
+ .rept NR_syscalls-222
.long SYMBOL_NAME(sys_ni_syscall)
.endr
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)