📄 excmgr.c
字号:
"BVA:%08x %08x tid:%d\n", vecno, isp->epc.hi, isp->epc.lo, isp->psr, isp->taskmode, badvaddr.hi, badvaddr.lo, excmsg.i.taskid)); tm_monitor(); /* To BMS */ return 0;}/* ------------------------------------------------------------------------ *//* * Page fault handler * EXC_TLBINV_L TLB invalid (load) * EXC_TLBINV_S TLB invalid (store) * EXC_TLBMOD TLB changed (first writing) */EXPORT W PageFaultHdr( UINT vecno, DW badvaddr ){IMPORT W DebugMonitorFlag; /* debug.c */ PTH pth; PTE pte; VP excaddr; UW chg; BOOL cow; ER er; DO_DEBUG( pte.w = TSD_PFH_VAL_M1; ) if ( (W)badvaddr.lo >= 0 ) { if ( badvaddr.hi != 0 ) { goto exception1; } } else { if ( badvaddr.hi != TSD_PFH_VAL_EM1 ) { goto exception1; } } excaddr = (VP)badvaddr.lo; InitPTH(&pth, excaddr, 0); er = NextPTE(&pth); if ( er < E_OK ) { goto exception2; /* Invalid access */ } pte.w = GetPTE(&pth); if ( pte.w == (UW)PTE_NONE ) { goto exception2; /* Invalid access */ } cow = FALSE; chg = PT_Accessed; if ( vecno == EXC_TLBMOD ) { if ( pte.c.w == 0 ) { /* If copy-on-write is not available: access violation */ if ( pte.c.cow == 0 ) { goto exception2; } cow = TRUE; } chg |= (UW)PT_Update; } /* Set access bit/dirty bit */ (void)ChgPTE(&pth, chg, ~0U, FALSE); if ( (pte.c.p != 0) && !cow ) { /* TLB loading only */ LoadTLB(&pth); } else if ( (pte.c.va != 0) && (SegLock.cnt < 0) && !cow ) { /* 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, ~0U, FALSE); LoadTLB(&pth); } else { ExcMsg excmsg; ExcStack *isp; ID tid; isp = SCInfo.istkpos; /* Obtain intended task ID */ tid = tk_get_tid(); if ( tid <= 0 ) { goto exception2; } memset(&excmsg, 0, (size_t)sizeof(excmsg)); excmsg.i.taskid = tid; excmsg.i.vecno = vecno; excmsg.i.badvaddr = badvaddr; excmsg.pgfault = TRUE; /* Handle it as exception if it occurred while a task independent section is executed or interrupt is disabled. */ if ( ((isp->psr & ((UW)SR_ERL | (UW)SR_IE)) != (UW)SR_IE) || TaskIndependent(isp) ) { goto exception2; } /* Suspend current task */ er = tk_sus_tsk(tid); if ( er < E_OK ) { goto exception2; } /* Notify to exception handling task */ er = sendExcMsg(&excmsg); if ( er < E_OK ) { BMS_DEBUG_PRINT(("\nPageFaultHdr sendExcMsg er = %d\n", er)); goto exception2; } } EndPTH(&pth, FALSE); return 0;exception2: /* Exception not handled by segment management */ EndPTH(&pth, FALSE);exception1: BMS_DEBUG_PRINT(( "PageFaultHdr vecno=%d badvaddr=%08x %08x pte=%08x er=%d\n", vecno, badvaddr.hi, badvaddr.lo, pte.w, er)); if ( DebugMonitorFlag != 0 ) { return 1; /* To monitor */ } return SysExcHdr(vecno, badvaddr);}/* * Provisional page fault handler * Used provisionally until T-Kernel starts. * Switched to a regular page fault handler after T-Kernel startup. * * EXC_TLBINV_L TLB invalid (load) * EXC_TLBINV_S TLB invalid (store) * EXC_TLBMOD TLB changed (first writing) */EXPORT W TmpPageFaultHdr( UINT vecno, DW badvaddr ){ PTH pth; PTE pte; VP excaddr; ER er; excaddr = (VP)badvaddr.lo; InitPTH(&pth, excaddr, 0); er = NextPTE(&pth); if ( er < E_OK ) { goto err_exit; } pte.w = GetPTE(&pth); if ( pte.w == (UW)PTE_NONE ) { goto err_exit; } if ( vecno == EXC_TLBMOD ) { /* First writing: set dirty bit */ (void)ChgPTE(&pth, PT_Update, ~0U, FALSE); } else if ( pte.c.p == 0 ) { /* Page-in */ er = PageIn(excaddr, 0); if ( er < E_OK ) { goto err_exit; } } LoadTLB(&pth); EndPTH(&pth, FALSE); return 0;err_exit: BMS_DEBUG_PRINT(( "TmpPageFaultHdr vecno=%d badvaddr=%08x %08x pte=%08x er=%d\n", vecno, badvaddr.hi, badvaddr.lo, pte.w, er)); return 1; /* To monitor */}/* ------------------------------------------------------------------------ *//* * Entry processing by exception handler */IMPORT void asmSysExcHdr( void );IMPORT void asmPageFaultHdr( void );IMPORT void asmTLBMissHdr( void );/* * Address of page fault handler * Address of handler called by asmPageFaultHdr() */EXPORT W (*pPageFaultHdr)( UINT vecno, DW badvaddr );/* * Entry address of the monitor's default handler */EXPORT FP DefaultHandlerEntry;/* * Register/deregister system exception handler * regist = TRUE Register * regist = FALSE Deregister */EXPORT void RegistSysExcHdr( BOOL regist ){ T_DINT dint; dint.intatr = TA_ASM; dint.inthdr = asmSysExcHdr; tk_def_int(EIT_DEFAULT, ( regist != 0 )? &dint: NULL);}/* * Register page fault handler */LOCAL ER RegistPageFaultHdr( void ){ T_DINT dint; ER er; /* Register TLB-related exception handler */ dint.intatr = TA_ASM; dint.inthdr = asmPageFaultHdr; pPageFaultHdr = PageFaultHdr; er = tk_def_int(EXC_TLBINV_L, &dint); if ( er < E_OK ) { goto err_ret; } er = tk_def_int(EXC_TLBINV_S, &dint); if ( er < E_OK ) { goto err_ret; } er = tk_def_int(EXC_TLBMOD, &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->intvec[EIT_DEFAULT]; /* Register TLB miss exception handler */ define_inthdr(EXC_TLBMISS, asmTLBMissHdr); define_inthdr(EXC_XTLBMISS, asmTLBMissHdr); /* Register provisional page fault handler */ pPageFaultHdr = TmpPageFaultHdr; define_inthdr(EXC_TLBMOD, asmPageFaultHdr); define_inthdr(EXC_TLBINV_L, asmPageFaultHdr); define_inthdr(EXC_TLBINV_S, asmPageFaultHdr);}/* * Initialize system exception processing * (immediately after T-Kernel 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_4096; 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_ASM; dint.inthdr = asmSysExcHdr; er = tk_def_int(BMS_KILL_PROC, &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 warmBootTLBInvLHdr( void ); define_inthdr(EXC_TLBMISS, asmTLBMissHdr); define_inthdr(EXC_XTLBMISS, asmTLBMissHdr); define_inthdr(EXC_TLBINV_L, warmBootTLBInvLHdr);}/* ------------------------------------------------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -