patch-2.4.4 linux/arch/s390/kernel/entry.S
Next file: linux/arch/s390/kernel/floatlib.c
Previous file: linux/arch/s390/kernel/ebcdic.c
Back to the patch index
Back to the overall index
- Lines: 433
- Date:
Wed Apr 11 19:02:27 2001
- Orig file:
v2.4.3/linux/arch/s390/kernel/entry.S
- Orig date:
Fri Mar 2 11:12:06 2001
diff -u --recursive --new-file v2.4.3/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
@@ -9,56 +9,52 @@
* Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
*/
+#define ASSEMBLY
+
#include <linux/sys.h>
#include <linux/linkage.h>
#include <linux/config.h>
#include <asm/lowcore.h>
#include <asm/errno.h>
-#define ASSEMBLY
#include <asm/smp.h>
-#include <asm/s390-regs-common.h>
-
+#include <asm/ptrace.h>
/*
- * stack layout for the system_call stack entry
- * Martin please don't modify these back to hard coded values
- * You know how bad I'm at mental arithmetic DJB & it gives
- * me grief when I modify the pt_regs
+ * Stack layout for the system_call stack entry.
+ * The first few entries are identical to the user_regs_struct.
*/
SP_PTREGS = STACK_FRAME_OVERHEAD
-SP_PSW = SP_PTREGS
-SP_R0 = (SP_PSW+PSW_MASK_SIZE+PSW_ADDR_SIZE)
-SP_R1 = (SP_R0+GPR_SIZE)
-SP_R2 = (SP_R1+GPR_SIZE)
-SP_R3 = (SP_R2+GPR_SIZE)
-SP_R4 = (SP_R3+GPR_SIZE)
-SP_R5 = (SP_R4+GPR_SIZE)
-SP_R6 = (SP_R5+GPR_SIZE)
-SP_R7 = (SP_R6+GPR_SIZE)
-SP_R8 = (SP_R7+GPR_SIZE)
-SP_R9 = (SP_R8+GPR_SIZE)
-SP_RA = (SP_R9+GPR_SIZE)
-SP_RB = (SP_RA+GPR_SIZE)
-SP_RC = (SP_RB+GPR_SIZE)
-SP_RD = (SP_RC+GPR_SIZE)
-SP_RE = (SP_RD+GPR_SIZE)
-SP_RF = (SP_RE+GPR_SIZE)
-SP_AREGS = (SP_RF+GPR_SIZE)
-SP_ORIG_R2 = (SP_AREGS+(NUM_ACRS*ACR_SIZE))
+SP_PSW = STACK_FRAME_OVERHEAD + PT_PSWMASK
+SP_R0 = STACK_FRAME_OVERHEAD + PT_GPR0
+SP_R1 = STACK_FRAME_OVERHEAD + PT_GPR1
+SP_R2 = STACK_FRAME_OVERHEAD + PT_GPR2
+SP_R3 = STACK_FRAME_OVERHEAD + PT_GPR3
+SP_R4 = STACK_FRAME_OVERHEAD + PT_GPR4
+SP_R5 = STACK_FRAME_OVERHEAD + PT_GPR5
+SP_R6 = STACK_FRAME_OVERHEAD + PT_GPR6
+SP_R7 = STACK_FRAME_OVERHEAD + PT_GPR7
+SP_R8 = STACK_FRAME_OVERHEAD + PT_GPR8
+SP_R9 = STACK_FRAME_OVERHEAD + PT_GPR9
+SP_R10 = STACK_FRAME_OVERHEAD + PT_GPR10
+SP_R11 = STACK_FRAME_OVERHEAD + PT_GPR11
+SP_R12 = STACK_FRAME_OVERHEAD + PT_GPR12
+SP_R13 = STACK_FRAME_OVERHEAD + PT_GPR13
+SP_R14 = STACK_FRAME_OVERHEAD + PT_GPR14
+SP_R15 = STACK_FRAME_OVERHEAD + PT_GPR15
+SP_AREGS = STACK_FRAME_OVERHEAD + PT_ACR0
+SP_ORIG_R2 = STACK_FRAME_OVERHEAD + PT_ORIGGPR2
+/* Now the additional entries */
SP_TRAP = (SP_ORIG_R2+GPR_SIZE)
#if CONFIG_REMOTE_DEBUG
SP_CRREGS = (SP_TRAP+4)
/* fpu registers are saved & restored by the gdb stub itself */
SP_FPC = (SP_CRREGS+(NUM_CRS*CR_SIZE))
SP_FPRS = (SP_FPC+FPC_SIZE+FPC_PAD_SIZE)
-/* SP_PGM_OLD_ILC etc are not part of pt_regs & they are not
- defined in ptrace.h but space is needed for this too */
SP_PGM_OLD_ILC= (SP_FPRS+(NUM_FPRS*FPR_SIZE))
#else
SP_PGM_OLD_ILC= (SP_TRAP+4)
#endif
-SP_SVC_STEP = (SP_PGM_OLD_ILC+4)
-SP_SIZE = (SP_SVC_STEP+4)
+SP_SIZE = (SP_PGM_OLD_ILC+4)
/*
* these defines are offsets into the thread_struct
*/
@@ -73,6 +69,8 @@
_TSS_TRAP = (_TSS_PROT+4)
_TSS_MM = (_TSS_TRAP+4)
_TSS_PER = (_TSS_MM+8)
+_TSS_IEEE = (_TSS_PER+36)
+_TSS_FLAGS = (_TSS_IEEE+4)
/*
* these are offsets into the task-struct.
@@ -84,11 +82,6 @@
tsk_ptrace = 28
processor = 60
-/* PSW related defines */
-disable = 0xFC
-enable = 0x03
-daton = 0x04
-
/*
* Base Address of this Module --- saved in __LC_ENTRY_BASE
*/
@@ -97,26 +90,6 @@
#define BASED(name) name-entry_base(%r13)
-#if 0
-/* some code left lying around in case we need a
- * printk for debugging purposes
- */
- sysc_printk: .long printk
- sysc_msg: .string "<2>r15 %X\n"
- .align 4
-
-# basr %r13,0
- l %r0,SP_PSW+4(%r15)
- sll %r0,1
- chi %r0,0
- jnz sysc_dn
- l %r9,sysc_printk-sysc_lit(%r13)
- la %r2,sysc_msg-sysc_lit(%r13)
- lr %r3,%r15
- basr %r14,%r9
-sysc_dn:
-#endif
-
/*
* Register usage in interrupt handlers:
* R9 - pointer to current task structure
@@ -125,38 +98,41 @@
* R15 - kernel stack pointer
*/
-#define SAVE_ALL(psworg) \
- stm %r13,%r15,__LC_SAVE_AREA ; \
- stam %a2,%a4,__LC_SAVE_AREA+12 ; \
- basr %r13,0 ; /* temp base pointer */ \
- l %r13,.Lentry_base-.(%r13) ; /* load &entry_base to %r13 */ \
- tm psworg+1,0x01 ; /* test problem state bit */ \
- bz BASED(.+12) ; /* skip stack setup save */ \
- l %r15,__LC_KERNEL_STACK ; /* problem state -> load ksp */ \
- lam %a2,%a4,BASED(.Lc_ac) ; /* set ac.reg. 2 to primary space */ \
- /* and access reg. 4 to home space */ \
-0: s %r15,BASED(.Lc_spsize); /* make room for registers & psw */ \
- n %r15,BASED(.Lc0xfffffff8) ; /* align stack pointer to 8 */ \
- stm %r0,%r12,SP_R0(%r15) ; /* store gprs 0-12 to kernel stack */ \
- st %r2,SP_ORIG_R2(%r15) ; /* store original content of gpr 2 */ \
- mvc SP_RD(12,%r15),__LC_SAVE_AREA ; /* move R13-R15 to stack */ \
- stam %a0,%a15,SP_AREGS(%r15) ; /* store access registers to kst. */ \
- mvc SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 ; /* store ac. regs */ \
- mvc SP_PSW(8,%r15),psworg ; /* move user PSW to stack */ \
- la %r0,psworg ; /* store trap indication */ \
- st %r0,SP_TRAP(%r15) ; \
- xc 0(4,%r15),0(%r15) ; /* clear back chain */
-
-#define RESTORE_ALL \
- mvc __LC_RETURN_PSW(8),SP_PSW(%r15) ; /* move user PSW to lowcore */ \
- lam %a0,%a15,SP_AREGS(%r15) ; /* load the access registers */ \
- lm %r0,%r15,SP_R0(%r15) ; /* load gprs 0-15 of user */ \
- ni __LC_RETURN_PSW+1,0xfd ; /* clear wait state bit */ \
- lpsw __LC_RETURN_PSW /* back to caller */
+ .macro SAVE_ALL psworg # system entry macro
+ stm %r13,%r15,__LC_SAVE_AREA
+ stam %a2,%a4,__LC_SAVE_AREA+12
+ basr %r13,0 # temp base pointer
+ l %r13,.Lentry_base-.(%r13) # load &entry_base to %r13
+ tm \psworg+1,0x01 # test problem state bit
+ bz BASED(.+12) # skip stack setup save
+ l %r15,__LC_KERNEL_STACK # problem state -> load ksp
+ lam %a2,%a4,BASED(.Lc_ac) # set ac.reg. 2 to primary space
+ # and access reg. 4 to home space
+0: s %r15,BASED(.Lc_spsize) # make room for registers & psw
+ n %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
+ stm %r0,%r12,SP_R0(%r15) # store gprs 0-12 to kernel stack
+ st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
+ mvc SP_R13(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
+ stam %a0,%a15,SP_AREGS(%r15) # store access registers to kst.
+ mvc SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
+ mvc SP_PSW(8,%r15),\psworg # move user PSW to stack
+ la %r0,\psworg # store trap indication
+ st %r0,SP_TRAP(%r15)
+ xc 0(4,%r15),0(%r15) # clear back chain
+ .endm
+
+ .macro RESTORE_ALL # system exit macro
+ mvc __LC_RETURN_PSW(8),SP_PSW(%r15) # move user PSW to lowcore
+ lam %a0,%a15,SP_AREGS(%r15) # load the access registers
+ lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
+ ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
+ lpsw __LC_RETURN_PSW # back to caller
+ .endm
-#define GET_CURRENT /* load pointer to task_struct to R9 */ \
- lr %r9,%r15 ; \
+ .macro GET_CURRENT
+ lr %r9,%r15 # load pointer to task_struct to %r9
n %r9,BASED(.Lc0xffffe000)
+ .endm
/*
@@ -173,7 +149,7 @@
l %r4,_TSS_PTREGS(%r3)
tm SP_PSW-SP_PTREGS(%r4),0x40 # is the new process using per ?
bz resume_noper-resume_base(%r1) # if not we're fine
- stctl %r9,%r11,24(%r15) # We are using per stuff
+ stctl %c9,%c11,24(%r15) # We are using per stuff
clc _TSS_PER(12,%r3),24(%r15)
be resume_noper-resume_base(%r1) # we got away w/o bashing TLB's
lctl %c9,%c11,_TSS_PER(%r3) # Nope we didn't
@@ -202,13 +178,13 @@
.globl system_call
system_call:
- SAVE_ALL(0x20)
- xc SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)
+ SAVE_ALL __LC_SVC_OLD_PSW
+ mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid
pgm_system_call:
+ GET_CURRENT # load pointer to task_struct to R9
slr %r8,%r8 # gpr 8 is call save (-> tracesys)
ic %r8,0x8B # get svc number from lowcore
stosm 24(%r15),0x03 # reenable interrupts
- GET_CURRENT # load pointer to task_struct to R9
sll %r8,2
l %r8,sys_call_table-entry_base(8,%r13) # get address of system call
tm tsk_ptrace+3(%r9),0x02 # PT_TRACESYS
@@ -219,7 +195,6 @@
# changing anything here !!
sysc_return:
- GET_CURRENT # load pointer to task_struct to R9
tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_leave) # no-> skip bottom half, resched & signal
#
@@ -237,9 +212,9 @@
icm %r0,15,sigpending(%r9) # get sigpending from task_struct
bnz BASED(sysc_signal_return)
sysc_leave:
- icm %r0,15,SP_SVC_STEP(%r15) # get sigpending from task_struct
- bnz BASED(pgm_svcret)
- stnsm 24(%r15),disable # disable I/O and ext. interrupts
+ tm SP_PGM_OLD_ILC(%r15),0xff
+ bz BASED(pgm_svcret)
+ stnsm 24(%r15),0xfc # disable I/O and ext. interrupts
RESTORE_ALL
#
@@ -371,7 +346,7 @@
br %r1 # branch to sys_rt_sigsuspend
sys_sigaltstack_glue:
- la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
+ la %r4,SP_PTREGS(%r15) # load pt_regs as parameter
l %r1,BASED(.Lsigaltstack)
br %r1 # branch to sys_sigreturn
@@ -647,20 +622,19 @@
n %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
stm %r0,%r12,SP_R0(%r15) # store gprs 0-12 to kernel stack
st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
- mvc SP_RD(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
+ mvc SP_R13(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
stam %a0,%a15,SP_AREGS(%r15) # store access registers to kst.
mvc SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
mvc SP_PSW(8,%r15),0x20 # move user PSW to stack
la %r0,0x20 # store trap indication
st %r0,SP_TRAP(%r15)
xc 0(4,%r15),0(%r15) # clear back chain
- mvi SP_SVC_STEP(%r15),1 # make SP_SVC_STEP nonzero
mvc SP_PGM_OLD_ILC(4,%r15),__LC_PGM_ILC # save program check information
b BASED(pgm_system_call) # now do the svc
pgm_svcret:
mvi SP_TRAP+3(%r15),0x28 # set trap indication back to pgm_chk
lh %r7,SP_PGM_OLD_ILC(%r15) # get ilc from stack
- xc SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)
+ mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid
b BASED(pgm_no_sv)
pgm_sv:
tm 0x29,0x01 # test problem state bit
@@ -672,25 +646,25 @@
n %r15,BASED(.Lc0xfffffff8) # align stack pointer to 8
stm %r0,%r12,SP_R0(%r15) # store gprs 0-12 to kernel stack
st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
- mvc SP_RD(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
+ mvc SP_R13(12,%r15),__LC_SAVE_AREA # move R13-R15 to stack
stam %a0,%a15,SP_AREGS(%r15) # store access registers to kst.
mvc SP_AREGS+8(12,%r15),__LC_SAVE_AREA+12 # store ac. regs
mvc SP_PSW(8,%r15),0x28 # move user PSW to stack
la %r0,0x28 # store trap indication
st %r0,SP_TRAP(%r15)
xc 0(4,%r15),0(%r15) # clear back chain
- xc SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)
- lh %r7,__LC_PGM_ILC # load instruction length
+ mvi SP_PGM_OLD_ILC(%r15),1 # mark PGM_OLD_ILC as invalid
+ lh %r7,__LC_PGM_ILC # load instruction length
+ GET_CURRENT
pgm_no_sv:
lh %r8,__LC_PGM_INT_CODE # N.B. saved int code used later KEEP it
- stosm 24(%r15),0x03 # reenable interrupts
lr %r3,%r8
la %r0,0x7f
nr %r3,%r0 # clear per-event-bit
be BASED(pgm_dn) # none of Martins exceptions occurred bypass
- l %r9,BASED(.Ljump_table)
+ l %r1,BASED(.Ljump_table)
sll %r3,2
- l %r9,0(%r3,%r9) # load address of handler routine
+ l %r1,0(%r3,%r1) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
srl %r3,2
cl %r3,BASED(.Lc4) # protection-exception ?
@@ -698,14 +672,17 @@
l %r5,SP_PSW+4(15) # load psw addr
sr %r5,%r7 # substract ilc from psw
st %r5,SP_PSW+4(15) # store corrected psw addr
-pgm_go: basr %r14,%r9 # branch to interrupt-handler
+pgm_per:cl %r3,BASED(.Lc20) # pseudo page fault ?
+ be BASED(pgm_go) # if yes then don't reenable interrupts
+ stosm 24(%r15),0x03 # reenable interrupts
+pgm_go: basr %r14,%r1 # branch to interrupt-handler
pgm_dn: la %r0,0x80
nr %r8,%r0 # check for per exception
be BASED(pgm_return)
la %r2,SP_PTREGS(15) # address of register-save area
- l %r9,BASED(.Lhandle_per) # load adr. of per handler
+ l %r1,BASED(.Lhandle_per) # load adr. of per handler
la %r14,BASED(sysc_return) # load adr. of system return
- br %r9 # branch to handle_per_exception
+ br %r1 # branch to handle_per_exception
#
# the backend code is the same as for sys-call
@@ -719,19 +696,19 @@
.globl io_int_handler
io_int_handler:
- SAVE_ALL(0x38)
+ SAVE_ALL __LC_IO_OLD_PSW
+ GET_CURRENT # load pointer to task_struct to R9
la %r2,SP_PTREGS(%r15) # address of register-save area
sr %r3,%r3
icm %r3,%r3,__LC_SUBCHANNEL_NR # load subchannel nr & extend to int
- l %r4,__LC_IO_INT_PARM # load interruption parm
- l %r5,__LC_IO_INT_WORD # load interruption word
- l %r9,BASED(.Ldo_IRQ) # load address of do_IRQ
- basr %r14,%r9 # branch to standard irq handler
+ l %r4,__LC_IO_INT_PARM # load interuption parm
+ l %r5,__LC_IO_INT_WORD # load interuption word
+ l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
+ basr %r14,%r1 # branch to standard irq handler
io_return:
- GET_CURRENT # load pointer to task_struct to R9
tm SP_PSW+1(%r15),0x01 # returning to user ?
- bz BASED(io_leave) # no-> skip resched & signal
+ bno BASED(io_leave) # no-> skip resched & signal
stosm 24(%r15),0x03 # reenable interrupts
#
# check, if bottom-half has to be done
@@ -748,7 +725,7 @@
icm %r0,15,sigpending(%r9) # get sigpending from task_struct
bnz BASED(io_signal_return)
io_leave:
- stnsm 24(%r15),disable # disable I/O and ext. interrupts
+ stnsm 24(%r15),0xfc # disable I/O and ext. interrupts
RESTORE_ALL
#
@@ -784,26 +761,27 @@
.globl ext_int_handler
ext_int_handler:
- SAVE_ALL(0x18)
+ SAVE_ALL __LC_EXT_OLD_PSW
+ GET_CURRENT # load pointer to task_struct to R9
la %r2,SP_PTREGS(%r15) # address of register-save area
lh %r3,__LC_EXT_INT_CODE # error code
lr %r1,%r3 # calculate index = code & 0xff
n %r1,BASED(.Lc0xff)
sll %r1,2
- l %r9,BASED(.Lext_hash)
- l %r9,0(%r1,%r9) # get first list entry for hash value
- ltr %r9,%r9 # == NULL ?
+ l %r4,BASED(.Lext_hash)
+ l %r4,0(%r1,%r4) # get first list entry for hash value
+ ltr %r4,%r4 # == NULL ?
bz BASED(io_return) # yes, nothing to do, exit
ext_int_loop:
- ch %r3,8(%r9) # compare external interrupt code
+ ch %r3,8(%r4) # compare external interrupt code
be BASED(ext_int_found)
- icm %r9,15,0(%r9) # next list entry
+ icm %r4,15,0(%r4) # next list entry
bnz BASED(ext_int_loop)
b BASED(io_return)
ext_int_found:
- l %r9,4(%r9) # get handler address
+ l %r4,4(%r4) # get handler address
la %r14,BASED(io_return)
- br %r9 # branch to ext call handler
+ br %r4 # branch to ext call handler
/*
* Machine check handler routines
@@ -811,7 +789,7 @@
.globl mcck_int_handler
mcck_int_handler:
- SAVE_ALL(0x30)
+ SAVE_ALL __LC_MCK_OLD_PSW
l %r1,BASED(.Ls390_mcck)
basr %r14,%r1 # call machine check handler
mcck_return:
@@ -826,7 +804,7 @@
l %r15,__LC_KERNEL_STACK # load ksp
lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
lam %a0,%a15,__LC_AREGS_SAVE_AREA
- stosm 0(%r15),daton # now we can turn dat on
+ stosm 0(%r15),0x04 # now we can turn dat on
lm %r6,%r15,24(%r15) # load registers from clone
basr %r14,0
l %r14,restart_addr-.(%r14)
@@ -859,6 +837,7 @@
.Lc_ac: .long 0,0,1
.Lc_ENOSYS: .long -ENOSYS
.Lc4: .long 4
+.Lc20: .long 20
.Lc0x1202: .long 0x1202
.Lc0x1004: .long 0x1004
.Lc0x2401: .long 0x2401
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)