📄 cpu_support.s
字号:
* | R7 | * | R6 | * | BPC | * | PSW|ICU1_ISTS | When the interrupt occurs, save until here * +---------------+ * | R7 | Saved by 'trap #TRAP_RETINT' * | R6 | * | BPC | * SP => | PSW | * Low Address +---------------+ */ .text .balign 4 .globl Csym(_tk_ret_int)Csym(_tk_ret_int): /* During interrupt disable PSW.IE=0, SM=? */ addi sp, #(4*4) // Throw away information saved by 'trap' ld r6, @sp // PSW ld24 r7, #PSW_BIE | PSW_BSM and r6, r7 // Is it a nesting interrupt? Or bne r6, r7, l_nodispatch // is it an exception during interrupt disable? seth r6, #CsymH(dispatch_disabled) // Is it during dispatch disable? ld r6, @(CsymL(dispatch_disabled), r6) bnez r6, l_nodispatch seth r6, #CsymH(ctxtsk) // Is dispatch required? ld r6, @(CsymL(ctxtsk), r6) seth r7, #CsymH(schedtsk) ld r7, @(CsymL(schedtsk), r7) beq r6, r7, l_nodispatch mvfc r6, psw and3 r6, r6, #PSW_SM // Current stack mode bnez r6, l_retint1 /* SM=0 : Move from interrupt stack to system stack */ mv r7, sp ldi r6, #PSW_SM mvtc r6, psw // Stack mode switch SM=1 ld r6, @(3*4, r7) // Move stack contents st r6, @-sp // R7 ld r6, @(2*4, r7) st r6, @-sp // R6 ld r6, @(1*4, r7) st r6, @-sp // BPC ld r6, @r7 or3 r6, r6, #PSW_SM st r6, @-sp // PSW|ICU1_ISTS addi r7, #(4*4) mvtc r7, spi // Free interrupt stack srl3 r7, r6, #16 // If ICU1_ISTS == 0, not ext. interrupt beqz r7, l_retint1 ld24 r7, #ICU1_IMASK // Ext. interrupt finalization st r6, @r7 // ICU1_IMASK = ICU1_ISTS l_retint1: /* PSW.IE=0, SM=1 */ bra _ret_int_dispatch // To dispatch processing l_nodispatch: // Dispatch not required INT_RETURN ret_int/* ------------------------------------------------------------------------ *//* * Unsupported system call */ .text .balign 4 .globl Csym(no_support)Csym(no_support): seth r0, #high(E_RSFN) jmp lr/* * 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. */ .text .balign 4 .globl Csym(call_entry)Csym(call_entry): /* During interrupt disable PSW.IE=0, SM=? */ mvfc r7, psw srli r7, #8 mvtc r7, psw /* The interrupt disable state keeps the caller's state PSW.IE=?, SM=? */ st lr, @-sp // lr save st fp, @-sp // fp save mv fp, sp#if USE_DBGSPT st r4, @-sp // Save function code seth r7, #shigh(hook_enter_jmp) // Hook processing ld r7, @(low(hook_enter_jmp), r7) jmp r7 ret_hook_enter:#endif bgez r4, l_esvc_function // R4 = Function code /* T-Kernel system call */ sra3 r5, r4, #16 add3 r7, r5, #-(N_TFN + 0xffff8000) bgtz r7, l_illegal_svc srai r4, #8 and3 r4, r4, #0xff // Number of arguments ldi r6, #5 bne r4, r6, l_nocopy ld r7, @(6*4, fp) // Copy fifth argument st r7, @-sp l_nocopy: seth r7, #shigh(_svctbl - (0xffff8000 << 2)) slli r5, #2 add r7, r5 ld r7, @(low(_svctbl - (0xffff8000 << 2)), r7) jl r7 // T-Kernel system call l_retsvc:#if USE_DBGSPT seth r7, #shigh(hook_leave_jmp) // Hook processing ld r7, @(low(hook_leave_jmp), r7) jmp r7 ret_hook_leave:#endif mv sp, fp // Register restore ld fp, @sp+ ld lr, @sp+ ld r6, @sp // PSW and3 r7, r6, #PSW_BSM // If it is a call from the task independent part, beqz r7, l_nodct // do not process DCT mvtc r6, psw // Interrupt disable seth r6, #CsymH(ctxtsk) ld r6, @(CsymL(ctxtsk), r6) ld r6, @(TCB_reqdct, r6) // DCT request seth r7, #high(0x80000000) bne r6, r7, l_nodct seth r7, #CsymH(dispatch_disabled) // During dispatch disable, ld r7, @(CsymL(dispatch_disabled), r7) // Do not process DCT beqz r7, Csym(dct_startup) // To DCT processing l_nodct: EXC_RETURN call_entry l_esvc_function: /* Extended SVC */ mv r1, r4 // R1 = Function code bl svc_ientry // svc_ientry(pk_para, fncd) bra l_retsvc l_illegal_svc: seth r0, #high(E_RSFN) bra l_retsvc#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 sp; Stack pointer * VP r14; Link register * VP r13; Frame pointer * } TD_CALINF; */ .text .balign 4hook_enter: st r0, @-sp // Save argument st r1, @-sp st r2, @-sp st r3, @-sp st r12, @-sp mv r12, sp // Save stack position ld r7, @fp // Create TD_CALINF st r7, @-sp // fp (r13) ld r7, @(1*4, fp) st r7, @-sp // lr (r14) add3 r7, fp, #2*4 st r7, @-sp // sp (r15) bgez r4, l_nocopy_para // Extended SVC and3 r5, r4, #0xff00 srai r5, #8 // Number of arguments ldi r6, #5 beq r5, r6, l_copy_para5 addi r6, #-1 beq r5, r6, l_copy_para4 addi r6, #-1 beq r5, r6, l_copy_para3 bra l_nocopy_para l_copy_para5: ld r7, @(6*4, fp) st r7, @-sp // Fifth argument l_copy_para4: st r3, @-sp // Fourth argument l_copy_para3: st r2, @-sp // Third argument l_nocopy_para: seth r6, #CsymH(hook_enterfn) ld r6, @(CsymL(hook_enterfn), r6) mv r3, r1 // Second argument mv r2, r0 // First argument add3 r1, r12, #-3*4 // calinf mv r0, r4 // fncd jl r6 // exinf = enter(fncd, calinf, ...) mv r5, r0 // End 'exinf' mv sp, r12 // Return stack position ld r12, @sp+ ld r3, @sp+ // Restore argument ld r2, @sp+ ld r1, @sp+ ld r0, @sp+ ld r4, @sp // Restore function code st r5, @-sp // Save 'exinf' bra ret_hook_enterhook_leave: mv r1, r0 // ret ld r2, @(-2*4, fp) // exinf ld r0, @(-1*4, fp) // Function code st r1, @(-1*4, fp) // Save 'ret' bgez r0, l_hl1 // If function cod >= 0, extended SVC and3 r4, r0, #0xff00 srai r4, #8-2 // Parameter number * 4 addi r4, #-4*4 // Whether 'hook_enter' is executed bgtz r4, l_hl2 // Check by stack consumption l_hl1: ldi r4, #0 l_hl2: addi r4, #2*4 add r4, sp beq r4, fp, l_hl3 ldi r2, #0 // 'hook_enter' is not executed l_hl3: seth r7, #CsymH(hook_leavefn) ld r7, @(CsymL(hook_leavefn), r7) jl r7 // call leave(fncd, ret, exinf) ld r0, @(-1*4, fp) // ret restore bra ret_hook_leave/* * Set/Clear system call/extended SVC hook routine */ .text .balign 4 .globl Csym(hook_svc)Csym(hook_svc): seth r2, #shigh(hook_enter) seth r3, #shigh(hook_leave) add3 r2, r2, #low(hook_enter) add3 r3, r3, #low(hook_leave) seth r0, #shigh(hook_enter_jmp) seth r1, #shigh(hook_leave_jmp) st r2, @(low(hook_enter_jmp), r0) st r3, @(low(hook_leave_jmp), r1) jmp lr .globl Csym(unhook_svc)Csym(unhook_svc): seth r2, #shigh(ret_hook_enter) seth r3, #shigh(ret_hook_leave) add3 r2, r2, #low(ret_hook_enter) add3 r3, r3, #low(ret_hook_leave) seth r0, #shigh(hook_enter_jmp) seth r1, #shigh(hook_leave_jmp) st r2, @(low(hook_enter_jmp), r0) st r3, @(low(hook_leave_jmp), r1) jmp lr .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 4 .globl Csym(call_dbgspt)Csym(call_dbgspt): /* During interrupt disable PSW.IE=0, SM=? */ mvfc r7, psw srli r7, #8 mvtc r7, psw /* The interrupt disable state keeps the caller's state PSW.IE=?, SM=? */ st lr, @-sp // lr save st fp, @-sp // fp save mv fp, sp sra3 r5, r4, #16 add3 r7, r5, #-(N_TDFN + 0xffff8000) bgtz r7, b_illegal_svc seth r7, #shigh(_tdsvctbl - (0xffff8000 << 2)) slli r5, #2 add r7, r5 ld r7, @(low(_tdsvctbl - (0xffff8000 << 2)), r7) jl r7 // T-Kernel/DS service call b_retsvc: mv sp, fp ld fp, @sp+ ld lr, @sp+ EXC_RETURN call_dbgspt b_illegal_svc: seth r0, #high(E_RSFN) bra b_retsvc#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ *//* * High level programming language routine for timer handler */ .text .balign 4 .globl Csym(timer_handler_startup)Csym(timer_handler_startup): /* During interrupt disable PSW.IE=0, SM=0 */ ldi r6, #PSW_IE mvtc r6, psw // interrupt nesting enable PSW.IE=1, SM=0 st lr, @-sp // Register save st r5, @-sp st r4, @-sp st r3, @-sp st r2, @-sp st r1, @-sp st r0, @-sp mvfaclo r1 mvfachi r0 st r1, @-sp st r0, @-sp bl timer_handler // call timer_handler() ld r0, @sp+ // Register restore ld r1, @sp+ mvtachi r0 mvtaclo r1 ld r0, @sp+ ld r1, @sp+ ld r2, @sp+ ld r3, @sp+ ld r4, @sp+ ld r5, @sp+ ld lr, @sp+ trap #TRAP_RETINT // tk_ret_int()/* ------------------------------------------------------------------------ *//* * Delayed context trap (DCT) * Task exception handler startup * When called, the stack is configured as shown below. * High Address +---------------+ * | R7 | * | R6 | * | BPC | * SP => | PSW | * Low Address +---------------+ */ .text .balign 4Csym(dct_startup): /* During interrupt disable PSW.IE=0, SM=1 */ st r7, @-sp // Area for storing 'texcd' st lr, @-sp // Register save st r5, @-sp st r4, @-sp st r3, @-sp st r2, @-sp st r1, @-sp st r0, @-sp mvfaclo r1 mvfachi r0 st r1, @-sp st r0, @-sp add3 r0, sp, #9*4 bl setup_texhdr // texhdr = setup_texhdr(&texcd) /* Return in interrupt enable state */ mv r6, r0 // r6 = texhdr ld r0, @sp+ // Register restore ld r1, @sp+ mvtachi r0 mvtaclo r1 ld r0, @sp+ ld r1, @sp+ ld r2, @sp+ ld r3, @sp+ ld r4, @sp+ ld r5, @sp+ ld lr, @sp+ beqz r6, l_notexhdr ld r7, @(1*4, sp) // PSW mvtc r7, psw // Changes to interrupt disable mvtc r6, bpc // texhdr ld r7, @sp+ // texcd rte // goto texhdr l_notexhdr: addi sp, #4 EXC_RETURN dct_startup/* ------------------------------------------------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -