📄 cpu_support.s
字号:
/* *---------------------------------------------------------------------- * T-Kernel * * Copyright (C) 2004 by Ken Sakamura. All rights reserved. * T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * * Version: 1.01.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* * cpu_support.S (SH7751R) * Device-Dependent CPU Operation */#define _in_asm_source_#include <machine.h>#include <tk/errno.h>#include <tk/sysdef.h>#include <tk/asm.h>#include <sys/sysinfo.h>#include "config.h"#include "cpu_conf.h"#include "isysconf.h"#include "tkdev_conf.h"#include "offset.h"#define MMU_RegBase 0xff000000 /* Head of MMU-related register *//* ------------------------------------------------------------------------ *//* * Dispatcher * dispatch_to_schedtsk: * Throw away the current contexts and forcibly dispatch to * 'schedtsk.' * Called directly by jump (jmp) but do not return. * Called on the undefined stack state (undefined 'ssp'). * Called on the interrupt disable state. * dispatch_entry: * Normal dispatch processing. * Called by 'trapa TRAP_DISPATCH.' * _ret_int_dispatch: * Called when dispatch is required by 'ret_int().' * * Contexts to save * Save registers except for SSP to a stack. Save SSP to TCB. * * High Address +---------------+ * | USP | Only RNG 1-3 * +---------------+ * | MDR (R2_BANK1)| RNG0-3 shared * | SSR | * | SPC | Saved by interrupt entry * | R0_BANK1 | routines until here. * +---------------+ * | R1_BANK1 | * | R8-14 | * | R0-7_BANK0 | * | GBR | * | PR | * | MACL | * Saved to TCB SSP => | MACH | * Low Address +---------------+ * */ /* Temporal stack used when 'dispatch_to_schedtsk' is called */#define TMP_STACK_SZ (4*1024)#define TMP_STACK_TOP (tmp_stack + TMP_STACK_SZ) .lcomm tmp_stack, TMP_STACK_SZ .text .balign 2 .globl Csym(dispatch_to_schedtsk) .type Csym(dispatch_to_schedtsk), @function .globl Csym(dispatch_entry) .type Csym(dispatch_entry), @functionCsym(dispatch_to_schedtsk): /* During interrupt disable SR.I=15 BL=0 RB=0 */ mov.l L_tmp_stack_top, SP // Set temporal stack mov.l L_dispatch_disabled, r0 // Dispatch disable mov #1, r1 mov.l r1, @r0 mov.l L_ctxtsk, r10 // R10 = &ctxtsk mov #0, r0#if USE_DBGSPT mov.l @r10, r8#endif mov.l r0, @r10 // ctxtsk = NULL mov.l L_EnableIntSR, r0 // Interrupt enable, Register bank switch ldc r0, sr bra l_dispatch0 nopCsym(dispatch_entry): /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l @(2*4, ISP), r0 or #SR_I(15), r0 xor #SR_I(15), r0 mov.l r0, @(2*4, ISP) // SSR compensation (I=0) mov.l L_DisableIntSR, r0 // Free exception block ldc r0, sr_ret_int_dispatch: /* During interrupt disable SR.I=15 BL=0 RB=1 */ /* Move from interrupt stack to system stack */ MOVE_ISP_SSP dispatch mov.l r1, @-SP // R1_BANK1 save mov.l L_dispatch_disabled, r0 // Dispatch disable mov #1, r1 mov.l r1, @r0 mov.l L_EnableIntSR, r0 // Interrupt enable ldc r0, sr mov.l r14, @-SP // Context save mov.l r13, @-SP mov.l r12, @-SP mov.l r11, @-SP mov.l r10, @-SP mov.l r9, @-SP mov.l r8, @-SP stc.l r7_bank, @-SP stc.l r6_bank, @-SP stc.l r5_bank, @-SP stc.l r4_bank, @-SP stc.l r3_bank, @-SP stc.l r2_bank, @-SP stc.l r1_bank, @-SP stc.l r0_bank, @-SP stc.l gbr, @-SP sts.l pr, @-SP sts.l macl, @-SP sts.l mach, @-SP mov.l L_ctxtsk, r10 // R10 = &ctxtsk mov.l @r10, r8 mov.l L_tskctxb_ssp, r0 mov.l SP, @(r0, r8) // Save SSP to TCB l_dispatch0: /* During interrupt enable SR.I=0 BL=0 RB=1 */#if USE_DBGSPT mov.l L_hook_stop_jmp, r0 // Hook processing mov.l @r0, r0 jmp @r0 nop ret_hook_stop:#endif mov #0, r0 mov.l r0, @r10 // ctxtsk = NULL mov.l L_schedtsk, r11 // R11 = &schedtsk mov.l L_lowpow_discnt, r12 // R12 = &lowpow_discnt mov.l L_low_pow, r13 // R13 = &low_pow() l_dispatch1: mov.l L_DisableIntSR, r0 // Interrupt disable ldc r0, sr mov.l @r11, r8 // R8 = schedtsk tst r8, r8 // Is there 'schedtsk'? bf l_dispatch2 /* Because there is no task that should be executed, move to the power saving mode */ mov.l @r12, r0 // Is 'low_pow' disabled? tst r0, r0 bf l_dispatch11 mov.l L_low_pow_SR, r0 // SR setting value for 'low_pow' call ldc r0, sr jsr @r13 // call low_pow() nop l_dispatch11: mov.l L_EnableIntSR, r0 // Interrupt enable ldc r0, sr bra l_dispatch1 nop l_dispatch2: // Switch to 'schedtsk' /* During interrupt disable SR.I=15 BL=0 RB=1 SH3:DSP=1 */ mov.l r8, @r10 // ctxtsk = schedtsk mov.l L_tskctxb_ssp, r0 mov.l @(r0, r8), SP // Restore SSP from TCB mov.l L_tcb_isstack, r0 mov.l @(r0, r8), SST // Restore SST from TCB /* Switch task eigenspace */ mov.l L_MMU_RegBase, r12 mov.l L_tskctxb_uatb, r0 // TTB = uatb mov.l @(r0, r8), r9 mov.l r9, @(TTB - MMU_RegBase, r12) mov.l L_tskctxb_lsid, r0 // PTEH = lsid mov.l @(r0, r8), r9 mov.l r9, @(PTEH - MMU_RegBase, r12)#if USE_DBGSPT mov.l L_hook_exec_jmp, r0 // Hook processing mov.l @r0, r0 jmp @r0 nop ret_hook_exec:#endif#if TA_FPU /* Switch FPU context */ mov.l L_fpu_ctxtsk, r12 // R12 = &fpu_ctxtsk mov.l @r12, r9 // R9 = fpu_ctxtsk; cmp/eq r8, r9 // If fpu_ctxtsk == ctxtsk bt/s l_same_fpuctx // Do not need to switch FPU context mov #22*4+1, r0 ldc SP, gbr or.b #SR_FD >> 8, @(r0, gbr) // SSR.FD = 1 on stack l_same_fpuctx:#endif /* TA_FPU */#if USE_SH3_DSP /* Switch DSP context */ mov.l L_tcb_tskatr, r0 // Use DSP? mov.l L_TA_COP0, r13 mov.l @(r0, r8), r0 tst r0, r13 bt l_noswdsp mov.l L_dsp_ctxtsk, r12 // R12 = &dsp_ctxtsk mov.l @r12, r9 // R9 = dsp_ctxtsk cmp/eq r8, r9 // If fpu_ctxtsk == ctxtsk, bt l_noswdsp // do not need to switch DSP context mov r4, r13 // R4_BANK1 save tst r9, r9 // If dsp_ctxtsk == NULL, bt l_nosavedsp // do not need to save DSP context mov.l L_tcb_isstack, r0 // DSP context save mov.l @(r0, r9), r4 add #COP0_REGSZ, r4 stc.l mod, @-r4 stc.l re, @-r4 stc.l rs, @-r4 movs.l y1, @-r4 movs.l y0, @-r4 movs.l x1, @-r4 movs.l x0, @-r4 movs.l m1, @-r4 movs.l m0, @-r4 movs.w a1g, @-r4 movs.w a0g, @-r4 movs.l a1, @-r4 movs.l a0, @-r4 sts.l dsr, @-r4 l_nosavedsp: mov SST, r4 // DSP context restore lds.l @r4+, dsr movs.l @r4+, a0 movs.l @r4+, a1 movs.w @r4+, a0g movs.w @r4+, a1g movs.l @r4+, m0 movs.l @r4+, m1 movs.l @r4+, x0 movs.l @r4+, x1 movs.l @r4+, y0 movs.l @r4+, y1 ldc.l @r4+, rs ldc.l @r4+, re ldc.l @r4+, mod mov.l r8, @r12 // dsp_ctxtsk = ctxtsk mov r13, r4 // R4_BANK1 restore l_noswdsp:#endif /* USE_SH3_DSP */#if !USE_MDR_DCT mov.l @(TCB_reqdct, r8), r0 // DCT request#endif lds.l @SP+, mach // Context restore lds.l @SP+, macl lds.l @SP+, pr ldc.l @SP+, gbr ldc.l @SP+, r0_bank ldc.l @SP+, r1_bank ldc.l @SP+, r2_bank ldc.l @SP+, r3_bank ldc.l @SP+, r4_bank ldc.l @SP+, r5_bank ldc.l @SP+, r6_bank ldc.l @SP+, r7_bank mov.l @SP+, r8 mov.l @SP+, r9 mov.l @SP+, r10 mov.l @SP+, r11 mov.l @SP+, r12 mov.l @SP+, r13 mov.l @SP+, r14#if !USE_MDR_DCT cmp/eq #1, r0 // If DCT request is enabled, SR.T=1#endif mov.l L_dispatch_disabled, r0 // Dispatch enable mov #0, r1 mov.l r1, @r0#if !USE_MDR_DCT bf l_nodct_dispatch mov.l @(4*4, SP), r0 // MDR tst #MDR_CPL(3), r0 // If the protected level is 0, DCT disable bt l_nodct_dispatch bra dct_startup // To DCT processing mov.l @SP+, r1 // R1_BANK1 restore l_nodct_dispatch:#endif mov.l @SP+, r1 // R1_BANK1 restore /* Move from system stack to interrupt stack */ MOVE_SSP_ISP dispatch mov.l L_BlockIntSR, r0 // Exception block ldc r0, sr INT_RETURN dispatch .balign 4 L_tmp_stack_top: .long TMP_STACK_TOP L_EnableIntSR: .long SR_MD | SR_FD | SR_RB | SR_I(0) L_DisableIntSR: .long SR_MD | SR_FD | SR_RB | SR_I(15) L_BlockIntSR: .long SR_MD | SR_FD | SR_RB | SR_I(15) | SR_BL L_low_pow_SR: .long SR_MD | SR_FD | SR_I(15) L_dispatch_disabled: .long Csym(dispatch_disabled) L_schedtsk: .long Csym(schedtsk) L_ctxtsk: .long Csym(ctxtsk) L_tskctxb_ssp: .long TCB_tskctxb + CTXB_ssp L_tskctxb_uatb: .long TCB_tskctxb + CTXB_uatb L_tskctxb_lsid: .long TCB_tskctxb + CTXB_lsid L_tcb_isstack: .long TCB_isstack L_MMU_RegBase: .long MMU_RegBase L_lowpow_discnt: .long Csym(lowpow_discnt) L_low_pow: .long Csym(low_pow)#if USE_SH3_DSP L_dsp_ctxtsk: .long Csym(dsp_ctxtsk) L_tcb_tskatr: .long TCB_tskatr L_TA_COP0: .long TA_COP0#endif#if TA_FPU L_fpu_ctxtsk: .long Csym(fpu_ctxtsk)#endif#if USE_DBGSPT/* * Task dispatcher hook routine call * void stop( ID tskid, INT lsid, UINT tskstat ) * void exec( ID tskid, INT lsid ) */ .text .balign 2hook_stop: tst r8, r8 // r8 = ctxtsk bt l_notask mov.l L_hook_SR, r0 // SR setting value for hook call stc sr, r9 // SR save ldc r0, sr /* SR.I=0 BL=0 RB=0 */ mov.l L_hook_stopfn, r1 mov.l @r1, r1 mov.l L_tcb_state, r0 mov.b @(r0, r8), r6 shll r6 // tskstat mov.l L_tskctxb_lsid2, r0 mov.l @(r0, r8), r5 // lsid mov.l L_tcb_tskid, r0 jsr @r1 // call stop(tskid, lsid, tskstat) mov.l @(r0, r8), r4 // tskid ldc r9, sr // SR restore l_notask: bra ret_hook_stop nophook_exec: mov.l L_hook_SR, r0 // SR setting value for hook call stc sr, r9 // SR save ldc r0, sr /* SR.I=0 BL=0 RB=0 */ mov.l L_hook_execfn, r1 mov.l @r1, r1 mov.l L_tskctxb_lsid2, r0 // r8 = ctxtsk mov.l @(r0, r8), r5 // lsid mov.l L_tcb_tskid, r0 jsr @r1 // call exec(tskid, lsid) mov.l @(r0, r8), r4 // tskid ldc r9, sr // SR restore bra ret_hook_exec nop/* * Set/Free task dispatcher hook routine */ .text .balign 2 .globl Csym(hook_dsp) .type Csym(hook_dsp), @functionCsym(hook_dsp): mov.l L_hook_exec_jmp, r0 mov.l L_hook_stop_jmp, r1 mov.l L_hook_exec, r2 mov.l L_hook_stop, r3 mov.l r2, @r0 rts mov.l r3, @r1 .globl Csym(unhook_dsp) .type Csym(unhook_dsp), @functionCsym(unhook_dsp): mov.l L_hook_exec_jmp, r0 mov.l L_hook_stop_jmp, r1 mov.l L_ret_hook_exec, r2 mov.l L_ret_hook_stop, r3 mov.l r2, @r0 rts mov.l r3, @r1 .balign 4 L_hook_SR: .long SR_MD | SR_I(0) | SR_FD L_tcb_tskid: .long TCB_tskid L_tcb_state: .long TCB_state L_tskctxb_lsid2: .long TCB_tskctxb + CTXB_lsid L_hook_exec_jmp: .long hook_exec_jmp L_hook_stop_jmp: .long hook_stop_jmp L_hook_exec: .long hook_exec L_hook_stop: .long hook_stop L_ret_hook_exec: .long ret_hook_exec L_ret_hook_stop: .long ret_hook_stop L_hook_execfn: .long Csym(hook_execfn) L_hook_stopfn: .long Csym(hook_stopfn) .data .balign 4 hook_exec_jmp: .long ret_hook_exec hook_stop_jmp: .long ret_hook_stop#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ */#if USE_SH3_DSP/* * Save DSP context * void save_dspctx( T_COP0REGS *save_area ) */ .text .balign 2 .globl Csym(save_dspctx) .type Csym(save_dspctx), @functionCsym(save_dspctx): stc sr, r0 // SR save mov.l S_SR_DSP, r1 or r0, r1 ldc r1, sr // SR.DSP = 1 add #COP0_REGSZ, r4 stc.l mod, @-r4 // DSP context save stc.l re, @-r4 stc.l rs, @-r4 movs.l y1, @-r4 movs.l y0, @-r4 movs.l x1, @-r4 movs.l x0, @-r4 movs.l m1, @-r4 movs.l m0, @-r4 movs.w a1g, @-r4 movs.w a0g, @-r4 movs.l a1, @-r4 movs.l a0, @-r4 sts.l dsr, @-r4 ldc r0, sr // SR restore rts nop .balign 4 S_SR_DSP: .long SR_DSP#endif /* USE_SH3_DSP *//* ------------------------------------------------------------------------ */#if TA_FPU/* * FPU suppress exception * FPU context switch * High Address +---------------+ * | USP | Only RNG 1-3 * +---------------+ * | MDR (R2_BANK1)| RNG0-3 shared * | SSR | * | SPC | * ISP => | R0_BANK1 | * Low Address +---------------+ */ .text .balign 2 .globl Csym(unavailable_cop) .type Csym(unavailable_cop), @functionCsym(unavailable_cop): /* During interrupt disable SR.I=15 BL=1 RB=1 */ mov.l r4, @-ISP // R4_BANK1 save mov.l U_DisableIntSR, r7 // Free exception block/Enable FPU ldc r7, sr // SR.BL=0 RB=1 FD=0 mov.l r8, @-SP // Save register for work mov.l r9, @-SP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -