📄 cpu_support.s
字号:
mov.l C_TFN_limit, r0 cmp/gt r0, r2 bt l_illegal_svc mov r8, r0 shlr8 r0 and #0xff, r0 // R0 = Number of arguments cmp/eq #5, r0 bf l_nocopy mov.l @r3, r1 // Copy fifth argument mov.l r1, @-SP l_nocopy: mov.l C_svctbl, r0 shll2 r2 mov.l @(r0, r2), r0 jsr @r0 // T-Kernel system call nop l_retsvc:#if USE_DBGSPT mov.l C_hook_leave_jmp, r1 // Hook processing mov.l @r1, r1 jmp @r1 nop ret_hook_leave:#endif mov r14, SP // Register restore mov.l @SP+, r14 lds.l @SP+, pr mov.l @SP+, r8 mov.l C_DisableIntSR, r1 // Interrupt disable/Register bank switch RB=1 ldc r1, sr#if !USE_MDR_DCT mov.l @(3*4, SP), r0 // MDR on stack tst #MDR_CPL(3), r0 // If it is a call from protected level 0, bt l_nodct_svc // do not process DCT mov.l C_ctxtsk, r0 // Is there a DCT request? mov.l @r0, r0 mov.l @(TCB_reqdct, r0), r0 cmp/eq #1, r0 bf l_nodct_svc mov.l C_dispatch_disabled, r0 // If it is dispatch disable, mov.l @r0, r0 // do not process DCT tst r0, r0 bf l_nodct_svc mov.l C_int_stack_top, r0 // If it is a call from the task independent part, mov.l @r0, r0 // do not process DCT cmp/eq ISP, r0 // (cannot not happen, but to make sure) bf l_nodct_svc bra dct_startup // To DCT processing nop l_nodct_svc:#endif MOVE_SSP_ISP call_entry // Move from system stack to interrupt stack mov.l C_BlockIntSR, r0 // Exception block ldc r0, sr INT_RETURN call_entry l_esvc_function: /* Extended SVC */ mov.l C_svc_ientry, r1 jsr @r1 // svc_ientry(pk_para, fncd) mov r8, r5 // R5 = Function code bra l_retsvc nop l_illegal_svc: mov.l C_E_RSFN, r0 bra l_retsvc nop l_oacv_err: mov.l C_E_OACV, r0 bra l_retsvc nop .balign 4 C_EnableIntSR: .long SR_MD | SR_I(0) C_DisableIntSR: .long SR_MD | SR_I(15) | SR_RB C_BlockIntSR: .long SR_MD | SR_I(15) | SR_RB | SR_BL C_CallerSRMask: .long SR_I(15) | SR_DSP C_TFN_limit: .long N_TFN + 0xffff8000 C_svctbl: .long _svctbl - (0xffff8000 << 2) C_TSVCLimit: .long Csym(svc_call_limit) C_svc_ientry: .long Csym(svc_ientry)#if !USE_MDR_DCT C_ctxtsk: .long Csym(ctxtsk) C_dispatch_disabled: .long Csym(dispatch_disabled) C_int_stack_top: .long Csym(int_stack_top)#endif C_E_RSFN: .long E_RSFN C_E_OACV: .long E_OACV#if USE_DBGSPT/* * System call/Extended SVC hook routine call * VP enter( FN fncd, TD_CALINF *calinf, ... ) * void leave( FN fncd, INT ret, VP exinf ) * * typedef struct td_calinf { * VP ssp; System stack pointer * VP pr; PR register when calling * VP r14; Flame pointer when calling * } TD_CALINF; */ .text .balign 2hook_enter: mov.l r13, @-SP // Save register for work mov.l r4, @-SP // Save argument mov.l r5, @-SP mov.l r6, @-SP mov.l r7, @-SP mov SP, r13 // Save stack position mov r14, r3 mov.l @r14, r2 // r2 = Frame pointer when calling add #(4*4), r3 // r3 = ssp mov.l r2, @-SP // Create TD_CALINF sts.l pr, @-SP mov.l r3, @-SP mov SP, r2 // r2 = &TD_CALINF cmp/pz r8 // r8 = fncd function code bt l_nocopy_para // Extended SVC mov r14, r3 add #(7*4), r3 mov.l @(6*4, r14), r0 // Saved MDR and #3, r0 // Caller's protected level cmp/pl r0 bf l_nousp_para mov.l @r3, r3 // User stack pointer l_nousp_para: // r3 = Argument position on stack mov r8, r0 // fncd shlr8 r0 and #0xff, r0 // Number of arguments cmp/eq #5, r0 bt l_copy_para5 cmp/eq #4, r0 bt l_copy_para4 cmp/eq #3, r0 bt l_copy_para3 bra l_nocopy_para nop l_copy_para5: mov.l @r3, r1 mov.l r1, @-SP // Fifth argument l_copy_para4: mov.l r7, @-SP // Fourth argument l_copy_para3: mov.l r6, @-SP // Third argument l_nocopy_para: mov.l C_hook_enterfn, r1 mov.l @r1, r1 mov r5, r7 // Second argument mov r4, r6 // First argument mov r2, r5 // TD_CALINF jsr @r1 // exinf = enter(fncd, calinf, ...) mov r8, r4 // fcnd mov r13, SP // Return stack position mov.l @SP+, r7 // Restore argument mov.l @SP+, r6 mov.l @SP+, r5 mov.l @SP+, r4 mov.l @SP, r13 // Restore register for work bra ret_hook_enter mov.l r0, @SP // Save 'lr_svc'hook_leave: mov r0, r5 // r5 = ret mov #0, r6 // r6 = exinf = 0 mov r8, r0 // Function code cmp/pz r0 // If r0 >= 0, extended SVC bt l_hl1 shlr8 r0 and #0xff, r0 // Parameter number add #-4, r0 cmp/pz r0 bt l_hl2 l_hl1: mov #0, r0 l_hl2: shll2 r0 add SP, r0 // Whether 'hook_enter' is executed cmp/hi r0, r14 // Check by stack usage bf l_hl3 // 'hook_enter' is executed mov.l @r0, r6 // 'exinf' retrieve l_hl3: mov.l C_hook_leavefn, r1 mov.l @r1, r1 mov r8, r4 // fncd jsr @r1 // call leave(fncd, ret, exinf) mov r5, r8 // r8 = ret save bra ret_hook_leave mov r8, r0 // r0 = ret restore/* * Set/Free system call/extended SVC hook routine */ .text .balign 2 .globl Csym(hook_svc) .type Csym(hook_svc), @functionCsym(hook_svc): mov.l C_hook_enter_jmp, r0 mov.l C_hook_leave_jmp, r1 mov.l C_hook_enter, r2 mov.l C_hook_leave, r3 mov.l r2, @r0 rts mov.l r3, @r1 .globl Csym(unhook_svc) .type Csym(unhook_svc), @functionCsym(unhook_svc): mov.l C_hook_enter_jmp, r0 mov.l C_hook_leave_jmp, r1 mov.l C_ret_hook_enter, r2 mov.l C_ret_hook_leave, r3 mov.l r2, @r0 rts mov.l r3, @r1 .balign 4 C_hook_enter_jmp: .long hook_enter_jmp C_hook_leave_jmp: .long hook_leave_jmp C_hook_enter: .long hook_enter C_hook_leave: .long hook_leave C_ret_hook_enter: .long ret_hook_enter C_ret_hook_leave: .long ret_hook_leave C_hook_enterfn: .long Csym(hook_enterfn) C_hook_leavefn: .long Csym(hook_leavefn) .data .balign 4 hook_enter_jmp: .long ret_hook_enter hook_leave_jmp: .long ret_hook_leave#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ */#if USE_DBGSPT/* * Debugger support function service call entry table */ .text .balign 4_tdsvctbl: .int Csym(no_support)#include <sys/svc/tdsvctbl.h>/* * Debugger support function service call entry */ .text .balign 2 .globl Csym(call_dbgspt) .type Csym(call_dbgspt), @functionCsym(call_dbgspt): /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l B_DisableIntSR, r0 // Free exception block ldc r0, sr /* Move from interrupt stack to system stack */ MOVE_ISP_SSP call_dbgspt mov.l r4, @-SP // R4_BANK1 save mov.l B_EnableIntSR, r4 // Register bank switch mov.l @(3*4, SP), r0 // SSR and #SR_I(15), r0 or r4, r0 mov.l @SP+, r4 // R4_BANK1 restore ldc r0, sr /* The interrupt disable state keeps the caller's state SR.I=? BL=0 RB=0 */ sts.l pr, @-SP // PR save mov.l r14, @-SP // FP save mov SP, r14 mov r0, r1 // Save function code to R1 mov.l @(5*4, r14), r0 // Saved MDR and #3, r0 // R0 = Caller's protected level mov.l B_TSVCLimit, r2 // Call protected level limit mov.l @r2, r2 cmp/hi r2, r0 bt b_oacv_err swap.w r1, r2 exts.w r2, r2 // R2 = Function code mov.l B_TDFN_limit, r0 cmp/gt r0, r2 bt b_illegal_svc mov.l B_tdsvctbl, r0 shll2 r2 mov.l @(r0, r2), r0 jsr @r0 // T-Kernel/DS service call nop b_retsvc: mov r14, SP mov.l @SP+, r14 lds.l @SP+, pr mov.l B_DisableIntSR, r1 // Interrupt disable RB=1 ldc r1, sr MOVE_SSP_ISP call_dbgspt // Move from system stack to interrupt stack mov.l B_BlockIntSR, r0 // Exception block ldc r0, sr INT_RETURN call_dbgspt b_illegal_svc: mov.l B_E_RSFN, r0 bra b_retsvc nop b_oacv_err: mov.l B_E_OACV, r0 bra b_retsvc nop .balign 4 B_BlockIntSR: .long SR_MD | SR_I(15) | SR_RB | SR_BL B_DisableIntSR: .long SR_MD | SR_I(15) | SR_RB B_EnableIntSR: .long SR_MD | SR_I(0) B_TDFN_limit: .long N_TDFN + 0xffff8000 B_tdsvctbl: .long _tdsvctbl - (0xffff8000 << 2) B_TSVCLimit: .long Csym(svc_call_limit) B_E_RSFN: .long E_RSFN B_E_OACV: .long E_OACV#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ *//* * High level programming language routine for timer handler */ .text .balign 2 .globl Csym(timer_handler_startup) .type Csym(timer_handler_startup), @functionCsym(timer_handler_startup): /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l T_EnableIntSR, r7 // Free exception block, Switch register bank ldc r7, sr /* Multiplexed interrupt enable SR.I=Timer priority BL=0 RB=0 */ mov.l r7, @-SP // Register save 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.l T_timer_handler, r0 jsr @r0 // call timer_handler() nop 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 trapa #TRAP_RETINT // tk_ret_int() .balign 4 T_EnableIntSR: .long SR_MD | SR_I(TIMER_INTLEVEL) T_timer_handler: .long Csym(timer_handler)/* ------------------------------------------------------------------------ *//* * Delayed context trap (DCT) * Task exception handler startup * When called, the interrupt stack is configured as shown below. * (Use MDR DCT) * High Address +---------------+ * | USP | * | MDR (R2_BANK1)| * | SSR | * | SPC | * | R0_BANK1 | * +---------------+ * | MDR (R2_BANK1)| Save by 'trapa TRAP_RETINT' * | SSR | * | SPC | * ISP => | R0_BANK1 | * Low Address +---------------+ */ .text .balign 2#if USE_MDR_DCT .globl Csym(dct_startup) .type Csym(dct_startup), @functionCsym(dct_startup): /* During interrupt disable SR.I=15 BL=1 RB=1 */ add #(4*4), ISP // Trash parts saved by 'trapa TRAP_RETINT' mov.l D_DisableIntSR_RB, r7 // Free exception block ldc r7, sr MOVE_ISP_SSP dct_startup#elsedct_startup:#endif /* During interrupt disable SR.I=15 BL=0 RB=1 */ mov.l D_DisableIntSR, r0 // Register bank switch (RB=0) ldc r0, sr /* During interrupt disable SR.I=15 BL=0 RB=0 */ mov.l r7, @-SP // Register save 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.l D_setup_texhdr, r0 mov SP, r4 jsr @r0 // call setup_texhdr(ISP) add #12*4, r4 // ISP equivalent position /* Return on interrupt enable state */ 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 D_DisableIntSR_RB, r7 // Interrupt disable/Register bank switch (RB=1) ldc r7, sr /* During interrupt disable SR.I=15 BL=0 RB=1 */ ldc.l @SP+, r7_bank MOVE_SSP_ISP dct_startup mov.l D_BlockIntSR, r0 // Exception block ldc r0, sr INT_RETURN dct_startup .balign 4 D_DisableIntSR_RB: .long SR_MD | SR_I(15) | SR_RB D_DisableIntSR: .long SR_MD | SR_I(15) D_BlockIntSR: .long SR_MD | SR_I(15) | SR_RB | SR_BL D_setup_texhdr: .long Csym(setup_texhdr)/* ------------------------------------------------------------------------ *//* * SR register load function * Function for writing to the SR register on the user mode. * Set the value to write to SR on R0_BANK0, * and then call by 'trapa TRAP_LOADSR.' * However, cannot change the following (not be changed): * MD Privilege mode * RB Register bank * BL Exception block * DSP DSP mode (SH3) * I Interrupt mask * Reservation bit */ .text .balign 2 .globl Csym(load_SR) .type Csym(load_SR), @functionCsym(load_SR): /* SR.I=15 BL=1 RB=1 */ mov.l r1, @-ISP // R1 save mov.l L_SR_Mask, r7 // R7 = Unchangeable bit mask mov.l @(3*4, ISP), r1 // R1 = Current SR stc r0_bank, r0 // R0 = Write only SR and r7, r1 not r7, r7 and r7, r0 or r0, r1 // R1 = R1 & R7 | R0 & ~R7 mov.l r1, @(3*4, ISP) // Save SR after change mov.l @ISP+, r1 // R1 restore INT_RETURN load_SR // Update SR by returning from TRAP .balign 4 L_SR_Mask: .long 0x8000e000 | SR_MD | SR_RB | SR_BL | SR_DSP | SR_I(15)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -