/* * InitTLB * * Initialize the TLB to a power-up state, guaranteeing that all entries * are unique and invalid. * * Arguments: * a0 = Maximum TLB index (from MMUSize field of C0_Config1) * * Returns: * No value * * Restrictions: * This routine must be called in unmapped space * * Algorithm: * va = kseg0_base; * for (entry = max_TLB_index; entry >= 0, entry--) { * while (TLB_Probe_Hit(va)) { * va += Page_Size; * } * TLB_Write(entry, va, 0, 0, 0); * } * * Notes: * - The Hazard macros used in the code below expand to the appropriate * number of SSNOPs in an implementation of Release 1 of the * Architecture, and to an ehb in an implementation of Release 2 of * the Architecture. See , “CP0 Hazards,” on page 79 for * more additional information. */ InitTLB: /* * Clear PageMask, EntryLo0 and EntryLo1 so that valid bits are off, PFN values * are zero, and the default page size is used. */ mtc0 zero, C0_EntryLo0 /* Clear out PFN and valid bits */ mtc0 zero, C0_EntryLo1 mtc0 zero, C0_PageMask /* Clear out mask register * /* Start with the base address of kseg0 for the VA part of the TLB */ la t0, A_K0BASE /* A_K0BASE == 0x8000.0000 */ /* * Write the VA candidate to EntryHi and probe the TLB to see if if is * already there. If it is, a write to the TLB may cause a machine * check, so just increment the VA candidate by one page and try again. */ 10: mtc0 t0, C0_EntryHi /* Write VA candidate */ TLBP_Write_Hazard() /* Clear EntryHi hazard (ssnop/ehb in R1/2) */ tlbp /* Probe the TLB to check for a match */ TLBP_Read_Hazard() /* Clear Index hazard (ssnop/ehb in R1/2) */ mfc0 t1, C0_Index /* Read back flag to check for match */ bgez t1, 10b /* Branch if about to duplicate an entry */ addiu t0, (1<<S_EntryHiVPN2) /* Add 1 to VPN index in va */ /* * A write of the VPN candidate will be unique, so write this entry * into the next index, decrement the index, and continue until the * index goes negative (thereby writing all TLB entries) */ mtc0 a0, C0_Index /* Use this as next TLB index */ TLBW_Write_Hazard() /* Clear Index hazard (ssnop/ehb in R1/2) */ tlbwi /* Write the TLB entry */ bne a0, zero, 10b /* Branch if more TLB entries to do */ addiu a0, -1 /* Decrement the TLB index /* * Clear Index and EntryHi simply to leave the state constant for all * returns */ mtc0 zero, C0_Index mtc0 zero, C0_EntryHi jr ra /* Return to caller */ nop
va = Virtual Address for i in 0..TLBEntries-1: if(TLB[i].VPN2 = va31..13) && (TLB[i].G | TLB[i].ASID = EntryHi.ASID){ if va12 = 0 { pfn = TLB[i].PFN0 v = TLB[i].V0 c = TLB[i].C0 d = TLB[i].D0 }else{ pfn = TLB[i].PFN1 v = TLB[i].V1 c = TLB[i].C1 d = TLB[i].D1 } if v = 0 then SignalException(TLBInvalid, reftype) endif if(d = 0) && (reftype = store) then SignalException(TLBModified) endif pa = pfn19..0 || va11..0 found = 1 } if found = 0 then SignalException(TLBMiss, reftype) endif