patch-2.4.5 linux/arch/cris/kernel/entry.S
Next file: linux/arch/cris/kernel/head.S
Previous file: linux/arch/cris/kernel/debugport.c
Back to the patch index
Back to the overall index
- Lines: 338
- Date:
Sun May 20 12:11:38 2001
- Orig file:
v2.4.4/linux/arch/cris/kernel/entry.S
- Orig date:
Fri Apr 6 10:42:55 2001
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.15 2001/03/05 13:14:30 bjornw Exp $
+/* $Id: entry.S,v 1.22 2001/04/17 13:58:39 orjanf Exp $
*
* linux/arch/cris/entry.S
*
@@ -7,6 +7,40 @@
* Authors: Bjorn Wesen (bjornw@axis.com)
*
* $Log: entry.S,v $
+ * Revision 1.22 2001/04/17 13:58:39 orjanf
+ * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
+ *
+ * Revision 1.21 2001/04/17 11:33:29 orjanf
+ * Updated according to review:
+ * * Included asm/sv_addr_ag.h to get macro for internal register.
+ * * Corrected comment regarding system call argument passing.
+ * * Removed comment about instruction being in a delay slot.
+ * * Added comment about SYMBOL_NAME macro.
+ *
+ * Revision 1.20 2001/04/12 08:51:07 hp
+ * - Add entry for sys_fcntl64. In fact copy last piece from i386 including ...
+ * - .rept to fill table to safe state with sys_ni_syscall.
+ *
+ * Revision 1.19 2001/04/04 09:43:32 orjanf
+ * * Moved do_sigtrap from traps.c to entry.S.
+ * * LTASK_PID need not be global anymore.
+ *
+ * Revision 1.18 2001/03/26 09:25:02 markusl
+ * Updated after review, should now handle USB interrupts correctly.
+ *
+ * Revision 1.17 2001/03/21 16:12:55 bjornw
+ * * Always make room for the cpu status record in the frame, in order to
+ * use the same framelength and layout for both mmu busfaults and normal
+ * irqs. No need to check for the explicit CRIS_FRAME_FIXUP type anymore.
+ * * Fixed bug with using addq for popping the stack in the epilogue - it
+ * destroyed the flag register. Use instructions that don't affect the
+ * flag register instead.
+ * * Removed write to R_PORT_PA_DATA during spurious_interrupt
+ *
+ * Revision 1.16 2001/03/20 19:43:02 bjornw
+ * * Get rid of esp0 setting
+ * * Give a 7th argument to a systemcall - the stackframe
+ *
* Revision 1.15 2001/03/05 13:14:30 bjornw
* Spelling fix
*
@@ -78,9 +112,11 @@
*
*/
+#include <linux/config.h>
#include <linux/linkage.h>
#include <linux/sys.h>
-
+#include <asm/sv_addr_ag.h>
+
;; functions exported from this file
.globl _system_call
@@ -95,10 +131,11 @@
.globl _spurious_interrupt
.globl _hw_bp_trigs
.globl _mmu_bus_fault
-
+ .globl _do_sigtrap
+ .globl _gdb_handle_breakpoint
+
.globl _sys_call_table
- .globl LTASK_PID
;; syscall error codes
LENOSYS = 38
@@ -115,11 +152,6 @@
PT_TRACESYS_BIT = 1
- ;; Offset for esp0 into task_struct: current->thread.esp0.
- ;; FIXME: In need of padding somewhere, to get dword-alignment.
-
-THREAD_ESP0 = 597
-
;; some pt_regs offsets (from ptrace.h)
LORIG_R10 = 4
@@ -182,7 +214,7 @@
;; Since we can't have system calls inside interrupts, it should not matter
;; that we don't stack IRP.
;;
- ;; In r1 we have the wanted syscall number. Arguments come in r10,r11,r12,r13,r0
+ ;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,r13,mof,srp
;;
;; This function looks on the _surface_ like spaghetti programming, but it's
;; really designed so that the fast-path does not force cache-loading of non-used
@@ -190,7 +222,7 @@
_system_call:
;; stack-frame similar to the irq heads, which is reversed in ret_from_sys_call
- push brp ; this is normally push irp
+ move brp,[sp=sp-16] ; instruction pointer and room for a fake SBFS frame
push srp
push dccr
push mof
@@ -202,15 +234,11 @@
movs.w -LENOSYS,r0
move.d r0,[sp+LR10] ; put the default return value in r10 in the frame
- ;; Perform "current->thread.esp0 = sp".
- ;; This used to be a separate function; set_esp0(ssp).
- movs.w -8192,r0 ; THREAD_SIZE == 8192
- and.d sp,r0
-
- move.d sp,[r0+THREAD_ESP0]
-
;; check if this process is syscall-traced
+ movs.w -8192,r0 ; THREAD_SIZE == 8192
+ and.d sp,r0
+
move.d [r0+LTASK_PTRACE],r0
btstq PT_TRACESYS_BIT, r0
bmi tracesys
@@ -222,6 +250,11 @@
bcc _ret_from_sys_call
lslq 2,r9 ; multiply by 4, in the delay slot
+ ;; as a bonus 7th parameter, we give the location on the stack
+ ;; of the register structure itself. some syscalls need this.
+
+ push sp
+
;; the parameter carrying registers r10, r11, r12 and 13 are intact.
;; the fifth and sixth parameters (if any) was in mof and srp
;; respectively, and we need to put them on the stack.
@@ -230,8 +263,8 @@
push mof
jsr [r9+_sys_call_table] ; actually do the system call
- addq 2*4,sp ; pop the mof and srp parameters
- move.d r10,[sp+LR10] ; save the return value
+ addq 3*4,sp ; pop the mof, srp and regs parameters
+ move.d r10,[sp+LR10] ; save the return value
moveq 1,r9 ; "parameter" to ret_from_sys_call to show it was a sys call
@@ -274,31 +307,20 @@
pop mof ; multiply overflow register
pop dccr ; condition codes
pop srp ; subroutine return pointer
- jmpu [sp+] ; return by popping irp and jumping there
- ;; jmpu takes the U-flag into account to see if we return to
- ;; user-mode or kernel mode.
+ ;; now we have a 4-word SBFS frame which we do not want to restore
+ ;; using RBF since it was not stacked with SBFS. instead we would like to
+ ;; just get the PC value to restart it with, and skip the rest of
+ ;; the frame.
+ move [sp=sp+16], p8 ; pop the SBFS frame from the sp
+ jmpu [sp-16] ; return through the irp field in the sbfs frame
RBFexit:
- cmpq 2, r10 ; was it CRIS_FRAME_FIXUP ?
- beq 2f
movem [sp+],r13 ; registers r0-r13, in delay slot
pop mof ; multiply overflow register
pop dccr ; condition codes
pop srp ; subroutine return pointer
rbf [sp+] ; return by popping the CPU status
-2: pop mof ; multiply overflow register
- pop dccr ; condition codes
- pop srp ; subroutine return pointer
- ;; now we have a 4-word SBFS frame which we do not want to restore
- ;; using RBF since we have made a fixup. instead we would like to
- ;; just get the PC value to restart it with, and skip the rest of
- ;; the frame.
- pop irp ; fixup location will be here
- reti ; return to IRP, taking U-flag into account
- addq 12,sp ; Skip rest of SBFS frame.
-
-
tracesys:
;; this first invocation of syscall_trace _requires_ that
;; LR10 in the frame contains -LENOSYS (as is set in the beginning
@@ -332,13 +354,19 @@
move [sp+LMOF], mof
move [sp+LSRP], srp
+ ;; as a bonus 7th parameter, we give the location on the stack
+ ;; of the register structure itself. some syscalls need this.
+
+ push sp
+
;; the fifth and sixth parameters needs to be put on the stack for
;; the system call to find them
push srp
push mof
+
jsr r9 ; actually call the system-call
- addq 2*4,sp ; pop the r0 parameter
+ addq 3*4,sp ; pop the srp, mof and regs parameters
1: move.d r10,[sp+LR10] ; save the return value
@@ -354,8 +382,7 @@
LTHREAD_KSP = 0
LTHREAD_USP = 4
-LTHREAD_ESP0 = 8
-LTHREAD_DCCR = 12
+LTHREAD_DCCR = 8
;; _resume performs the actual task-switching, by switching stack pointers
;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct
@@ -468,8 +495,6 @@
_IRQ1_interrupt:
_spurious_interrupt:
di
- move.b 4,r0
- move.b r0,[0xb0000030]
basse2: ba basse2
nop
@@ -479,7 +504,7 @@
_multiple_interrupt:
;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
- push irp
+ move irp,[sp=sp-16] ; instruction pointer and room for a fake SBFS frame
push srp
push dccr
push mof
@@ -491,15 +516,15 @@
move.d _irq_shortcuts + 8,r1
moveq 2,r2 ; first bit we care about is the timer0 irq
- move.d [0xb00000d8],r0 ; read the irq bits that triggered the multiple irq
+ move.d [R_VECT_MASK_RD],r0 ; read the irq bits that triggered the multiple irq
multloop:
btst r2,r0 ; check for the irq given by bit r2
bmi do_shortcut ; actually do the shortcut
nop
- addq 1,r2 ; next vector bit - remember this is in the delay slot!
+ addq 1,r2 ; next vector bit
addq 4,r1 ; next vector
- cmpq 26,r2
- bne multloop ; process all irq's up to and including number 25
+ cmp.b 32,r2
+ bne multloop ; process all irq's up to and including number 31
nop
;; strange, we didn't get any set vector bits.. oh well, just return
@@ -513,6 +538,48 @@
nop
jump [r1] ; jump to the irq handlers shortcut
+_do_sigtrap:
+ ;;
+ ;; SIGTRAP the process that executed the break instruction.
+ ;; Make a frame that Rexit in entry.S expects.
+ ;;
+ move brp,[sp=sp-16] ; Push BRP while faking a cpu status record.
+ push srp ; Push subroutine return pointer.
+ push dccr ; Push condition codes.
+ push mof ; Push multiply overflow reg.
+ di ; Need to disable irq's at this point.
+ subq 14*4,sp ; Make room for r0-r13.
+ movem r13,[sp] ; Push the r0-r13 registers.
+ push r10 ; Push orig_r10.
+ clear.d [sp=sp-4] ; Frametype - this is a normal stackframe.
+
+ movs.w -8192,r9 ; THREAD_SIZE == 8192
+ and.d sp,r9
+ move.d [r9+LTASK_PID],r10 ; current->pid as arg1.
+ moveq 5,r11 ; SIGTRAP as arg2.
+ jsr _sys_kill
+ jump _ret_from_intr ; Use the return routine for interrupts.
+
+_gdb_handle_breakpoint:
+ push dccr
+ push r0
+#ifdef CONFIG_ETRAX_KGDB
+ move dccr,r0 ; U-flag not affected by previous insns.
+ btstq 8,r0 ; Test the U-flag.
+ bmi _ugdb_handle_breakpoint ; Go to user mode debugging.
+ nop ; Empty delay slot (cannot pop r0 here).
+ pop r0 ; Restore r0.
+ ba _kgdb_handle_breakpoint ; Go to kernel debugging.
+ pop dccr ; Restore dccr in delay slot.
+#endif
+
+_ugdb_handle_breakpoint:
+ move brp,r0 ; Use r0 temporarily for calculation.
+ subq 2,r0 ; Set to address of previous instruction.
+ move r0,brp
+ pop r0 ; Restore r0.
+ ba _do_sigtrap ; SIGTRAP the offending process.
+ pop dccr ; Restore dccr in delay slot.
.data
@@ -521,8 +588,11 @@
_hw_bp_trig_ptr:
.dword _hw_bp_trigs
-/* linux/linkage.h got it wrong for this compiler currently */
-
+/* 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. */
+
#undef SYMBOL_NAME
#define SYMBOL_NAME(X) _/**/X
@@ -748,6 +818,8 @@
.long SYMBOL_NAME(sys_mincore)
.long SYMBOL_NAME(sys_madvise)
.long SYMBOL_NAME(sys_getdents64) /* 220 */
+ .long SYMBOL_NAME(sys_fcntl64)
+ .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
/*
* NOTE!! This doesn't have to be exact - we just have
@@ -756,9 +828,7 @@
* been shrunk every time we add a new system call.
*/
- ;; TODO: this needs to actually generate sys_ni_syscall entires
- ;; since we now have removed the check for NULL entries in this
- ;; table in system_call!
-
- .space (NR_syscalls-220)*4
+ .rept NR_syscalls-221
+ .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)