📄 cpu_support.s
字号:
/* *---------------------------------------------------------------------- * micro T-Kernel * * Copyright (C) 2006-2007 by Ken Sakamura. All rights reserved. * micro T-Kernel is distributed under the micro T-License. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2007/03/26. * *---------------------------------------------------------------------- *//* * cpu_support.S (H8S2212) * 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 "utk_config.h"#if USE_TRAP | (USE_DBGSPT & USE_HOOK_TRACE)#include "isysconf.h"#endif#include "tkdev_conf.h"#include "offset.h"/* ------------------------------------------------------------------------ *//* * 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. * _ret_int_dispatch: * Called when dispatch is required by 'tk_ret_int().' * * Contexts to save * Save registers except for SP to a stack. Save SP to TCB. * * High Address +---------------+ * | SPC(24bit) | * | | Saved by interrupt entry * | SCCR(8bit) | routines until here. * +---------------+ * | ER0 | * | ER1 | * | ER2 | * | ER3 | * | ER4 | * | ER5 | * Saved to TCB SP => | ER6 | * Low Address +---------------+ *//* Temporal stack used when 'dispatch_to_schedtsk' is called */ .h8300s .text .balign 2 .globl Csym(knl_dispatch_to_schedtsk) .globl Csym(knl_dispatch_entry)Csym(knl_dispatch_to_schedtsk): /* During interrupt disable SR.I=15 BL=0 RB=0 */ mov.l #(Csym(knl_tmp_stack) + TMP_STACK_SZ), er7 // Set temporal stack sub.l er0, er0 inc.l #1, er0 // er0 := 1 mov.l er0, @Csym(knl_dispatch_disabled) // Dispatch disable mov.l #Csym(knl_ctxtsk), er6 // er6 := &ctxtsk#if USE_DBGSPT mov.l @er6, er1 // er1 := ctxtsk#endif sub.l er0, er0 mov.l er0, @er6 // ctxtsk = NULL andc #CCR_EI_MASK, ccr // Interrupt enable bra l_dispatch0Csym(knl_dispatch_entry): /* During interrupt disable SR.I=15 BL=1 RB=1 */#if USE_TRAP mov.w @er7, r0 and.b #CCR_EI_MASK, r0h mov.w r0, @er7 // SSR compensation (I=0)#else mov.w @er7, r0 stc ccr, r0h and.b #CCR_EI_MASK, r0h mov.w r0, @er7#endif_ret_int_dispatch: /* During interrupt disable SR.I=15 BL=0 RB=1 */ sub.l er0, er0 inc.l #1, er0 // er0 := 1 mov.l er0, @Csym(knl_dispatch_disabled) // Dispatch disable andc #CCR_EI_MASK, ccr // Interrupt enable stm.l (er0-er3), @-er7 // Context save stm.l (er4-er6), @-er7 mov.l #Csym(knl_ctxtsk), er6 // er6 := &ctxtsk mov.l @er6, er1 mov.l er7, @(TCB_tskctxb + CTXB_ssp, er1) // Save SSP to TCB l_dispatch0: /* During interrupt enable CPSR.I=0 F=0 */#if USE_DBGSPT & USE_HOOK_TRACE mov.l @hook_stop_jmp, er0 // Hook processing jmp @er0 ret_hook_stop:#endif l_dispatch1: orc #CCR_I, ccr // Interrupt disable mov.l @Csym(knl_schedtsk), er5 // ER5 = schedtsk // Is there 'schedtsk'? bne l_dispatch2 /* Because there is no task that should be executed, move to the power-saving mode */ mov.l @Csym(knl_lowpow_discnt), er0 // Is 'low_pow' disabled? bne l_dispatch11 jsr @Csym(knl_low_pow) // call low_pow() l_dispatch11: andc #CCR_EI_MASK, ccr // Interrupt enable bra l_dispatch1 l_dispatch2: // Switch to 'schedtsk' /* During interrupt disable SR.I=15 BL=0 RB=1 SH3:DSP=1 */ mov.l er5, @er6 // ctxtsk = schedtsk mov.l @(TCB_tskctxb + CTXB_ssp, er5), er7 // Restore SSP from TCB#if USE_DBGSPT & USE_HOOK_TRACE mov.l @hook_exec_jmp, er0 // Hook processing jmp @er0 ret_hook_exec:#endif sub.l er1, er1 mov.l er1, @Csym(knl_dispatch_disabled) // Dispatch enable ldm.l @er7+, (er4-er6) // Context restore ldm.l @er7+, (er0-er3) rte#if USE_DBGSPT & USE_HOOK_TRACE/* * Task dispatcher hook routine call * void stop( ID tskid, INT lsid, UINT tskstat ) * void exec( ID tskid, INT lsid ) */ .text .balign 2hook_stop: mov.l er1, er1 // er1 = ctxtsk beq ret_hook_stop // no task mov.b @(TCB_state, er1), r2l // tskstat shll.b r2l extu.w r2 mov.w @(TCB_tskid, er1), r0 // tskid mov.l @Csym(knl_hook_stopfn), er3 jsr @er3 // call stop(tskid, lsid, tskstat) jmp ret_hook_stophook_exec: stc ccr, r4l // SR save andc #CCR_EI_MASK, ccr /* SR.I=0 BL=0 RB=0 */ mov.l @er6, er1 // er1 = ctxtsk mov.w @(TCB_tskid, er1), r0 // tskid mov.l @Csym(knl_hook_execfn), er3 jsr @er3 // call exec(tskid, lsid) ldc r4l, ccr // SR restore jmp ret_hook_exec/* * Set/Free task dispatcher hook routine */ .text .balign 2 .globl Csym(knl_hook_dsp)Csym(knl_hook_dsp): mov.l #hook_exec, er2 mov.l #hook_stop, er3 mov.l er2, @hook_exec_jmp mov.l er3, @hook_stop_jmp rts .globl Csym(knl_unhook_dsp)Csym(knl_unhook_dsp): mov.l #ret_hook_exec, er2 mov.l #ret_hook_stop, er3 mov.l er2, @hook_exec_jmp mov.l er3, @hook_stop_jmp rts .data .balign 4 hook_exec_jmp: .long ret_hook_exec hook_stop_jmp: .long ret_hook_stop#endif /* USE_DBGSPT & USE_HOOK_TRACE */#if USE_HLL_INTHDR/* ------------------------------------------------------------------------ *//* * 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 +---------------+ * | SPC(24bit) | * | SCCR(8bit) | * | er0 | * ISP => | er1 | * Low Address +---------------+ * * er0 = intno */ .text .balign 2 .globl Csym(knl_inthdr_startup)Csym(knl_inthdr_startup): /* During interrupt disable SR.I=15 BL=0 RB=0 */ stm.l (er2-er3), @-er7 // er0-er1 are already saved stm.l (er4-er6), @-er7 mov.l @Csym(knl_taskindp), er6 // enter task independent mode inc.l #1, er6 mov.l er6, @Csym(knl_taskindp) mov.l @Csym(knl_int_nest), er2 // interrupt nest count mov.l er2, er5 inc.l #1, er2 mov.l er2, @Csym(knl_int_nest) mov.l er5, er5 bne l_no_change_sp // multiple interrupt mov.l er7, er2 mov.l #RI_INTSTACK, er7 // change to ISP mov.l er2, @-er7 // SSP save l_no_change_sp:#if USE_DBGSPT & USE_HOOK_TRACE mov.l @hook_ienter_jmp, er3 jmp @er3 ret_hook_ienter:#endif shll.l #2, er0 // offset = dintno << 2 mov.l @(Csym(knl_hll_inthdr), er0), er3 // call hll_inthdr[n](dintno) jsr @er3#if USE_DBGSPT & USE_HOOK_TRACE mov.l @hook_ileave_jmp, er3 jmp @er3 ret_hook_ileave:#endif orc.b #CCR_I, ccr // Interrupt disable /* During interrupt disable SR.I=15 BL=0 RB=0 */ mov.l er5, er5 bne l_no_change_sp2 // multiple interrupt mov.l @er7+, er2 // er2 = SSP mov.l er2, er7l_no_change_sp2: dec.l #1, er6 mov.l er6, @Csym(knl_taskindp) ldm.l @er7+, (er4-er6) ldm.l @er7+, (er2-er3)#if USE_TRAP trapa #TRAP_RETINT // tk_ret_int()#else jmp @Csym(tk_ret_int_impl)#endif#if USE_DBGSPT & USE_HOOK_TRACE/* * Interrupt handler hook routine call */ .text .balign 2hook_ienter: mov.l er0, @-er7 // Save dintno mov.l @Csym(knl_hook_ienterfn), er3 jsr @er3 // call enter(dintno) mov.l @er7, er0 // er0 restore jmp ret_hook_ienterhook_ileave: mov.l @er7+, er0 // dintno mov.l @Csym(knl_hook_ileavefn), er3 jsr @er3 // call leave(dintno) jmp ret_hook_ileave/* * Set/Free interrupt handler hook routine */ .text .balign 2 .globl Csym(knl_hook_int)Csym(knl_hook_int): mov.l #hook_ienter, er2 mov.l #hook_ileave, er3 mov.l er2, @hook_ienter_jmp mov.l er3, @hook_ileave_jmp rts .globl Csym(knl_unhook_int)Csym(knl_unhook_int): mov.l #ret_hook_ienter, er2 mov.l #ret_hook_ileave, er3 mov.l er2, @hook_ienter_jmp mov.l er3, @hook_ileave_jmp rts .data .balign 4 hook_ienter_jmp: .long ret_hook_ienter hook_ileave_jmp: .long ret_hook_ileave#endif /* USE_DBGSPT & USE_HOOK_TRACE */#endif /* USE_HLL_INTHDR *//* * _tk_ret_int() * * tk_ret_int() processing * When called, the interrupt stack is configured as shown below. * High Address +---------------+ * | SPC(24bit) | Saved when interrupt occur * | SCCR(8bit) | * | ER0(32bit) | * SSP => | ER1(32bit) | * +---------------+ * | SPC(24bit) | Save by 'trapa TRAP_RETINT' * SSP => | SCCR(8bit) | * Low Address +---------------+ */ .text .balign 2 .globl Csym(tk_ret_int_impl)Csym(tk_ret_int_impl): /* During interrupt disable SR.I=15 BL=1 RB=1 */#if USE_TRAP add.l #4, er7 // Trash parts saved by 'trapa TRAP_RETINT'#endif mov.l @Csym(knl_int_nest), er0 // Is it a nesting interrupt? dec.l #1, er0 mov.l er0, @Csym(knl_int_nest) bne l_nodispatch mov.w @(2*4, er7), r0 // CCR when EIT occurs and.b #CCR_I, r0h // Is it an exception during interrupt disable? bne l_nodispatch mov.l @Csym(knl_dispatch_disabled), er0 // Is it during dispatch disable? bne l_nodispatch mov.l @Csym(knl_ctxtsk), er0 // Is dispatch required? mov.l @Csym(knl_schedtsk), er1 cmp er0, er1 beq l_nodispatch ldm.l @er7+, (er0-er1) // ER0, ER1 restore jmp _ret_int_dispatch // To dispatch processing l_nodispatch: // Dispatch not required ldm.l @er7+, (er0-er1) // ER0, ER1 restore rte/* ------------------------------------------------------------------------ */#if USE_TRAP | USE_DBGSPT | CFN_MAX_SSYID > 0/* * Unsupported system call
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -