#include "assym.h"
#include <sys/syscall.h>
#include <sh/asm.h>
#include <sh/locore.h>
#include <sh/param.h>
#include <sh/mmu_sh3.h>
#include <sh/mmu_sh4.h>
#define SAVEPCB(reg) \
add #SF_SIZE, reg ; \
sts.l mach, @-##reg ; \
sts.l macl, @-##reg ; \
stc.l r7_bank,@-##reg ; \
stc.l sr, @-##reg ; \
stc.l r6_bank,@-##reg ; \
sts.l pr, @-##reg ; \
mov.l r8, @-##reg ; \
mov.l r9, @-##reg ; \
mov.l r10, @-##reg ; \
mov.l r11, @-##reg ; \
mov.l r12, @-##reg ; \
mov.l r13, @-##reg ; \
mov.l r14, @-##reg ; \
mov.l r15, @-##reg
#define SAVEFP(reg, tmp, tmp2) \
add #124, reg ; \
sts fpscr, tmp2 ; \
add #(FP_SIZE - 124), reg ; \
mov #0, tmp; \
mov.l tmp2, @-##reg ; \
lds tmp, fpscr; \
sts.l fpul, @-##reg ; \
frchg; \
fmov.s fr15, @-##reg ; \
fmov.s fr14, @-##reg ; \
fmov.s fr13, @-##reg ; \
fmov.s fr12, @-##reg ; \
fmov.s fr11, @-##reg ; \
fmov.s fr10, @-##reg ; \
fmov.s fr9, @-##reg ; \
fmov.s fr8, @-##reg ; \
fmov.s fr7, @-##reg ; \
fmov.s fr6, @-##reg ; \
fmov.s fr5, @-##reg ; \
fmov.s fr4, @-##reg ; \
fmov.s fr3, @-##reg ; \
fmov.s fr2, @-##reg ; \
fmov.s fr1, @-##reg ; \
fmov.s fr0, @-##reg ; \
frchg; \
fmov.s fr15, @-##reg ; \
fmov.s fr14, @-##reg ; \
fmov.s fr13, @-##reg ; \
fmov.s fr12, @-##reg ; \
fmov.s fr11, @-##reg ; \
fmov.s fr10, @-##reg ; \
fmov.s fr9, @-##reg ; \
fmov.s fr8, @-##reg ; \
fmov.s fr7, @-##reg ; \
fmov.s fr6, @-##reg ; \
fmov.s fr5, @-##reg ; \
fmov.s fr4, @-##reg ; \
fmov.s fr3, @-##reg ; \
fmov.s fr2, @-##reg ; \
fmov.s fr1, @-##reg ; \
fmov.s fr0, @-##reg ; \
lds tmp2, fpscr
#define LOADFP(reg, tmp) \
mov #0, tmp; \
lds tmp, fpscr; \
fmov.s @##reg##+, fr0 ; \
fmov.s @##reg##+, fr1 ; \
fmov.s @##reg##+, fr2 ; \
fmov.s @##reg##+, fr3 ; \
fmov.s @##reg##+, fr4 ; \
fmov.s @##reg##+, fr5 ; \
fmov.s @##reg##+, fr6 ; \
fmov.s @##reg##+, fr7 ; \
fmov.s @##reg##+, fr8 ; \
fmov.s @##reg##+, fr9 ; \
fmov.s @##reg##+, fr10 ; \
fmov.s @##reg##+, fr11 ; \
fmov.s @##reg##+, fr12 ; \
fmov.s @##reg##+, fr13 ; \
fmov.s @##reg##+, fr14 ; \
fmov.s @##reg##+, fr15 ; \
frchg; \
fmov.s @##reg##+, fr0 ; \
fmov.s @##reg##+, fr1 ; \
fmov.s @##reg##+, fr2 ; \
fmov.s @##reg##+, fr3 ; \
fmov.s @##reg##+, fr4 ; \
fmov.s @##reg##+, fr5 ; \
fmov.s @##reg##+, fr6 ; \
fmov.s @##reg##+, fr7 ; \
fmov.s @##reg##+, fr8 ; \
fmov.s @##reg##+, fr9 ; \
fmov.s @##reg##+, fr10 ; \
fmov.s @##reg##+, fr11 ; \
fmov.s @##reg##+, fr12 ; \
fmov.s @##reg##+, fr13 ; \
fmov.s @##reg##+, fr14 ; \
fmov.s @##reg##+, fr15 ; \
lds.l @##reg##+, fpul ; \
lds.l @##reg##+, fpscr
.text
.align 5
ENTRY(cpu_switchto)
mov r4, r0
cmp/eq #0, r0
bt 1f
mov.l .L_SF, r0
mov.l @(r0, r4), r1
SAVEPCB(r1)
add #PCB_FP, r1
SAVEFP(r1, r8, r9)
1:
mov.l .L_cpu_switch_prepare, r0
jsr @r0
mov r5, r8
mov r8, r4
mov.l .L_SF, r0
mov.l @(r0, r4), r1
mov.l @(SF_R7_BANK, r1), r0
mov.l @(SF_R6_BANK, r1), r2
mov.l @(SF_R15, r1), r3
__EXCEPTION_BLOCK(r1, r5)
ldc r0, r7_bank
ldc r2, r6_bank
mov r3, r15
MOV (switch_resume, r0)
jsr @r0
mov r4, r8
mov r8, r4
__EXCEPTION_UNBLOCK(r0, r1)
mov.l .L_SF, r0
mov.l @(r0, r4), r1
add #4, r1
mov.l @r1+, r14
mov.l @r1+, r13
mov.l @r1+, r12
mov.l @r1+, r11
mov.l @r1+, r10
mov.l @r1+, r9
mov.l @r1+, r8
lds.l @r1+, pr
add #4, r1
ldc.l @r1+, sr
add #4, r1
lds.l @r1+, macl
lds.l @r1+, mach
mov.l @(r0, r4), r1
add #PCB_FP, r1
LOADFP(r1, r0)
rts
nop
.align 2
.L_SF: .long (P_MD_PCB)
.L_cpu_switch_prepare: .long cpu_switch_prepare
FUNC_SYMBOL(switch_resume)
#ifdef SH3
NENTRY(sh3_switch_resume)
mov.l .L_UPTE, r0
mov.l .L_curupte, r1
add r4, r0
rts
mov.l r0, @r1
.align 2
.L_UPTE: .long P_MD_UPTE
.L_curupte: .long curupte
SET_ENTRY_SIZE(sh3_switch_resume)
#endif
#ifdef SH4
NENTRY(sh4_switch_resume)
mov.l .L_UPTE__sh4, r0
add r0, r4
mov #UPAGES,r3
mov #1, r2
mov.l @r4, r0
tst r0, r0
bt 2f
xor r0, r0
mov.l .L_4_PTEH, r1
mov.l @r1, r7
mov.l r0, @r1
mov.l .L_VPN_MASK, r6
mov.l .L_4_UTLB_AA_A, r5
mova 1f, r0
mov.l .L_P2BASE, r1
or r1, r0
jmp @r0
nop
.align 2
1: mov.l @(4, r4), r0
and r6, r0
mov.l r0, @r5
mov.l @r4+, r0
mov.l @r4+, r1
mov.l r1, @r0
mov.l @r4+, r0
mov.l @r4+, r1
mov.l r1, @r0
cmp/eq r2, r3
bf/s 1b
add #1, r2
mov.l .L_4_PTEH, r0
mov.l r7, @r0
mova 2f, r0
jmp @r0
nop
.align 2
2: rts
nop
.align 2
.L_UPTE__sh4: .long P_MD_UPTE
.L_4_PTEH: .long SH4_PTEH
.L_4_UTLB_AA_A: .long (SH4_UTLB_AA | SH4_UTLB_A)
.L_4_ITLB_AA: .long SH4_ITLB_AA
.L_VPN_MASK: .long 0xfffff000
.L_P2BASE: .long 0xa0000000
SET_ENTRY_SIZE(sh4_switch_resume)
#endif
NENTRY(_cpu_intr_raise)
stc sr, r2
mov #0x78, r1
mov r2, r0
shll r1
and r1, r0
cmp/ge r4, r0
bt/s 1f
not r1, r1
and r1, r2
or r2, r4
ldc r4, sr
1: rts
nop
SET_ENTRY_SIZE(_cpu_intr_raise)
NENTRY(_cpu_intr_suspend)
stc sr, r0
mov #0x78, r1
shll r1
mov r0, r2
or r1, r2
ldc r2, sr
rts
and r1, r0
SET_ENTRY_SIZE(_cpu_intr_suspend)
NENTRY(_cpu_intr_resume)
stc sr, r0
mov #0x78, r2
shll r2
not r2, r1
and r0, r1
or r1, r4
ldc r4, sr
rts
and r2, r0
SET_ENTRY_SIZE(_cpu_intr_resume)
NENTRY(_cpu_exception_suspend)
stc sr, r0
mov #0x10, r1
swap.b r1, r1
mov r0, r2
swap.w r1, r1
or r1, r2
ldc r2, sr
rts
and r1, r0
SET_ENTRY_SIZE(_cpu_exception_suspend)
NENTRY(_cpu_exception_resume)
stc sr, r0
mov #0x10, r1
swap.b r1, r1
swap.w r1, r1
not r1, r1
and r1, r0
or r4, r0
ldc r0, sr
rts
nop
SET_ENTRY_SIZE(_cpu_exception_resume)
.align 5
NENTRY(_cpu_spin)
1: nop
nop
nop
add #-1, r4
nop
cmp/pl r4
nop
bt 1b
rts
nop
SET_ENTRY_SIZE(_cpu_spin)
NENTRY(proc_trampoline)
mov.l .L_proc_trampoline_mi, r1
jsr @r1
nop
jsr @r12
mov r11, r4
__EXCEPTION_RETURN
.L_proc_trampoline_mi:
.long proc_trampoline_mi
SET_ENTRY_SIZE(proc_trampoline)
NENTRY(sigcode)
mov r15, r4
mov.l .L_SYS_sigreturn, r0
.globl sigcodecall
sigcodecall:
trapa #0x80
.globl sigcoderet
sigcoderet:
sleep
.align 2
.L_SYS_sigreturn: .long SYS_sigreturn
.globl esigcode
esigcode:
SET_ENTRY_SIZE(sigcode)
.globl sigfill
sigfill:
sleep
esigfill:
.data
.globl sigfillsiz
sigfillsiz:
.word esigfill - sigfill
.text
ENTRY(savectx)
SAVEPCB(r4)
add #PCB_FP, r4
SAVEFP(r4, r0, r1)
rts
nop
SET_ENTRY_SIZE(savectx)
ENTRY(fpu_save)
SAVEFP(r4, r0, r1)
rts
nop
SET_ENTRY_SIZE(fpu_save)
ENTRY(fpu_restore)
LOADFP(r4, r0)
rts
nop
SET_ENTRY_SIZE(fpu_restore)
ENTRY(copyout)
mov.l r14, @-r15
sts.l pr, @-r15
mov r15, r14
mov #EFAULT, r0
mov r4, r3
mov r5, r2
mov r5, r4
add r6, r2
cmp/hs r5, r2
bf 2f
mov.l .L_copyout_VM_MAXUSER_ADDRESS, r1
cmp/hi r1, r2
bt 2f
mov.l .L_copyout_curpcb, r1
mov.l @r1, r2
mov.l .L_copyout_onfault, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov.l .L_copyout_memcpy, r1
jsr @r1
mov r3, r5
mov #0, r0
1:
mov.l .L_copyout_curpcb, r1
mov.l @r1, r2
mov #0, r1
mov.l r1, @(PCB_ONFAULT,r2)
2:
mov r14, r15
lds.l @r15+, pr
rts
mov.l @r15+, r14
3:
bra 1b
mov #EFAULT, r0
.align 2
.L_copyout_onfault:
.long 3b
.L_copyout_VM_MAXUSER_ADDRESS:
.long VM_MAXUSER_ADDRESS
.L_copyout_curpcb:
.long curpcb
.L_copyout_memcpy:
.long memcpy
SET_ENTRY_SIZE(copyout)
ENTRY(_copyin)
mov.l r14, @-r15
sts.l pr, @-r15
mov r15, r14
mov #EFAULT, r0
mov r4, r3
mov r5, r4
mov r3, r2
add r6, r2
cmp/hs r3, r2
bf 2f
mov.l .L_copyin_VM_MAXUSER_ADDRESS, r1
cmp/hi r1, r2
bt 2f
mov.l .L_copyin_curpcb, r1
mov.l @r1, r2
mov.l .L_copyin_onfault, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov.l .L_copyin_memcpy, r1
jsr @r1
mov r3, r5
mov #0, r0
1:
mov.l .L_copyin_curpcb, r1
mov.l @r1, r2
mov #0, r1
mov.l r1, @(PCB_ONFAULT,r2)
2:
mov r14, r15
lds.l @r15+, pr
rts
mov.l @r15+, r14
3:
bra 1b
mov #EFAULT, r0
.align 2
.L_copyin_onfault:
.long 3b
.L_copyin_VM_MAXUSER_ADDRESS:
.long VM_MAXUSER_ADDRESS
.L_copyin_curpcb:
.long curpcb
.L_copyin_memcpy:
.long memcpy
SET_ENTRY_SIZE(_copyin)
ENTRY(copyin32)
mov.l r14, @-r15
sts.l pr, @-r15
mov r15, r14
mov #3, r3
mov #EFAULT, r0
and r4, r3
tst r3, r3
bf 2f
mov.l .L_copyin32_VM_MAXUSER_ADDRESS, r1
cmp/hi r1, r4
bt 2f
mov.l .L_copyin32_curpcb, r1
mov.l @r1, r2
mov.l .L_copyin32_onfault, r3
mov.l r3, @(PCB_ONFAULT,r2)
mov.l @r4, r1
mov #0, r0
mov.l r1, @r5
mov.l r0, @(PCB_ONFAULT,r2)
2:
mov r14, r15
lds.l @r15+, pr
rts
mov.l @r15+, r14
3:
mov.l .L_copyin32_curpcb, r1
mov.l @r1, r2
mov #0, r1
mov.l r1, @(PCB_ONFAULT,r2)
bra 2b
mov #EFAULT, r0
.align 2
.L_copyin32_onfault:
.long 3b
.L_copyin32_VM_MAXUSER_ADDRESS:
.long VM_MAXUSER_ADDRESS - 4
.L_copyin32_curpcb:
.long curpcb
SET_ENTRY_SIZE(copyin32)
ENTRY(copyoutstr)
mov.l r8, @-r15
mov #EFAULT, r3
mov r4, r8
mov.l .L_copyoutstr_curpcb, r1
mov.l @r1, r2
mov.l .L_copyoutstr_onfault, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov.l .L_copyoutstr_VM_MAXUSER_ADDRESS, r1
cmp/hi r1, r5
bt 4f
mov r1, r0
sub r5, r0
cmp/hi r6, r0
bf 2f
bra 2f
mov r6, r0
.align 2
1:
mov.b @r4+, r1
mov.b r1, @r5
extu.b r1, r1
add #1, r5
tst r1, r1
bf 2f
bra 3f
mov #0, r3
.align 2
2:
add #-1, r0
cmp/eq #-1, r0
bf 1b
mov.l .L_copyoutstr_VM_MAXUSER_ADDRESS, r1
cmp/hs r1, r5
bt 3f
mov #ENAMETOOLONG, r3
3:
tst r7, r7
bt 4f
mov r4, r1
sub r8, r1
mov.l r1, @r7
4:
mov.l .L_copyoutstr_curpcb, r1
mov.l @r1, r2
mov #0, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov r3, r0
rts
mov.l @r15+, r8
5:
bra 4b
mov #EFAULT, r3
.align 2
.L_copyoutstr_onfault:
.long 5b
.L_copyoutstr_VM_MAXUSER_ADDRESS:
.long VM_MAXUSER_ADDRESS
.L_copyoutstr_curpcb:
.long curpcb
SET_ENTRY_SIZE(copyoutstr)
ENTRY(_copyinstr)
mov.l r8, @-r15
mov #EFAULT, r3
mov r4, r8
mov.l .L_copyinstr_curpcb, r1
mov.l @r1, r2
mov.l .L_copyinstr_onfault, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov.l .L_copyinstr_VM_MAXUSER_ADDRESS, r1
cmp/hi r1, r4
bt 4f
mov r1, r0
sub r4, r0
cmp/hi r6, r0
bf 2f
bra 2f
mov r6, r0
.align 2
1:
mov.b @r4+, r1
mov.b r1, @r5
extu.b r1, r1
add #1, r5
tst r1, r1
bf 2f
bra 3f
mov #0, r3
.align 2
2:
add #-1, r0
cmp/eq #-1, r0
bf 1b
mov.l .L_copyinstr_VM_MAXUSER_ADDRESS, r1
cmp/hs r1, r4
bt 3f
mov #ENAMETOOLONG, r3
3:
tst r7, r7
bt 4f
mov r4, r1
sub r8, r1
mov.l r1, @r7
4:
mov.l .L_copyinstr_curpcb, r1
mov.l @r1, r2
mov #0, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov r3, r0
rts
mov.l @r15+, r8
5:
bra 4b
mov #EFAULT, r3
.align 2
.L_copyinstr_onfault:
.long 5b
.L_copyinstr_VM_MAXUSER_ADDRESS:
.long VM_MAXUSER_ADDRESS
.L_copyinstr_curpcb:
.long curpcb
SET_ENTRY_SIZE(_copyinstr)
ENTRY(kcopy)
mov.l r8, @-r15
mov.l r14, @-r15
sts.l pr, @-r15
mov r15, r14
mov r4, r3
mov.l .L_kcopy_curpcb, r1
mov.l @r1, r2
mov.l @(PCB_ONFAULT,r2) ,r8
mov.l .L_kcopy_onfault, r1
mov.l r1, @(PCB_ONFAULT,r2)
mov.l .L_kcopy_memcpy, r1
mov r5, r4
jsr @r1
mov r3, r5
mov #0, r0
1:
mov.l .L_kcopy_curpcb, r1
mov.l @r1, r2
mov.l r8, @(PCB_ONFAULT,r2)
mov r14, r15
lds.l @r15+, pr
mov.l @r15+, r14
rts
mov.l @r15+, r8
2:
bra 1b
mov #EFAULT, r0
.align 2
.L_kcopy_onfault:
.long 2b
.L_kcopy_curpcb:
.long curpcb
.L_kcopy_memcpy:
.long memcpy
SET_ENTRY_SIZE(kcopy)
#if defined(DDB)
ENTRY(setjmp)
add #4*9, r4
mov.l r8, @-r4
mov.l r9, @-r4
mov.l r10, @-r4
mov.l r11, @-r4
mov.l r12, @-r4
mov.l r13, @-r4
mov.l r14, @-r4
mov.l r15, @-r4
sts.l pr, @-r4
rts
xor r0, r0
SET_ENTRY_SIZE(setjmp)
ENTRY(longjmp)
lds.l @r4+, pr
mov.l @r4+, r15
mov.l @r4+, r14
mov.l @r4+, r13
mov.l @r4+, r12
mov.l @r4+, r11
mov.l @r4+, r10
mov.l @r4+, r9
mov.l @r4+, r8
rts
mov #1, r0
SET_ENTRY_SIZE(longjmp)
#endif