📄 cpu_init.c
字号:
/* *---------------------------------------------------------------------- * 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_init.c (VR4131) * CPU-Dependent Initialization/Finalization */#include "kernel.h"#include "task.h"#include "cpu_insn.h"#include "cpu_task.h"EXPORT MONHDR SaveMonHdr; /* For saving monitor exception handler */EXPORT VP int_stack_top; /* Exception stack top */EXPORT ATR available_cop; /* Enabled coprocessor */EXPORT UW initPSR; /* PSR DS part at system startup */#if TA_FPUEXPORT TCB *fpu_ctxtsk; /* Task including FPU context */#endif/* * CPU-dependant initialization */EXPORT ER cpu_initialize( void ){IMPORT void delayed_interrupt( void ); /* Delayed interrupt (Task dispatcher) */IMPORT void unavailable_cop( void ); /* Coprocessor disable exception */IMPORT void call_entry( void ); /* System call */IMPORT void rettex_entry( void ); /* Return from task exception handler */IMPORT void call_dbgspt( void ); /* Debugger support call */ UW occ; /* Save monitor exception handler */ SaveMonHdr.default_hdr = SCArea->intvec[VECNO_DEFAULT]; SaveMonHdr.interrupt_hdr = SCArea->intvec[VECNO_INTERRUPT]; SaveMonHdr.syscall_hdr = SCArea->intvec[VECNO_SYSCALL]; SaveMonHdr.watch_hdr = SCArea->intvec[VECNO_WATCH]; SaveMonHdr.monitor_hdr = SCArea->intvec[VECNO_MONITOR]; SaveMonHdr.break_hdr = SCArea->intvec[VECNO_BREAK]; SaveMonHdr.ip2_hdr = SCArea->intvec[VECNO_IP2]; SaveMonHdr.gpio_hdr = SCArea->intvec[VECNO_GPIO]; SaveMonHdr.fpga_hdr = SCArea->intvec[VECNO_FPGA]; /* Clear software interrupt in CP0 cause register */ Asm("mfc0 %0, $13": "=r"(occ)); occ &= ~(OC_IP(0)|OC_IP(1)); Asm("mtc0 %0, $13 ; nop":: "r"(occ)); /* Get CP0 status register */ Asm("mfc0 %0, $12": "=r"(initPSR)); initPSR &= SR_DS; /* Leave only DS part */ /* CP0 status register initial value setting */ Asm("mtc0 %0, $12":: "r"(initPSR | _INIT_PSR)); /* Keep exception stack top */ int_stack_top = SCInfo.istkpos; /* Enabled coprocessor */ available_cop = TA_FPU;#if TA_FPU fpu_ctxtsk = NULL;#endif /* Register exception handler used on OS */ define_inthdr(CALL_SVC, call_entry); define_inthdr(CALL_RETTEX, rettex_entry); define_inthdr(EIT_IP(1), delayed_interrupt);#if TA_FPU define_inthdr(EIT_EXC(11), unavailable_cop);#endif#if USE_DBGSPT define_inthdr(CALL_DEBUG, call_dbgspt);#endif return E_OK;}/* * CPU-dependant finalization */EXPORT void cpu_shutdown( void ){ /* Restore saved monitor exception handler */ SCArea->intvec[VECNO_DEFAULT] = SaveMonHdr.default_hdr; SCArea->intvec[VECNO_INTERRUPT] = SaveMonHdr.interrupt_hdr; SCArea->intvec[VECNO_SYSCALL] = SaveMonHdr.syscall_hdr; SCArea->intvec[VECNO_WATCH] = SaveMonHdr.watch_hdr; SCArea->intvec[VECNO_MONITOR] = SaveMonHdr.monitor_hdr; SCArea->intvec[VECNO_BREAK] = SaveMonHdr.break_hdr; SCArea->intvec[VECNO_IP2] = SaveMonHdr.ip2_hdr; SCArea->intvec[VECNO_GPIO] = SaveMonHdr.gpio_hdr; SCArea->intvec[VECNO_FPGA] = SaveMonHdr.fpga_hdr;}/* ------------------------------------------------------------------------- *//* * Task exception handler startup reservation */EXPORT void request_tex( TCB *tcb ){ /* Cannot set to the task operating at protected level 0 */ if ( tcb->isysmode == 0 ) { tcb->reqdct = 1; }}/* * Task exception handler startup setting * * First stack state * System stack User stack * +---------------+ +---------------+ * ssp -> | t8 | usp -> | (xxxxxxxxxxx) | * +8 | t9 | | | * +16 | EPC | * +24 | PSR||taskmode | High:PSR Low:taskmode * +32 | usp | * +---------------+ * * Stack state after change (Change *) * +---------------+ +---------------+ * ssp -> | t8 | usp* -> | texcd |* * +8 | t9 | +8 | retadr (EPC) |* * +16 | texhdr |* +---------------+ * +24 | PSR||taskmode | | (xxxxxxxxxxx) | * +32 | usp |* * +---------------+ */EXPORT void setup_texhdr( DW *ssp ){ FP texhdr; INT texcd; UINT m; DW *usp; /* Called in interrupt disable state */ ctxtsk->reqdct = 0; /* Free DCT */ /* Get exception code */ m = 0x00000001; for ( texcd = 0; texcd <= 31; texcd++ ) { if ( (ctxtsk->exectex & m) != 0 ) break; m <<= 1; } /* Exception does not occur /Exception is freed */ if ( texcd > 31 ) return; ctxtsk->exectex = 0; ctxtsk->pendtex &= ~m; ctxtsk->texflg |= ( texcd == 0 )? TEX0_RUNNING: TEX1_RUNNING; texhdr = ctxtsk->texhdr; usp = (DW*)ssp[4].lo; /* If the exception code is 0, return the user stack to the initial value */ if ( texcd == 0 ) usp = ctxtsk->istack; usp -= 2; /* Set user stack pointer */ SetDW(&ssp[4], (INT)usp);#if TA_FPU /* If an interrupt is enabled, a task dispatch may occur. * This may cause the FPU context switched. * To avoid this, set FPU disabled. */ ssp[3].hi &= ~SR_CU1;#endif ENABLE_INTERRUPT; /* Stack coordination * A page fault may occur * due to access to the user stack. */ SetDW(&usp[0], texcd); usp[1] = ssp[2]; /* retadr */ SetDW(&ssp[2], (INT)texhdr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -