patch-2.2.16 linux/arch/s390/kernel/entry.S
Next file: linux/arch/s390/kernel/head.S
Previous file: linux/arch/s390/kernel/ebcdic.c
Back to the patch index
Back to the overall index
- Lines: 829
- Date:
Wed Jun 7 14:26:42 2000
- Orig file:
v2.2.15/linux/arch/s390/kernel/entry.S
- Orig date:
Wed May 3 17:16:31 2000
diff -urN v2.2.15/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
@@ -89,6 +89,13 @@
enable = 0x03
daton = 0x04
+/*
+ * Base Address of this Module --- saved in __LC_ENTRY_BASE
+ */
+ .globl entry_base
+entry_base:
+
+#define BASED(name) name-entry_base(%r13)
#if 0
/* some code left lying around in case we need a
@@ -118,59 +125,38 @@
* R15 - kernel stack pointer
*/
-#define SAVE_ALL1(psworg) \
- st %r15,__LC_SAVE_AREA ; \
+#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 */ \
- jz 0f ; /* skip stack setup save */ \
+ bz BASED(.+12) ; /* skip stack & access regs setup */ \
l %r15,__LC_KERNEL_STACK ; /* problem state -> load ksp */ \
-0: ahi %r15,-SP_SIZE ; /* make room for registers & psw */ \
- srl %r15,3 ; \
- sll %r15,3 ; /* align stack pointer to 8 */ \
- stm %r0,%r14,SP_R0(%r15) ; /* store gprs 0-14 to kernel stack */ \
+ 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_RF(4,%r15),__LC_SAVE_AREA ; /* move R15 to stack */ \
+ 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 */ \
- xc 0(7,%r15),0(%r15) ; /* clear back chain & trap ind. */ \
- mvi SP_TRAP+3(%r15),psworg ; /* store trap indication in pt_regs */ \
- slr %r0,%r0 ; \
- sar %a2,%r0 ; /* set ac.reg. 2 to primary space */ \
- lhi %r0,1 ; \
- sar %a4,%r0 ; /* set access reg. 4 to home space */
+ la %r0,psworg ; /* store trap indication */ \
+ st %r0,SP_TRAP(%r15) ; \
+ xc 0(4,%r15),0(%r15) ; /* clear back chain */
-#define RESTORE_ALL1 \
- mvc 0x50(8,0),SP_PSW(%r15) ; /* move user PSW to lowcore */ \
+#define RESTORE_ALL \
+ mvc __LC_RETURN_PSW(8,0),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 0x51(0),0xfd ; /* clear wait state bit */ \
- lpsw 0x50 /* back to caller */
-
-#if CONFIG_REMOTE_DEBUG
-#define SAVE_ALL(psworg) \
- SAVE_ALL1(psworg) \
- tm psworg+1,0x01 ; /* test problem state bit */ \
- jz 0f ; /* skip stack setup save */ \
- stctl %c0,%c15,SP_CRREGS(%r15) ; /* save control regs for remote debugging */ \
-0:
-
-#define RESTORE_ALL \
- tm SP_PSW+1(%r15),0x01 ; /* test problem state bit */ \
- jz 0f ; /* skip cr restore */ \
- lctl %c0,%c15,SP_CRREGS(%r15) ; /* store control regs for remote debugging */ \
-0: RESTORE_ALL1
-#else
-
-#define SAVE_ALL(psworg) \
- SAVE_ALL1(psworg)
-
-#define RESTORE_ALL \
- RESTORE_ALL1
-#endif
+ ni __LC_RETURN_PSW+1(0),0xfd ; /* clear wait state bit */ \
+ lpsw __LC_RETURN_PSW /* back to caller */
#define GET_CURRENT /* load pointer to task_struct to R9 */ \
- lhi %r9,-8192 ; \
- nr %r9,15
-
+ lr %r9,%r15 ; \
+ n %r9,BASED(.Lc0xffffe000)
/*
* Scheduler resume function, called by switch_to
@@ -181,22 +167,24 @@
*/
.globl resume
resume:
+ basr %r1,0 # setup base pointer
+resume_base:
l %r4,_TSS_PTREGS(%r3)
tm SP_PSW-SP_PTREGS(%r4),0x40 # is the new process using per ?
- jz RES_DN1 # if not we're fine
+ bz resume_noper-resume_base(%r1) # if not we're fine
stctl %r9,%r11,24(%r15) # We are using per stuff
clc _TSS_PER(12,%r3),24(%r15)
- je RES_DN1 # we got away without bashing TLB's
+ be resume_noper-resume_base(%r1) # we got away w/o bashing TLB's
lctl %c9,%c11,_TSS_PER(%r3) # Nope we didn't
-RES_DN1:
+resume_noper:
stm %r6,%r15,24(%r15) # store resume registers of prev task
st %r15,_TSS_KSP(%r2) # store kernel stack ptr to prev->tss.ksp
- lhi %r0,-8192
- nr %r0,%r15
+ lr %r0,%r15
+ n %r0,.Lc0xffffe000-resume_base(%r1)
l %r15,_TSS_KSP(%r3) # load kernel stack ptr from next->tss.ksp
- lhi %r1,8191
+ l %r1,.Lc8191-resume_base(%r1)
or %r1,%r15
- ahi %r1,1
+ la %r1,1(%r1)
st %r1,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack
stam %a2,%a2,_TSS_AR2(%r2) # store kernel access reg. 2
stam %a4,%a4,_TSS_AR4(%r2) # store kernel access reg. 4
@@ -213,40 +201,19 @@
* are executed with interrupts enabled.
*/
-sysc_lit:
- sysc_bhmask: .long bh_mask
- sysc_bhactive: .long bh_active
- sysc_do_signal: .long do_signal
- sysc_do_bottom_half:.long do_bottom_half
- sysc_schedule: .long schedule
- sysc_trace: .long syscall_trace
-#ifdef __SMP__
- sysc_schedtail: .long schedule_tail
-#endif
- sysc_clone: .long sys_clone
- sysc_fork: .long sys_fork
- sysc_vfork: .long sys_vfork
- sysc_sigreturn: .long sys_sigreturn
- sysc_rt_sigreturn: .long sys_rt_sigreturn
- sysc_execve: .long sys_execve
- sysc_sigsuspend: .long sys_sigsuspend
- sysc_rt_sigsuspend: .long sys_rt_sigsuspend
-
.globl system_call
system_call:
SAVE_ALL(0x20)
- XC SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)
+ xc SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)
pgm_system_call:
- basr %r13,0
- ahi %r13,sysc_lit-. # setup base pointer R13 to sysc_lit
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-sysc_lit(8,%r13) # get address of system call
+ l %r8,sys_call_table-entry_base(8,%r13) # get address of system call
tm flags+3(%r9),0x20 # PF_TRACESYS
- jnz sysc_tracesys
+ bnz BASED(sysc_tracesys)
basr %r14,%r8 # call sys_xxxx
st %r2,SP_R2(%r15) # store return value (change R2 on stack)
# ATTENTION: check sys_execve_glue before
@@ -255,26 +222,26 @@
sysc_return:
GET_CURRENT # load pointer to task_struct to R9
tm SP_PSW+1(%r15),0x01 # returning to user ?
- jno sysc_leave # no-> skip bottom half, resched & signal
+ bno BASED(sysc_leave) # no-> skip bottom half, resched & signal
#
# check, if bottom-half has to be done
#
- l %r1,sysc_bhmask-sysc_lit(%r13)
+ l %r1,BASED(.Lbhmask)
l %r0,0(%r1)
- l %r1,sysc_bhactive-sysc_lit(%r13)
+ l %r1,BASED(.Lbhactive)
n %r0,0(%r1)
- jnz sysc_handle_bottom_half
+ bnz BASED(sysc_handle_bottom_half)
#
# check, if reschedule is needed
#
sysc_return_bh:
icm %r0,15,need_resched(%r9) # get need_resched from task_struct
- jnz sysc_reschedule
+ bnz BASED(sysc_reschedule)
icm %r0,15,sigpending(%r9) # get sigpending from task_struct
- jnz sysc_signal_return
+ bnz BASED(sysc_signal_return)
sysc_leave:
icm %r0,15,SP_SVC_STEP(%r15) # get sigpending from task_struct
- jnz pgm_svcret
+ bnz BASED(pgm_svcret)
stnsm 24(%r15),disable # disable I/O and ext. interrupts
RESTORE_ALL
@@ -284,24 +251,24 @@
sysc_signal_return:
la %r2,SP_PTREGS(%r15) # load pt_regs
sr %r3,%r3 # clear *oldset
- l %r1,sysc_do_signal-sysc_lit(%r13)
- la %r14,sysc_leave-sysc_lit(%r13)
+ l %r1,BASED(.Ldo_signal)
+ la %r14,BASED(sysc_leave)
br %r1 # return point is sysc_leave
#
# call trace before and after sys_call
#
sysc_tracesys:
- l %r1,sysc_trace-sysc_lit(%r13)
- lhi %r2,-ENOSYS
+ l %r1,BASED(.Ltrace)
+ l %r2,BASED(.Lc_ENOSYS)
st %r2,SP_R2(%r15) # give sysc_trace an -ENOSYS retval
basr %r14,%r1
lm %r3,%r6,SP_R3(%r15)
l %r2,SP_ORIG_R2(%r15)
basr %r14,%r8 # call sys_xxx
st %r2,SP_R2(%r15) # store return value
- l %r1,sysc_trace-sysc_lit(%r13)
- la %r14,sysc_return-sysc_lit(%r13)
+ l %r1,BASED(.Ltrace)
+ la %r14,BASED(sysc_return)
br %r1 # return point is sysc_return
@@ -310,16 +277,16 @@
# is zero
#
sysc_handle_bottom_half:
- l %r1,sysc_do_bottom_half-sysc_lit(%r13)
- la %r14,sysc_return_bh-sysc_lit(%r13)
+ l %r1,BASED(.Ldo_bottom_half)
+ la %r14,BASED(sysc_return_bh)
br %r1 # call do_bottom_half
#
# call schedule with sysc_return as return-address
#
sysc_reschedule:
- l %r1,sysc_schedule-sysc_lit(%r13)
- la %r14,sysc_return-sysc_lit(%r13)
+ l %r1,BASED(.Lschedule)
+ la %r14,BASED(sysc_return)
br %r1 # call scheduler, return to sysc_return
#
@@ -328,17 +295,17 @@
.globl ret_from_fork
ret_from_fork:
basr %r13,0
- ahi %r13,sysc_lit-. # setup base pointer R13 to $SYSCDAT
+ l %r13,.Lentry_base-.(%r13) # setup base pointer to &entry_base
GET_CURRENT # load pointer to task_struct to R9
stosm 24(%r15),0x03 # reenable interrupts
sr %r0,%r0 # child returns 0
st %r0,SP_R2(%r15) # store return value (change R2 on stack)
#ifdef __SMP__
- l %r1,sysc_schedtail-sysc_lit(%r13)
- la %r14,sysc_return-sysc_lit(%r13)
+ l %r1,BASED(.Lschedtail)
+ la %r14,BASED(sysc_return)
br %r1 # call schedule_tail, return to sysc_return
#else
- j sysc_return
+ b BASED(sysc_return)
#endif
#
@@ -349,22 +316,22 @@
#
sys_clone_glue:
la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,sysc_clone-sysc_lit(%r13)
+ l %r1,BASED(.Lclone)
br %r1 # branch to sys_clone
sys_fork_glue:
la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,sysc_fork-sysc_lit(%r13)
+ l %r1,BASED(.Lfork)
br %r1 # branch to sys_fork
sys_vfork_glue:
la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,sysc_vfork-sysc_lit(%r13)
+ l %r1,BASED(.Lvfork)
br %r1 # branch to sys_vfork
sys_execve_glue:
la %r2,SP_PTREGS(%r15) # load pt_regs
- l %r1,sysc_execve-sysc_lit(%r13)
+ l %r1,BASED(.Lexecve)
lr %r12,%r14 # save return address
basr %r14,%r1 # call sys_execve
ltr %r2,%r2 # check if execve failed
@@ -374,12 +341,12 @@
sys_sigreturn_glue:
la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
- l %r1,sysc_sigreturn-sysc_lit(%r13)
+ l %r1,BASED(.Lsigreturn)
br %r1 # branch to sys_sigreturn
sys_rt_sigreturn_glue:
la %r2,SP_PTREGS(%r15) # load pt_regs as parameter
- l %r1,sysc_rt_sigreturn-sysc_lit(%r13)
+ l %r1,BASED(.Lrt_sigreturn)
br %r1 # branch to sys_sigreturn
#
@@ -394,7 +361,7 @@
lr %r4,%r3 # move history1 parameter
lr %r3,%r2 # move history0 parameter
la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter
- l %r1,sysc_sigsuspend-sysc_lit(%r13)
+ l %r1,BASED(.Lsigsuspend)
la %r14,4(%r14) # skip store of return value
br %r1 # branch to sys_sigsuspend
@@ -402,7 +369,7 @@
lr %r4,%r3 # move sigsetsize parameter
lr %r3,%r2 # move unewset parameter
la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter
- l %r1,sysc_rt_sigsuspend-sysc_lit(%r13)
+ l %r1,BASED(.Lrt_sigsuspend)
la %r14,4(%r14) # skip store of return value
br %r1 # branch to sys_rt_sigsuspend
@@ -415,7 +382,7 @@
.long sys_write
.long sys_open /* 5 */
.long sys_close
- .long sys_waitpid
+ .long sys_ni_syscall /* old waitpid syscall holder */
.long sys_creat
.long sys_link
.long sys_unlink /* 10 */
@@ -426,7 +393,7 @@
.long sys_chmod /* 15 */
.long sys_lchown
.long sys_ni_syscall /* old break syscall holder */
- .long sys_stat
+ .long sys_ni_syscall /* old stat syscall holder */
.long sys_lseek
.long sys_getpid /* 20 */
.long sys_mount
@@ -436,7 +403,7 @@
.long sys_stime /* 25 */
.long sys_ptrace
.long sys_alarm
- .long sys_fstat
+ .long sys_ni_syscall /* old fstat syscall holder */
.long sys_pause
.long sys_utime /* 30 */
.long sys_ni_syscall /* old stty syscall holder */
@@ -467,7 +434,7 @@
.long sys_ni_syscall /* old mpx syscall holder */
.long sys_setpgid
.long sys_ni_syscall /* old ulimit syscall holder */
- .long sys_olduname
+ .long sys_ni_syscall /* old uname syscall holder */
.long sys_umask /* 60 */
.long sys_chroot
.long sys_ustat
@@ -476,8 +443,8 @@
.long sys_getpgrp /* 65 */
.long sys_setsid
.long sys_sigaction
- .long sys_sgetmask
- .long sys_ssetmask
+ .long sys_ni_syscall /* old sgetmask syscall holder */
+ .long sys_ni_syscall /* old ssetmask syscall holder */
.long sys_setreuid /* 70 */
.long sys_setregid
.long sys_sigsuspend_glue
@@ -490,9 +457,9 @@
.long sys_settimeofday
.long sys_getgroups /* 80 */
.long sys_setgroups
- .long old_select
+ .long sys_ni_syscall /* old select syscall holder */
.long sys_symlink
- .long sys_lstat
+ .long sys_ni_syscall /* old lstat syscall holder */
.long sys_readlink /* 85 */
.long sys_uselib
.long sys_swapon
@@ -517,7 +484,7 @@
.long sys_newstat
.long sys_newlstat
.long sys_newfstat
- .long sys_uname
+ .long sys_ni_syscall /* old uname syscall holder */
.long sys_ni_syscall /* 110 */ /* iopl for i386 */
.long sys_vhangup
.long sys_idle
@@ -599,22 +566,14 @@
.long sys_ni_syscall /* streams1 */
.long sys_ni_syscall /* streams2 */
.long sys_vfork_glue /* 190 */
- .rept 254-190
+ .rept 255-190
.long sys_ni_syscall
.endr
- .long sys_msgcp /* 255 */
/*
* Program check handler routine
*/
-pgm_lit:
- pgm_handle_per: .long handle_per_exception
- pgm_jump_table: .long pgm_check_table
- pgm_sysc_ret: .long sysc_return
- pgm_sysc_lit: .long sysc_lit
- pgm_do_signal: .long do_signal
-
.globl pgm_check_handler
pgm_check_handler:
/*
@@ -630,115 +589,132 @@
* we just ignore the PER event (FIXME: is there anything we have to do
* for LPSW?).
*/
+
+ 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 __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
- jz pgm_sv # skip if not
+ bz BASED(pgm_sv) # skip if not
tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
- jnz pgm_sv # skip if it is
+ bnz BASED(pgm_sv) # skip if it is
# ok its one of the special cases, now we need to find out which one
clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
- je pgm_svcper
+ be BASED(pgm_svcper)
# no interesting special case, ignore PER event
+ lm %r13,%r15,__LC_SAVE_AREA
lpsw 0x28
# it was a single stepped SVC that is causing all the trouble
pgm_svcper:
- SAVE_ALL(0x20)
+ tm 0x21,0x01 # test problem state bit
+ bz BASED(.+12) # skip stack & access regs setup
+ 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
+ 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),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
- j pgm_system_call # now do the svc
+ b BASED(pgm_system_call) # now do the svc
pgm_svcret:
- mvc __LC_PGM_ILC(4),SP_PGM_OLD_ILC(%r15) # restore program check info
- lhi %r0,0x28
- st %r0,SP_TRAP(%r15) # set new trap indicator
- j pgm_no_sv
+ 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)
+ b BASED(pgm_no_sv)
pgm_sv:
- SAVE_ALL(0x28)
-pgm_no_sv:
- XC SP_SVC_STEP(4,%r15),SP_SVC_STEP(%r15)
- basr %r13,0
- ahi %r13,pgm_lit-. # setup base pointer R13 to $PGMDAT
+ tm 0x29,0x01 # test problem state bit
+ bz BASED(.+12) # skip stack & access regs setup
+ 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
+ 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),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
+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
- lhi %r0,0x7f
+ la %r0,0x7f
nr %r3,%r0 # clear per-event-bit
- je pgm_dn # none of Martins exceptions occured bypass
- l %r9,pgm_jump_table-pgm_lit(%r13)
+ be BASED(pgm_dn) # none of Martins exceptions occured bypass
+ l %r9,BASED(.Ljump_table)
sll %r3,2
l %r9,0(%r3,%r9) # load address of handler routine
la %r2,SP_PTREGS(%r15) # address of register-save area
srl %r3,2
- chi %r3,0x4 # protection-exception ?
- jne pgm_go # if not,
+ cl %r3,BASED(.Lc4) # protection-exception ?
+ bne BASED(pgm_go) # if not,
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_dn: lhi %r0,0x80
+pgm_dn: la %r0,0x80
nr %r8,%r0 # check for per exception
- je pgm_return
+ be BASED(pgm_return)
la %r2,SP_PTREGS(15) # address of register-save area
- l %r9,pgm_handle_per-pgm_lit(%r13) # load adr. of per handler
- l %r14,pgm_sysc_ret-pgm_lit(%r13) # load adr. of system return
- l %r13,pgm_sysc_lit-pgm_lit(%r13)
+ l %r9,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
#
# the backend code is the same as for sys-call
#
pgm_return:
- l %r14,pgm_sysc_ret-pgm_lit(%r13)
- l %r13,pgm_sysc_lit-pgm_lit(%r13)
- br %r14
-
-default_trap_handler:
- .globl default_trap_handler
- lpsw 112
+ b BASED(sysc_return)
/*
* IO interrupt handler routine
*/
-io_lit:
- io_do_IRQ: .long do_IRQ
- io_schedule: .long schedule
- io_do_signal: .long do_signal
- io_bhmask: .long bh_mask
- io_bhactive: .long bh_active
- io_do_bottom_half:.long do_bottom_half
-
.globl io_int_handler
io_int_handler:
SAVE_ALL(0x38)
- basr %r13,0
- ahi %r13,io_lit-. # setup base pointer R13 to $IODAT
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 interuption parm
- l %r9,io_do_IRQ-io_lit(%r13) # load address of do_IRQ
+ l %r9,BASED(.Ldo_IRQ) # load address of do_IRQ
basr %r14,%r9 # 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 ?
- jz io_leave # no-> skip resched & signal
+ bz BASED(io_leave) # no-> skip resched & signal
stosm 24(%r15),0x03 # reenable interrupts
#
# check, if bottom-half has to be done
#
- l %r1,io_bhmask-io_lit(%r13)
+ l %r1,BASED(.Lbhmask)
l %r0,0(%r1)
- l %r1,io_bhactive-io_lit(%r13)
+ l %r1,BASED(.Lbhactive)
n %r0,0(%r1)
- jnz io_handle_bottom_half
+ bnz BASED(io_handle_bottom_half)
io_return_bh:
#
# check, if reschedule is needed
#
icm %r0,15,need_resched(%r9) # get need_resched from task_struct
- jnz io_reschedule
+ bnz BASED(io_reschedule)
icm %r0,15,sigpending(%r9) # get sigpending from task_struct
- jnz io_signal_return
+ bnz BASED(io_signal_return)
io_leave:
stnsm 24(%r15),disable # disable I/O and ext. interrupts
RESTORE_ALL
@@ -748,16 +724,16 @@
# is zero
#
io_handle_bottom_half:
- l %r1,io_do_bottom_half-io_lit(%r13)
- la %r14,io_return_bh-io_lit(%r13)
+ l %r1,BASED(.Ldo_bottom_half)
+ la %r14,BASED(io_return_bh)
br %r1 # call do_bottom_half
#
# call schedule with io_return as return-address
#
io_reschedule:
- l %r1,io_schedule-io_lit(%r13)
- la %r14,io_return-io_lit(%r13)
+ l %r1,BASED(.Lschedule)
+ la %r14,BASED(io_return)
br %r1 # call scheduler, return to io_return
#
@@ -766,103 +742,48 @@
io_signal_return:
la %r2,SP_PTREGS(%r15) # load pt_regs
sr %r3,%r3 # clear *oldset
- l %r1,io_do_signal-io_lit(%r13)
- la %r14,io_leave-io_lit(%r13)
+ l %r1,BASED(.Ldo_signal)
+ la %r14,BASED(io_leave)
br %r1 # return point is io_leave
/*
* External interrupt handler routine
*/
-ext_lit:
- ext_timer_int: .long do_timer_interrupt
-#ifdef __SMP__
- ext_call_int: .long do_ext_call_interrupt
-#endif
-#ifdef CONFIG_HWC
- ext_hwc_int: .long do_hwc_interrupt
-#endif
-#ifdef CONFIG_MDISK
- ext_mdisk_int: .long do_mdisk_interrupt
-#endif
-#ifdef CONFIG_IUCV
- ext_iucv_int: .long do_iucv_interrupt
-#endif
- ext_io_lit: .long io_lit
- ext_io_return: .long io_return
-
.globl ext_int_handler
ext_int_handler:
SAVE_ALL(0x18)
- basr %r13,0
- ahi %r13,ext_lit-. # setup base pointer R13 to $EXTDAT
la %r2,SP_PTREGS(%r15) # address of register-save area
lh %r3,__LC_EXT_INT_CODE # error code
-#ifdef __SMP__
- chi %r3,0x1202 # EXTERNAL_CALL
- jne ext_no_extcall
- l %r9,ext_call_int-ext_lit(%r13) # load ext_call_interrupt
- l %r14,ext_io_return-ext_lit(%r13)
- l %r13,ext_io_lit-ext_lit(%r13)
- br %r9 # branch to ext call handler
-ext_no_extcall:
-#endif
- chi %r3,0x1004 # CPU_TIMER
- jne ext_no_timer
- l %r9,ext_timer_int-ext_lit(%r13) # load timer_interrupt
- l %r14,ext_io_return-ext_lit(%r13)
- l %r13,ext_io_lit-ext_lit(%r13)
- br %r9 # branch to ext call handler
-ext_no_timer:
-#ifdef CONFIG_HWC
- chi %r3,0x2401 # HWC interrupt
- jne ext_no_hwc
- l %r9,ext_hwc_int-ext_lit(%r13) # load addr. of hwc routine
- l %r14,ext_io_return-ext_lit(%r13)
- l %r13,ext_io_lit-ext_lit(%r13)
+ lr %r1,%r3 # calculate index
+ srl %r1,8 # = (code + (code >> 8)) & 0xff
+ alr %r1,%r3
+ 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 ?
+ bz BASED(io_return) # yes, nothing to do, exit
+ext_int_loop:
+ ch %r3,8(%r9) # compare external interrupt code
+ be BASED(ext_int_found)
+ icm %r9,15,0(%r9) # next list entry
+ bnz BASED(ext_int_loop)
+ b BASED(io_return)
+ext_int_found:
+ l %r9,4(%r9) # get handler address
+ la %r14,BASED(io_return)
br %r9 # branch to ext call handler
-ext_no_hwc:
-#endif
-#ifdef CONFIG_MDISK
- chi %r3,0x2603 # diag 250 (VM) interrupt
- jne ext_no_mdisk
- l %r9,ext_mdisk_int-ext_lit(%r13)
- l %r14,ext_io_return-ext_lit(%r13)
- l %r13,ext_io_lit-ext_lit(%r13)
- br %r9 # branch to ext call handler
-ext_no_mdisk:
-#endif
-#ifdef CONFIG_IUCV
- chi %r3,0x4000 # diag 250 (VM) interrupt
- jne ext_no_iucv
- l %r9,ext_iucv_int-ext_lit(%r13)
- l %r14,ext_io_return-ext_lit(%r13)
- l %r13,ext_io_lit-ext_lit(%r13)
- br %r9 # branch to ext call handler
-ext_no_iucv:
-#endif
-
- l %r14,ext_io_return-ext_lit(%r13)
- l %r13,ext_io_lit-ext_lit(%r13)
- br %r14 # use backend code of io_int_handler
/*
* Machine check handler routines
*/
-mcck_lit:
- mcck_crw_pending: .long do_crw_pending
-
.globl mcck_int_handler
mcck_int_handler:
SAVE_ALL(0x30)
- basr %r13,0
- ahi %r13,mcck_lit-. # setup base pointer R13 to $MCCKDAT
- tm __LC_MCCK_CODE+1,0x40
- jno mcck_no_crw
- l %r1,mcck_crw_pending-mcck_lit(%r13)
- basr %r14,%r1 # call do_crw_pending
-mcck_no_crw:
+ l %r1,BASED(.Ls390_mcck)
+ basr %r14,%r1 # call machine check handler
mcck_return:
RESTORE_ALL
@@ -877,11 +798,11 @@
lam %a0,%a15,__LC_AREGS_SAVE_AREA
stosm 0(%r15),daton # now we can turn dat on
lm %r6,%r15,24(%r15) # load registers from clone
- bras %r14,restart_go
- .long start_secondary
-restart_go:
- l %r14,0(%r14)
+ basr %r14,0
+ l %r14,restart_addr-.(%r14)
br %r14 # branch to start_secondary
+restart_addr:
+ .long start_secondary
#else
/*
* If we do not run with SMP enabled, let the new CPU crash ...
@@ -898,8 +819,49 @@
#endif
+/*
+ * Integer constants
+ */
+ .align 4
+.Lc0xfffffff8: .long -8 # to align stack pointer to 8
+.Lc0xffffe000: .long -8192 # to round stack pointer to &task_struct
+.Lc8191: .long 8191
+.Lc_spsize: .long SP_SIZE
+.Lc_ac: .long 0,0,1
+.Lc_ENOSYS: .long -ENOSYS
+.Lc4: .long 4
+.Lc0x1202: .long 0x1202
+.Lc0x1004: .long 0x1004
+.Lc0x2401: .long 0x2401
+.Lc0x4000: .long 0x4000
+.Lc0xff: .long 0xff
+/*
+ * Symbol constants
+ */
+.Lbhactive: .long bh_active
+.Lbhmask: .long bh_mask
+.Ls390_mcck: .long s390_do_machine_check
+.Ldo_IRQ: .long do_IRQ
+.Ldo_bottom_half:
+ .long do_bottom_half
+.Ldo_signal: .long do_signal
+.Lentry_base: .long entry_base
+.Lext_hash: .long ext_int_hash
+.Lhandle_per: .long handle_per_exception
+.Ljump_table: .long pgm_check_table
+.Lschedule: .long schedule
+.Lclone: .long sys_clone
+.Lexecve: .long sys_execve
+.Lfork: .long sys_fork
+.Lrt_sigreturn:.long sys_rt_sigreturn
+.Lrt_sigsuspend:
+ .long sys_rt_sigsuspend
+.Lsigreturn: .long sys_sigreturn
+.Lsigsuspend: .long sys_sigsuspend
+.Ltrace: .long syscall_trace
+.Lvfork: .long sys_vfork
-
-
-
+#ifdef __SMP__
+.Lschedtail: .long schedule_tail
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)