📄 excmgr.c
字号:
system_down: BMS_DEBUG_PRINT(("\n***** OS SYSTEM DOWN *****\n")); BMS_DEBUG_PRINT(("INT:%03x PC:%08x SR:%08x TEA:%08x tid:%d\n", exccode, isp->spc, isp->ssr, excmsg.i.excaddr, excmsg.i.taskid)); tm_monitor(); /* To BMS */}/* * System exception handler entry */LOCAL void SysExcHdr( UW exccode, UW excinfo ){ ExcStack *isp; Asm("stc r6_bank, %0": "=r"(isp)); _SysExcHdr(exccode, excinfo, isp);}/* * Page fault handler * EXC_TLBINV_R 0x040 TLB invalid (read) * EXC_TLBINV_W 0x060 TLB invalid (write) * EXC_FIRSTWRITE 0x080 First writing to page * EXC_TLBPRO_W 0x0c0 TLB protection (write) * * exccode Exception code (EXPEVT) * excaddr Exception address (TEA) * tlbway TLB way (MMUCR) (*) No meaning in SH4. */EXPORT W PageFaultHdr( UW exccode, VP excaddr, UW tlbway ){//IMPORT W DebugMonitorFlag; /* debug.c */ struct { UW sp; UW r4_bank1; UW r0_bank1; ExcStack i; } *isp; PTH pth; PTE pte; ER er; DO_DEBUG( pte.w = TSD_PFH_VAL_M1; ) InitPTH(&pth, excaddr, 0); er = NextPTE(&pth); if ( er < E_OK ) { goto exception; /* Invalid access */ } pte.w = GetPTE(&pth); if ( pte.w == PTE_NONE ) { goto exception; /* Invalid access */ } if ( exccode == EXC_TLBPRO_W ) { /* If copy-on-write is not available: access violation */ if ( !((pte.c.cow != 0U) && (pte.c.w == 0U)) ) { goto exception; /* Access violation */ } } /* Set access bit */ (void)ChgPTE(&pth, PT_Accessed, ~PT_Accessed, FALSE); if ( ((exccode == EXC_TLBINV_R) || (exccode == EXC_TLBINV_W)) && (pte.c.p != 0) ) { /* TLB loading only */ LoadTLB(&pth, tlbway); } else if ( ((exccode == EXC_TLBINV_R) || (exccode == EXC_TLBINV_W)) && (pte.c.va != 0) && (SegLock.cnt < 0) ) { /* Since the page is valid, make page frame settings only. * However, if LockSEG() cannot be handled here, * pass it to an exception handling task. */ PFE *pfe = PFAtoPFE(pte.c.pfa); MovePageFrame(pfe, PFS_use); (void)ChgPTE(&pth, PT_Present, ~PT_Present, FALSE); LoadTLB(&pth, tlbway); } else if ( exccode == EXC_FIRSTWRITE ) { /* First writing: set dirty bit */ (void)ChgPTE(&pth, PT_Update, ~PT_Update, FALSE); LoadTLB(&pth, tlbway); } else { ExcMsg excmsg; Asm("stc r6_bank, %0": "=r"(isp)); memset(&excmsg, 0, sizeof(excmsg)); excmsg.i.exccode = exccode; excmsg.i.excaddr = (UW)excaddr; excmsg.pgfault = TRUE; /* Obtain intended task ID */ excmsg.i.taskid = er = tk_get_tid(); if ( er < E_OK ) { goto exception; } /* Handle it as exception if it occurred while a task independent section is executed or interrupt is disabled. */ if ( ((isp->i.ssr & SR_I(TSD_HDR_MSK_15)) > 0U) || TaskIndependent(&isp->i) ) { goto exception; } /* Suspend current task */ er = tk_sus_tsk(excmsg.i.taskid); if ( er < E_OK ) { goto exception; } /* Notify to exception handling task */ er = sendExcMsg(&excmsg); if ( er < E_OK ) { BMS_DEBUG_PRINT(("\nPageFaultHdr sendExcMsg er = %d\n", er)); goto exception; } } EndPTH(&pth, FALSE); return 0;exception: /* Exception not handled by segment management */ EndPTH(&pth, FALSE); BMS_DEBUG_PRINT(("PageFaultHdr exccode=0x%08x excaddr=0x%08x" " pte=0x%08x er=%d\n", exccode, excaddr, pte.w, er)); //if ( DebugMonitorFlag != 0 ) return 1; /* To BMS */ Asm("stc r6_bank, %0": "=r"(isp)); _SysExcHdr(exccode, 0, &isp->i); return 0;}/* * Provisional page fault handler * Used provisionally until T-Kernel/OS starts. * Switched to a regular page fault handler after T-Kernel/OS startup. * * EXC_TLBINV_R 0x040 TLB invalid (read) * EXC_TLBINV_W 0x060 TLB invalid (write) * EXC_FIRSTWRITE 0x080 First writing to page * * exccode Exception code (EXPEVT) * excaddr Exception address (TEA) * tlbway TLB way (MMUCR) (*) No meaning in SH4. */EXPORT void TmpPageFaultHdr( UW exccode, VP excaddr, UW tlbway ){ PTH pth; PTE pte; ER er; InitPTH(&pth, excaddr, 0); er = NextPTE(&pth); if ( er < E_OK ) { goto err_exit; } pte.w = GetPTE(&pth); if ( pte.w == PTE_NONE ) { goto err_exit; } if ( exccode == EXC_FIRSTWRITE ) { /* First writing: set dirty bit */ (void)ChgPTE(&pth, PT_Update, ~PT_Update, FALSE); } else if ( pte.c.p == 0 ) { /* Page-in */ er = PageIn(excaddr, 0); if ( er < E_OK ) { goto err_exit; } } LoadTLB(&pth, tlbway); EndPTH(&pth, FALSE); return;err_exit: BMS_DEBUG_PRINT(("TmpPageFaultHdr exccode=0x%08x excaddr=0x%08x" " pte=0x%08x er=%d\n", exccode, excaddr, pte.w, er)); tm_monitor();}/* ------------------------------------------------------------------------ *//* * Entry address of the monitor's default handler */IMPORT FP DefaultHandlerEntry;/* * Register/deregister system exception handler * regist = TRUE Register * regist = FALSE Deregister */EXPORT void RegistSysExcHdr( BOOL regist ){const UW DefaultHandler = TSD_RSH_DHL_0X1000; T_DINT dint; dint.intatr = TA_HLNG; dint.inthdr = SysExcHdr; tk_def_int(DefaultHandler, ( regist != 0 )? &dint: NULL);}/* * Register page fault handler */LOCAL ER RegistPageFaultHdr( void ){ T_DINT dint; ER er; /* Register other TLB-related exception handler */ dint.intatr = TA_ASM; dint.inthdr = asmPageFaultHdr; er = tk_def_int(EXC_TLBINV_R, &dint); if ( er < E_OK ) { goto err_ret; } er = tk_def_int(EXC_TLBINV_W, &dint); if ( er < E_OK ) { goto err_ret; } er = tk_def_int(EXC_FIRSTWRITE, &dint); if ( er < E_OK ) { goto err_ret; } er = tk_def_int(EXC_TLBPRO_W, &dint); if ( er < E_OK ) { goto err_ret; } return E_OK;err_ret: BMS_DEBUG_PRINT(("RegistPageFaultHdr er = %d\n", er)); return er;}/* * Register provisional page fault handler */EXPORT void RegistTmpPageFaultHdr( void ){ /* Save T-Monitor's default handler */ DefaultHandlerEntry = SCArea->defaulthdr; /* Register TLB miss exception handler */ SCArea->tlbmisshdr = asmTLBMissHdr; define_inthdr(EXC_TLBINV_R, asmTmpPageFaultHdr); define_inthdr(EXC_TLBINV_W, asmTmpPageFaultHdr); define_inthdr(EXC_FIRSTWRITE, asmTmpPageFaultHdr);}/* * Initialize system exception processing * (immediately after T-Kernel/OS startup) */EXPORT ER InitExcMgr( BOOL StartUp ){ T_CTSK ctsk; T_DINT dint; ER er; if ( !StartUp ) { /* Termination processing: deregister at least the exception handler. */ RegistSysExcHdr(FALSE); return E_OK; } /* Start system exception processing task */ SetOBJNAME(ctsk.exinf, "SExc"); ctsk.tskatr = TA_HLNG|TA_RNG0; ctsk.task = SysExcTsk; ctsk.itskpri = 1; ctsk.stksz = TSD_IEM_STK_2048; er = tk_cre_tsk(&ctsk); if ( er < E_OK ) { goto err_ret; } er = tk_sta_tsk(SysExcTskID = er, 0); if ( er < E_OK ) { goto err_ret; } /* Register page fault handler */ er = RegistPageFaultHdr(); if ( er < E_OK ) { goto err_ret; } /* Register BMS_KILL_PROC handler */ dint.intatr = TA_HLNG; dint.inthdr = SysExcHdr; er = tk_def_int(BMS_KILL_PROC << TSD_IEM_SFT_5, &dint); if ( er < E_OK ) { goto err_ret; } return E_OK;err_ret: BMS_DEBUG_PRINT(("InitExcMgr: er = %d\n", er)); return er;}/* ------------------------------------------------------------------------ *//* * Set TLB exception handler for re-startup processing */EXPORT void SetWarmBootTLBHdr( void ){IMPORT void warmBootTLBInvRHdr( void );IMPORT void warmBootTLBMissHdr( void ); SCArea->tlbmisshdr = warmBootTLBMissHdr; define_inthdr(EXC_TLBINV_R, warmBootTLBInvRHdr); *(_UW*)TTB = (UW)SATB;}/* ------------------------------------------------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -