#include "opt_fpu_emulate.h"
#include "opt_lockdebug.h"
#include "opt_pmap_debug.h"
#include "opt_m68k_arch.h"
#include <machine/asm.h>
#include "assym.h"
.file "switch_subr.s"
.text
.data
GLOBAL(curpcb)
GLOBAL(masterpaddr) | XXXcompatibility (debuggers)
.long 0
ASENTRY_NOPROFILE(cpu_idle)
stop #PSL_LOWIPL
GLOBAL(_Idle)
rts
ENTRY(cpu_switchto)
movl 4(%sp),%a1 | fetch outgoing lwp
movl L_PCB(%a1),%a1
moveml %d2-%d7/%a2-%a7,PCB_REGS(%a1) | save non-scratch registers
movl %usp,%a2 | grab USP (a2 has been saved)
movl %a2,PCB_USP(%a1) | and save it
#ifdef M68K_FPCOPROC
tstl _C_LABEL(fputype) | Do we have an FPU?
jeq .Lcpu_switch_nofpsave | No Then don't attempt save.
lea PCB_FPCTX(%a1),%a2 | pointer to FP save area
fsave (%a2) | save FP state
#if defined(M68020) || defined(M68030) || defined(M68040)
#if defined(M68060)
cmpl #FPU_68060,_C_LABEL(fputype)
jeq .Lcpu_switch_savfp60
#endif
tstb (%a2) | null state frame?
jeq .Lcpu_switch_nofpsave | yes, all done
fmovem %fp0-%fp7,FPF_REGS(%a2) | save FP general registers
fmovem %fpcr/%fpsr/%fpi,FPF_FPCR(%a2) | save FP control registers
#if defined(M68060)
jra .Lcpu_switch_nofpsave
#endif
#endif
#if defined(M68060)
.Lcpu_switch_savfp60:
tstb 2(%a2) | null state frame?
jeq .Lcpu_switch_nofpsave | yes, all done
fmovem %fp0-%fp7,FPF_REGS(%a2) | save FP general registers
fmovem %fpcr,FPF_FPCR(%a2) | save FP control registers
fmovem %fpsr,FPF_FPSR(%a2)
fmovem %fpi,FPF_FPI(%a2)
#endif
.Lcpu_switch_nofpsave:
#endif
movl 8(%sp),%a0 | get newlwp
movl %a0,_C_LABEL(curlwp) | curlwp = new lwp
movl L_PCB(%a0),%a1 | get its pcb
movl %a1,_C_LABEL(curpcb) | curpcb = new pcb
movl L_PROC(%a0),%a2
tstl P_RASLIST(%a2) | p->p_raslist == NULL?
jeq 2f | yes, skip it.
movl L_MD_REGS(%a0),%a1
movl TF_PC(%a1),-(%sp) | push return PC
movl %a2,-(%sp) | push proc
jbsr _C_LABEL(ras_lookup) | a0 = ras_lookup(p, pc)
addql #8,%sp
movql #-1,%d0
cmpl %a0,%d0 | a0 == -1?
jeq 1f | yes, skip it.
movl _C_LABEL(curlwp),%a1
movl L_MD_REGS(%a1),%a1
movl %a0,TF_PC(%a1) | fixup return PC
1:
movl _C_LABEL(curlwp),%a0 | recover new lwp
movl _C_LABEL(curpcb),%a1 | recover new pcb
2:
movl %a0,%d0 | free up %a0
movl 4(%sp),%d1 | get oldlwp for return value
lea _ASM_LABEL(tmpstk),%sp | switch to tmp stack in case of NMI
moveml PCB_REGS(%a1),%d2-%d7/%a2-%a7 | restore registers
movl PCB_USP(%a1),%a0
movl %a0,%usp | and USP
#ifdef M68K_FPCOPROC
tstl _C_LABEL(fputype) | Do we have an FPU?
jeq .Lcpu_switch_nofprest | No Then don't attempt restore.
lea PCB_FPCTX(%a1),%a0 | pointer to FP save area
#if defined(M68020) || defined(M68030) || defined(M68040)
#if defined(M68060)
cmpl #FPU_68060,_C_LABEL(fputype)
jeq .Lcpu_switch_resfp60rest1
#endif
tstb (%a0) | null state frame?
jeq .Lcpu_switch_resfprest | yes, easy
fmovem FPF_FPCR(%a0),%fpcr/%fpsr/%fpi | restore FP control registers
fmovem FPF_REGS(%a0),%fp0-%fp7 | restore FP general registers
#if defined(M68060)
jra .Lcpu_switch_resfprest
#endif
#endif
#if defined(M68060)
.Lcpu_switch_resfp60rest1:
tstb 2(%a0) | null state frame?
jeq .Lcpu_switch_resfprest | yes, easy
fmovem FPF_FPCR(%a0),%fpcr | restore FP control registers
fmovem FPF_FPSR(%a0),%fpsr
fmovem FPF_FPI(%a0),%fpi
fmovem FPF_REGS(%a0),%fp0-%fp7 | restore FP general registers
#endif
.Lcpu_switch_resfprest:
frestore (%a0) | restore state
#endif
.Lcpu_switch_nofprest:
movl %d1,%d0 | return outgoing lwp
movl %d0,%a0 | (in a0, too)
rts
ENTRY(savectx)
movl 4(%sp),%a1
movw %sr,PCB_PS(%a1)
movl %usp,%a0 | grab USP
movl %a0,PCB_USP(%a1) | and save it
moveml %d2-%d7/%a2-%a7,PCB_REGS(%a1) | save non-scratch registers
#ifdef M68K_FPCOPROC
tstl _C_LABEL(fputype) | Do we have FPU?
jeq .Lsavectx_nofpsave | No? Then don't save state.
lea PCB_FPCTX(%a1),%a0 | pointer to FP save area
fsave (%a0) | save FP state
#if defined(M68020) || defined(M68030) || defined(M68040)
#if defined(M68060)
cmpl #FPU_68060,_C_LABEL(fputype)
jeq .Lsavectx_savfp60
#endif
tstb (%a0) | null state frame?
jeq .Lsavectx_nofpsave | yes, all done
fmovem %fp0-%fp7,FPF_REGS(%a0) | save FP general registers
fmovem %fpcr/%fpsr/%fpi,FPF_FPCR(%a0) | save FP control registers
#if defined(M68060)
jra .Lsavectx_nofpsave
#endif
#endif
#if defined(M68060)
.Lsavectx_savfp60:
tstb 2(%a0) | null state frame?
jeq .Lsavectx_nofpsave | yes, all done
fmovem %fp0-%fp7,FPF_REGS(%a0) | save FP general registers
fmovem %fpcr,FPF_FPCR(%a0) | save FP control registers
fmovem %fpsr,FPF_FPSR(%a0)
fmovem %fpi,FPF_FPI(%a0)
#endif
.Lsavectx_nofpsave:
#endif
moveq #0,%d0 | return 0
rts
#ifdef M68K_FPCOPROC
ENTRY(m68k_make_fpu_idle_frame)
clrl -(%sp)
fnop
frestore (%sp) | Effectively `resets' the FPU
fnop
fmove.d #0,%fp0
fnop
lea _C_LABEL(m68k_cached_fpu_idle_frame),%a0
fsave (%a0)
fnop
frestore (%sp)
fnop
addql #4,%sp
rts
ENTRY(m68881_save)
movl 4(%sp),%a0 | save area pointer
fsave (%a0) | save state
#if defined(M68020) || defined(M68030) || defined(M68040)
#if defined(M68060)
cmpl #FPU_68060,_C_LABEL(fputype)
jeq .Lm68060fpsave
#endif
.Lm68881fpsave:
tstb (%a0) | null state frame?
jeq .Lm68881sdone | yes, all done
fmovem %fp0-%fp7,FPF_REGS(%a0) | save FP general registers
fmovem %fpcr/%fpsr/%fpi,FPF_FPCR(%a0) | save FP control registers
.Lm68881sdone:
rts
#endif
#if defined(M68060)
.Lm68060fpsave:
tstb 2(%a0) | null state frame?
jeq .Lm68060sdone | yes, all done
fmovem %fp0-%fp7,FPF_REGS(%a0) | save FP general registers
fmovem %fpcr,FPF_FPCR(%a0) | save FP control registers
fmovem %fpsr,FPF_FPSR(%a0)
fmovem %fpi,FPF_FPI(%a0)
.Lm68060sdone:
rts
#endif
ENTRY(m68881_restore)
movl 4(%sp),%a0 | save area pointer
#if defined(M68020) || defined(M68030) || defined(M68040)
#if defined(M68060)
cmpl #FPU_68060,_C_LABEL(fputype)
jeq .Lm68060fprestore
#endif
.Lm68881fprestore:
tstb (%a0) | null state frame?
jeq .Lm68881rdone | yes, easy
fmovem FPF_FPCR(%a0),%fpcr/%fpsr/%fpi | restore FP control registers
fmovem FPF_REGS(%a0),%fp0-%fp7 | restore FP general registers
.Lm68881rdone:
frestore (%a0) | restore state
rts
#endif
#if defined(M68060)
.Lm68060fprestore:
tstb 2(%a0) | null state frame?
jeq .Lm68060fprdone | yes, easy
fmovem FPF_FPCR(%a0),%fpcr | restore FP control registers
fmovem FPF_FPSR(%a0),%fpsr
fmovem FPF_FPI(%a0),%fpi
fmovem FPF_REGS(%a0),%fp0-%fp7 | restore FP general registers
.Lm68060fprdone:
frestore (%a0) | restore state
rts
#endif
#else
#ifdef DIAGNOSTIC
.L68881panic:
.asciz "m68881 save/restore"
.even
#endif
ENTRY_NOPROFILE(m68881_save)
GLOBAL(m68881_restore)
#ifdef DIAGNOSTIC
pea .L68881panic
jbsr _C_LABEL(panic)
#endif
rts
#endif
ENTRY_NOPROFILE(lwp_trampoline)
movl %a4,-(%sp) | new lwp
movl %a0,-(%sp) | old lpw
jbsr _C_LABEL(lwp_startup)
addql #8,%sp
movl %a3,-(%sp) | push function arg
jbsr (%a2) | call function
addql #4,%sp | pop arg
movl FR_SP(%sp),%a0 | grab and load
movl %a0,%usp | user SP
moveml (%sp)+,#0x7FFF | restore most user regs
addql #8,%sp | toss SP and stack adjust
jra _ASM_LABEL(rei) | and return