#include <linux/sys.h>
#include <linux/linkage.h>
+#include <linux/config.h>
#include <asm/cache.h>
#include <asm/lowcore.h>
#include <asm/errno.h>
#define BASED(name) name-system_call(%r13)
-#ifdef CONFIG_TRACE_IRQFLAGS
- .macro TRACE_IRQS_ON
- l %r1,BASED(.Ltrace_irq_on)
- basr %r14,%r1
- .endm
-
- .macro TRACE_IRQS_OFF
- l %r1,BASED(.Ltrace_irq_off)
- basr %r14,%r1
- .endm
-#else
-#define TRACE_IRQS_ON
-#define TRACE_IRQS_OFF
-#endif
-
/*
* Register usage in interrupt handlers:
* R9 - pointer to current task structure
l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
.endm
- .macro SAVE_ALL_SYNC psworg,savearea
+ .macro SAVE_ALL psworg,savearea,sync
la %r12,\psworg
+ .if \sync
tm \psworg+1,0x01 # test problem state bit
bz BASED(2f) # skip stack setup save
l %r15,__LC_KERNEL_STACK # problem state -> load ksp
-#ifdef CONFIG_CHECK_STACK
- b BASED(3f)
-2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
- bz BASED(stack_overflow)
-3:
-#endif
-2:
- .endm
-
- .macro SAVE_ALL_ASYNC psworg,savearea
- la %r12,\psworg
+ .else
tm \psworg+1,0x01 # test problem state bit
bnz BASED(1f) # from user -> load async stack
clc \psworg+4(4),BASED(.Lcritical_end)
sra %r14,STACK_SHIFT
be BASED(2f)
1: l %r15,__LC_ASYNC_STACK
+ .endif
#ifdef CONFIG_CHECK_STACK
b BASED(3f)
2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
STORE_TIMER __LC_SYNC_ENTER_TIMER
sysc_saveall:
SAVE_ALL_BASE __LC_SAVE_AREA
- SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
lh %r7,0x8a # get svc number from lowcore
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
sysc_nr_ok:
mvc SP_ARGS(4,%r15),SP_R7(%r15)
sysc_do_restart:
- l %r8,BASED(.Lsysc_table)
tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
- l %r8,0(%r7,%r8) # get system call addr.
+ l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr.
bnz BASED(sysc_tracesys)
basr %r14,%r8 # call sys_xxxx
st %r2,SP_R2(%r15) # store return value (change R2 on stack)
basr %r14,%r1
clc SP_R2(4,%r15),BASED(.Lnr_syscalls)
bnl BASED(sysc_tracenogo)
- l %r8,BASED(.Lsysc_table)
l %r7,SP_R2(%r15) # strace might have changed the
sll %r7,2 # system call
- l %r8,0(%r7,%r8)
+ l %r8,sys_call_table-system_call(%r7,%r13)
sysc_tracego:
lm %r3,%r6,SP_R3(%r15)
l %r2,SP_ORIG_R2(%r15)
st %r15,SP_R15(%r15) # store stack pointer for new kthread
0: l %r1,BASED(.Lschedtail)
basr %r14,%r1
- TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
b BASED(sysc_return)
SAVE_ALL_BASE __LC_SAVE_AREA
tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
bnz BASED(pgm_per) # got per exception -> special case
- SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
# Normal per exception
#
pgm_per_std:
- SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
# it was a single stepped SVC that is causing all the trouble
#
pgm_svcper:
- SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
- TRACE_IRQS_ON
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
b BASED(sysc_do_svc)
STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+16
- SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
+ SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
io_no_vtime:
#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- TRACE_IRQS_OFF
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler
- TRACE_IRQS_ON
io_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+16
- SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
+ SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm SP_PSW+1(%r15),0x01 # interrupting from user ?
ext_no_vtime:
#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- TRACE_IRQS_OFF
la %r2,SP_PTREGS(%r15) # address of register-save area
lh %r3,__LC_EXT_INT_CODE # get interruption code
l %r1,BASED(.Ldo_extint)
basr %r14,%r1
- TRACE_IRQS_ON
b BASED(io_return)
__critical_end:
.globl mcck_int_handler
mcck_int_handler:
spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
+ mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
SAVE_ALL_BASE __LC_SAVE_AREA+32
la %r12,__LC_MCK_OLD_PSW
tm __LC_MCCK_CODE,0x80 # system damage?
bo BASED(mcck_int_main) # yes -> rest of mcck code invalid
+ tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
+ bo BASED(0f)
+ spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
- mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
- tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
- bo BASED(1f)
- la %r14,__LC_SYNC_ENTER_TIMER
- clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
- bl BASED(0f)
- la %r14,__LC_ASYNC_ENTER_TIMER
-0: clc 0(8,%r14),__LC_EXIT_TIMER
- bl BASED(0f)
- la %r14,__LC_EXIT_TIMER
-0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
- bl BASED(0f)
- la %r14,__LC_LAST_UPDATE_TIMER
-0: spt 0(%r14)
- mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
-1:
+ mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
+ mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
+ mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
#endif
- tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
+0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
bno BASED(mcck_int_main) # no -> skip cleanup critical
tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
bnz BASED(mcck_int_main) # from user -> load async stack
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
bno BASED(mcck_no_vtime) # no -> skip cleanup critical
- tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
bz BASED(mcck_no_vtime)
UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
stosm __SF_EMPTY(%r15),0x04 # turn dat on
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
bno BASED(mcck_return)
- TRACE_IRQS_OFF
l %r1,BASED(.Ls390_handle_mcck)
basr %r14,%r1 # call machine check handler
- TRACE_IRQS_ON
mcck_return:
- mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
- ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52
- tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
- bno BASED(0f)
- lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
- stpt __LC_EXIT_TIMER
- lpsw __LC_RETURN_MCCK_PSW # back to caller
-0:
-#endif
- lm %r0,%r15,SP_R0(%r15) # load gprs 0-15
- lpsw __LC_RETURN_MCCK_PSW # back to caller
-
RESTORE_ALL __LC_RETURN_MCCK_PSW,0
#ifdef CONFIG_SMP
.long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
cleanup_table_sysc_work_loop:
.long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
-cleanup_table_io_return:
- .long io_return + 0x80000000, io_leave + 0x80000000
cleanup_table_io_leave:
.long io_leave + 0x80000000, io_done + 0x80000000
cleanup_table_io_work_loop:
bl BASED(0f)
clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
bl BASED(cleanup_sysc_return)
-0:
- clc 4(4,%r12),BASED(cleanup_table_io_return)
- bl BASED(0f)
- clc 4(4,%r12),BASED(cleanup_table_io_return+4)
- bl BASED(cleanup_io_return)
0:
clc 4(4,%r12),BASED(cleanup_table_io_leave)
bl BASED(0f)
mvc __LC_SAVE_AREA(16),0(%r12)
0: st %r13,4(%r12)
st %r12,__LC_SAVE_AREA+48 # argh
- SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+ SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
l %r12,__LC_SAVE_AREA+48 # argh
st %r15,12(%r12)
.Ltrace: .long syscall_trace
.Lvfork: .long sys_vfork
.Lschedtail: .long schedule_tail
-.Lsysc_table: .long sys_call_table
-#ifdef CONFIG_TRACE_IRQFLAGS
-.Ltrace_irq_on:.long trace_hardirqs_on
-.Ltrace_irq_off:
- .long trace_hardirqs_off
-#endif
+
.Lcritical_start:
.long __critical_start + 0x80000000
.Lcritical_end:
.Lcleanup_critical:
.long cleanup_critical
- .section .rodata, "a"
#define SYSCALL(esa,esame,emu) .long esa
+ .globl sys_call_table
sys_call_table:
#include "syscalls.S"
#undef SYSCALL
+