pub struct Tlb { /* private fields */ }Expand description
The joint TLB plus its instruction micro-TLB.
Implementations§
Source§impl Tlb
impl Tlb
Sourcepub const fn new() -> Self
pub const fn new() -> Self
A TLB in its power-on state.
The manual calls the reset contents undefined (UM §6.4.4, p. 183) and ADR 0004 requires reproducibility, so a fixed state must be chosen — but all-zero is not a usable choice, and that is not obvious.
Zeroing gives all 32 entries VPN2 = 0 and ASID = 0. Since V does
not participate in matching, any access to virtual page-pair 0 then
matches all 32 entries at once, which is the TLB-shutdown condition — so
the very first KUSEG access to low memory would brick the TLB.
Each entry therefore gets a distinct VPN2 near the top of the
field, so no two coincide and none sits where software is likely to look.
Recorded as accuracy-ledger D-4: a deliberate deviation, chosen
because real hardware powers up with arbitrary contents that do not
coincide, and zero is the one arbitrary value that does.
Sourcepub const fn is_shutdown(&self) -> bool
pub const fn is_shutdown(&self) -> bool
Has the TLB shut down? “the processor must be reset to restart” (UM Fig. 6-6, p. 167).
Sourcepub const fn page_size(mask: u32) -> u64
pub const fn page_size(mask: u32) -> u64
The page size an entry maps, in bytes, from its PageMask.
PageMask bits 24:13 select 4K…16M (UM Table 5-7, p. 149). “When the
Mask field is not one of the values shown in Table 5-7, the operation of
the TLB is undefined” — we take the mask at face value, which is a
documented-undefined choice rather than a hardware fact.
Sourcepub const fn pair_size(mask: u32) -> u64
pub const fn pair_size(mask: u32) -> u64
The size of the even/odd pair an entry covers — twice
Tlb::page_size, and the granularity the VPN2 tag is compared at.
Sourcepub fn lookup(
&mut self,
vaddr: u64,
asid: u8,
store: bool,
) -> Result<Translated, TlbFault>
pub fn lookup( &mut self, vaddr: u64, asid: u8, store: bool, ) -> Result<Translated, TlbFault>
Sourcepub fn write_entry(&mut self, index: usize, cop0: &Cop0)
pub fn write_entry(&mut self, index: usize, cop0: &Cop0)
TLBWI / TLBWR — write EntryHi/EntryLo0/EntryLo1/PageMask into
entry index.
Sourcepub fn read_entry(&self, index: usize, cop0: &mut Cop0)
pub fn read_entry(&self, index: usize, cop0: &mut Cop0)
TLBR — read entry index back into the COP0 registers.
Sourcepub fn probe(&self, cop0: &mut Cop0)
pub fn probe(&self, cop0: &mut Cop0)
TLBP — probe for an entry matching the current EntryHi.
Sets Index to the matching index, or sets Index.P (bit 31) on a miss:
“Set to 1 when the previous TLBProbe (TLBP) instruction was
unsuccessful” (UM §5.4.1, p. 146).
What the low bits hold on a miss is undocumented (accuracy-ledger U-2). This implementation leaves them zero — a guess, not a fact.
Sourcepub fn jtlb_has_match(&self, vaddr: u64, asid: u8) -> bool
pub fn jtlb_has_match(&self, vaddr: u64, asid: u8) -> bool
Does any entry match, without translating or shutting down?
Used by the instruction-fetch path to decide whether a micro-TLB reload can actually happen: the 3-PCycle penalty is “incurred when the micro-TLB is updated from the JTLB” (UM §4.6.2), so a lookup that misses the JTLB too must not be charged for a reload that never occurred.
Sourcepub fn itlb_probe(&mut self, vaddr: u64, asid: u8) -> bool
pub fn itlb_probe(&mut self, vaddr: u64, asid: u8) -> bool
Probe the instruction micro-TLB, reporting whether it hit.
A miss costs ITLB_MISS_PCYCLES and is a stall, not an exception —
the JTLB is then consulted, and only a JTLB miss raises.