📄 cpu_support.s
字号:
mov.l @r8, r8 // R8 = ctxtsk tst r8, r8 // If ctxtsk == NULL, invalid use of FPU bt l_goto_defaulthdr mov.l @(TCB_tskatr, r8), r9 mov.l U_TA_FPU, r4 // If TA_FPU attribute is not specified tst r4, r9 // Invalid use of FPU bt l_goto_defaulthdr /* Do not destroy R0_BANK1 until here */ mov.l U_fpu_ctxtsk, r9 // R9 = &fpu_ctxtsk mov.l @r9, r4 // R4 = fpu_ctxtsk cmp/eq r4, r8 // If fpu_ctxtsk == ctxtsk, bt l_nosw_fpu // do not need to switch FPU context tst r4, r4 // If fpu_ctxtsk == NULL, bt l_nosave_fpu // do not need to save FPU context mov.l U_tcb_isstack, r0 // Save FPU context mov.l @(r0, r4), r4 // Location for saving R4 = FPU context mov.l U_COP0_REGSZ, r0 add r0, r4 sts.l fpscr, @-r4 sts.l fpul, @-r4 mov.l U_FPSCR_FR0_SZ1, r0 lds r0, fpscr // FPSCR.FR=0 SZ=1 fmov xd14, @-r4 fmov xd12, @-r4 fmov xd10, @-r4 fmov xd8, @-r4 fmov xd6, @-r4 fmov xd4, @-r4 fmov xd2, @-r4 fmov xd0, @-r4 fmov dr14, @-r4 fmov dr12, @-r4 fmov dr10, @-r4 fmov dr8, @-r4 fmov dr6, @-r4 fmov dr4, @-r4 fmov dr2, @-r4 fmov dr0, @-r4 l_nosave_fpu: mov.l U_tcb_isstack, r0 // Restore FPU context mov.l @(r0, r8), r4 // Location for R4 = FPU context mov.l U_FPSCR_FR0_SZ1, r0 lds r0, fpscr // FPSCR.FR=0 SZ=1 fmov @r4+, dr0 fmov @r4+, dr2 fmov @r4+, dr4 fmov @r4+, dr6 fmov @r4+, dr8 fmov @r4+, dr10 fmov @r4+, dr12 fmov @r4+, dr14 fmov @r4+, xd0 fmov @r4+, xd2 fmov @r4+, xd4 fmov @r4+, xd6 fmov @r4+, xd8 fmov @r4+, xd10 fmov @r4+, xd12 fmov @r4+, xd14 lds.l @r4+, fpul lds.l @r4+, fpscr mov.l r8, @r9 // fpu_ctxtsk = ctxtsk l_nosw_fpu: mov.l @(3*4, ISP), r4 mov.l U_NOT_SR_FD, r0 and r0, r4 // FPU enable mov.l r4, @(3*4, ISP) // SSR.FD = 0 on stack mov.l @SP+, r9 // Restore register for work mov.l @SP+, r8 mov.l U_BlockIntSR, r0 // Exception block ldc r0, sr mov.l @ISP+, r4 // R4_BANK1 restore INT_RETURN unavailable_cop l_goto_defaulthdr: // R0_BANK1 is when entering handler mov.l @(3*4, ISP), r4 // Same state mov.l U_BlockIntSR, r8 or r8, r4 // Value for R4 = SR restorer mov.l @SP+, r9 // Restore register for work mov.l @SP+, r8 ldc r4, sr // SR restore mov.l @ISP+, r4 // R4_BANK1 restore mov.l U_DEFAULTHDR, r7 mov.l @r7, r7 jmp @r7 // To default handler nop/* * Save FPU context * void save_fpuctx( T_COP0REGS *save_area ) * * 'save_area' is aligned by 4 bytes. * Note that this is not to be accessed by double (8 bytes). */ .text .balign 2 .globl Csym(save_fpuctx) .type Csym(save_fpuctx), @functionCsym(save_fpuctx): mov.l U_NOT_SR_FD, r0 stc sr, r1 // R1 = SR save and r1, r0 ldc r0, sr // SR.FD=0 FPU enable sts fpscr, r2 // R2 = FPSCR save mov.l U_COP0_REGSZ, r0 add r0, r4 sts.l fpscr, @-r4 sts.l fpul, @-r4 mov.l U_FPSCR_FR1_SZ0, r0 lds r0, fpscr // FPSCR.FR=1 SZ=0 fmov.s fr15, @-r4 fmov.s fr14, @-r4 fmov.s fr13, @-r4 fmov.s fr12, @-r4 fmov.s fr11, @-r4 fmov.s fr10, @-r4 fmov.s fr9, @-r4 fmov.s fr8, @-r4 fmov.s fr7, @-r4 fmov.s fr6, @-r4 fmov.s fr5, @-r4 fmov.s fr4, @-r4 fmov.s fr3, @-r4 fmov.s fr2, @-r4 fmov.s fr1, @-r4 fmov.s fr0, @-r4 frchg // FPSCR.FR=0 fmov.s fr15, @-r4 fmov.s fr14, @-r4 fmov.s fr13, @-r4 fmov.s fr12, @-r4 fmov.s fr11, @-r4 fmov.s fr10, @-r4 fmov.s fr9, @-r4 fmov.s fr8, @-r4 fmov.s fr7, @-r4 fmov.s fr6, @-r4 fmov.s fr5, @-r4 fmov.s fr4, @-r4 fmov.s fr3, @-r4 fmov.s fr2, @-r4 fmov.s fr1, @-r4 fmov.s fr0, @-r4 lds r2, fpscr // FPSCR restore ldc r1, sr // SR restore rts nop .balign 4 U_DisableIntSR: .long SR_MD | SR_RB | SR_I(15) U_BlockIntSR: .long SR_MD | SR_RB | SR_BL | SR_FD | SR_I(15) U_NOT_SR_FD: .long ~SR_FD U_FPSCR_FR0_SZ1: .long FPSCR_SZ U_FPSCR_FR1_SZ0: .long FPSCR_FR U_TA_FPU: .long TA_FPU U_ctxtsk: .long Csym(ctxtsk) U_fpu_ctxtsk: .long Csym(fpu_ctxtsk) U_tcb_isstack: .long TCB_isstack U_COP0_REGSZ: .long COP0_REGSZ U_DEFAULTHDR: .long DEFAULTHDR#endif /* TA_FPU *//* ------------------------------------------------------------------------ *//* * High level programming language routine for interrupt handler * Called by interrupt entry routine on the state saved in the interrupt * stack as shown below. * High Address +---------------+ * | USP | Only RNG 1-3 * +---------------+ * | MDR (R2_BANK1)| RNG0-3 common * | SSR | * | SPC | * ISP => | R0_BANK1 | * Low Address +---------------+ * * Also, 'vector indexe + factor' are saved in R0_BANK1. * Factor 0:Exception 1:TRAPA 2:Interrupt */ .text .balign 2 .globl Csym(defaulthdr_startup) .type Csym(defaulthdr_startup), @function .globl Csym(inthdr_startup) .type Csym(inthdr_startup), @functionCsym(defaulthdr_startup): and #3, r0 mov.l I_defaulthdr_vecidx, r7 or r7, r0Csym(inthdr_startup): /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l r8, @-ISP // Temporarily save R8-R9 mov.l r9, @-ISP /* Get EIT information */ mov #0xffffffd0, r7 tst #2, r0 bf l_interrupt // Exception/TRAPA mov.l @(EXPEVT - 0xffffffd0, r7), r8 // R8 = EXPEVT mov.l @(TRA - 0xffffffd0, r7), r9 // R9 = TRA bra l_inthdr1 nop l_interrupt: mov.l I_INTEVT2, r8 // Interrupt mov.l @r8, r8 // R8 = INTEVT2 mov.l @(INTEVT - 0xffffffd0, r7), r9 // R9 = INTEVT l_inthdr1: mov.l I_DisableIntSR, r7 // Free exception block, Switch register bank ldc r7, sr /* During interrupt disable SR.I=15 BL=0 RB=0 */ stc.l r1_bank, @-SP // Register save mov.l r7, @-SP mov.l r6, @-SP mov.l r5, @-SP mov.l r4, @-SP mov.l r3, @-SP mov.l r2, @-SP mov.l r1, @-SP mov.l r0, @-SP stc.l gbr, @-SP sts.l pr, @-SP sts.l macl, @-SP sts.l mach, @-SP mov r8, r4 // EIT information mov r9, r5 stc r6_bank, r6 // ISP == R6_BANK1 mov.l @r6+, r9 // R8,R9 restore mov.l @r6+, r8 ldc r6, r6_bank#if USE_DBGSPT mov.l I_hook_ienter_jmp, r3 mov.l @r3, r3 jmp @r3 nop ret_hook_ienter:#endif stc r0_bank, r0 // R0 = vector indexe + factor mov.l I_hll_inthdr, r1 shlr2 r0 shll2 r0 mov.l @(r0, r1), r2 // call hll_inthdr[n](dintno, info) jsr @r2 nop#if USE_DBGSPT mov.l I_hook_ileave_jmp, r3 mov.l @r3, r3 jmp @r3 nop ret_hook_ileave:#endif mov.l I_DisableIntSR, r0 // Interrupt disable ldc r0, sr /* During interrupt disable SR.I=15 BL=0 RB=0 */ lds.l @SP+, mach // Register restore lds.l @SP+, macl lds.l @SP+, pr ldc.l @SP+, gbr mov.l @SP+, r0 mov.l @SP+, r1 mov.l @SP+, r2 mov.l @SP+, r3 mov.l @SP+, r4 mov.l @SP+, r5 mov.l @SP+, r6 mov.l @SP+, r7 ldc.l @SP+, r1_bank trapa #TRAP_RETINT // tk_ret_int() .balign 4 I_defaulthdr_vecidx: .long DEFAULTHDR - VECTBL I_hll_inthdr: .long Csym(hll_inthdr) I_DisableIntSR: .long SR_MD | SR_I(15) I_INTEVT2: .long INTEVT2#if USE_DBGSPT/* * Interrupt handler hook routine call */ .text .balign 2hook_ienter: mov.l I_hook_ienterfn, r3 mov.l @r3, r3 mov.l r4, @-SP // Save dintno, info mov.l r5, @-SP jsr @r3 // call enter(dintno, info) nop mov.l @(0*4, SP), r5 // r5 restore mov.l @(1*4, SP), r4 // r4 restore bra ret_hook_ienter nophook_ileave: mov.l I_hook_ileavefn, r3 mov.l @r3, r3 mov.l @SP+, r5 // info jsr @r3 // call leave(dintno, info) mov.l @SP+, r4 // dintno bra ret_hook_ileave nop/* * Set/Free interrupt handler hook routine */ .text .balign 2 .globl Csym(hook_int) .type Csym(hook_int), @functionCsym(hook_int): mov.l I_hook_ienter_jmp, r0 mov.l I_hook_ileave_jmp, r1 mov.l I_hook_ienter, r2 mov.l I_hook_ileave, r3 mov.l r2, @r0 rts mov.l r3, @r1 .globl Csym(unhook_int) .type Csym(unhook_int), @functionCsym(unhook_int): mov.l I_hook_ienter_jmp, r0 mov.l I_hook_ileave_jmp, r1 mov.l I_ret_hook_ienter, r2 mov.l I_ret_hook_ileave, r3 mov.l r2, @r0 rts mov.l r3, @r1 .balign 4 I_hook_ienter_jmp: .long hook_ienter_jmp I_hook_ileave_jmp: .long hook_ileave_jmp I_hook_ienter: .long hook_ienter I_hook_ileave: .long hook_ileave I_ret_hook_ienter: .long ret_hook_ienter I_ret_hook_ileave: .long ret_hook_ileave I_hook_ienterfn: .long Csym(hook_ienterfn) I_hook_ileavefn: .long Csym(hook_ileavefn) .data .balign 4 hook_ienter_jmp: .long ret_hook_ienter hook_ileave_jmp: .long ret_hook_ileave#endif /* USE_DBGSPT *//* * tk_ret_int() processing * When called, the interrupt stack is configured as shown below. * High Address +---------------+ * | USP | Only RNG 1-3 * +---------------+ * | MDR (R2_BANK1)| RNG0-3 common * | SSR | * | SPC | * | R0_BANK1 | When the interrupt occurs, save * +---------------+ until here * | MDR (R2_BANK1)| Save by 'trapa TRAP_RETINT' * | SSR | * | SPC | * ISP => | R0_BANK1 | * Low Address +---------------+ */ .text .balign 2 .globl Csym(_tk_ret_int) .type Csym(_tk_ret_int), @functionCsym(_tk_ret_int): /* During interrupt disable SR.I=15 BL=1 RB=1 */ add #(4*4), ISP // Trash parts saved by 'trapa TRAP_RETINT' mov.l R_DisableIntSR, r0 // Free exception block ldc r0, sr /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l R_int_stack_top, r0 // Is it a nesting interrupt? mov.l @r0, r0 add #-(5*4), r0 cmp/ge r0, ISP // ISP >= r0 bf l_nodispatch mov.l @(2*4, ISP), r0 // SR when EIT occurs tst #SR_I(15), r0 // Is it an exception during interrupt disable? bf l_nodispatch mov.l R_dispatch_disabled, r0 // Is it during dispatch disable? mov.l @r0, r0 tst r0, r0 bf l_nodispatch mov.l r4, @-SP mov.l R_ctxtsk, r0 // Is dispatch required? mov.l R_schedtsk, r4 mov.l @r0, r0 mov.l @r4, r4 cmp/eq r0, r4 mov.l @SP+, r4 bt l_nodispatch mov.l R_ret_int_dispatch, r0 // To dispatch processing jmp @r0 nop l_nodispatch: // Dispatch not required mov.l R_BlockIntSR, r0 ldc r0, sr INT_RETURN ret_int .balign 4 R_int_stack_top: .long Csym(int_stack_top) R_dispatch_disabled: .long Csym(dispatch_disabled) R_ctxtsk: .long Csym(ctxtsk) R_schedtsk: .long Csym(schedtsk) R_ret_int_dispatch: .long _ret_int_dispatch R_DisableIntSR: .long SR_MD | SR_RB | SR_I(15) R_BlockIntSR: .long SR_MD | SR_RB | SR_I(15) | SR_BL/* ------------------------------------------------------------------------ *//* * Unsupported system call */ .text .balign 2 .globl Csym(no_support) .type Csym(no_support), @functionCsym(no_support): mov.l N_E_RSFN, r0 rts nop .balign 4 N_E_RSFN: .long E_RSFN/* * System call entry table */ .text .balign 4_svctbl: .int Csym(no_support)#define _tk_ret_int no_support#include <sys/svc/tksvctbl.h>#undef _tk_ret_int/* * System call entry * Do not need to save the temporary register. * The compiler saves the permanent register. * High Address +---------------+ * | USP | Only RNG 1-3 * +---------------+ * | MDR (R2_BANK1)| RNG0-3 common * | SSR | * | SPC | * ISP/SSP => | R0_BANK1 | * Low Address +---------------+ */ .text .balign 2 .globl Csym(call_entry) .type Csym(call_entry), @functionCsym(call_entry): /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l C_DisableIntSR, r0 // Free exception block ldc r0, sr /* Move from interrupt stack to system stack */ MOVE_ISP_SSP call_entry mov.l r8, @-SP // R8 save mov.l C_CallerSRMask, r8 // Register bank switch mov.l @(3*4, SP), r0 // SSR and r8, r0 mov.l C_EnableIntSR, r8 or r8, r0 ldc r0, sr /* The interrupt disable state keeps the caller's state SR.I=? BL=0 RB=0 */ mov r0, r8 // Save function code to R8 sts.l pr, @-SP // PR save mov.l r14, @-SP // FP save mov SP, r14#if USE_DBGSPT mov.l C_hook_enter_jmp, r1 // Hook processing mov.l @r1, r1 jmp @r1 nop ret_hook_enter:#endif cmp/pz r8 // R0_BANK0 : Function code bt l_esvc_function /* T-Kernel system call */ mov r14, r3 add #(7*4), r3 mov.l @(6*4, r14), r0 // Saved MDR and #3, r0 // R0 = Caller's protected level mov.l C_TSVCLimit, r2 // Call protected level limit mov.l @r2, r2 cmp/hi r2, r0 bt l_oacv_err cmp/pl r0 bf l_nousp mov.l @r3, r3 // R3 = User stack pointer l_nousp: // R3 = Argument position on stack swap.w r8, r2 exts.w r2, r2 // R2 = Function code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -