Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIPS: add TLB debugging features #54

Open
vhotspur opened this issue Jan 3, 2024 · 3 comments
Open

MIPS: add TLB debugging features #54

vhotspur opened this issue Jan 3, 2024 · 3 comments

Comments

@vhotspur
Copy link
Member

vhotspur commented Jan 3, 2024

It would be useful if in some mode (perhaps we can abuse -t for this?) MSIM would warn about possibly wrong use of TLB.

  • Set TS field (TLB shutdown) in DS (diagnostic status) of status register to 1 if more entries match (and possibly print a warning?)

    • This should help especially for situations when TLB is used for the first time and contains ASID 0 for all entries
    • Should conform to section 4.1, paragraph Multiple Matches that states: If more than one entry in the TLB matches the virtual address being translated, the operation is undefined. To prevent permanent damage to the part, the TLB may be disabled if more than several entries match. The TLB-Shutdown (TS) bit in the Status register is set to 1 if the TLB is disabled.
  • Perhaps warn if multiple physical frames are accessible via different virtual addresses?

    • This should be enabled with some specific flag only as it is completely fine that this happens for shared memory but usually indicates a bug in toy kernels.
@vhotspur
Copy link
Member Author

vhotspur commented Jan 3, 2024

Both of above should be checked when TLBWI and TLBWR are executed: if such combination of VPN and ASID already exists, we should print a warning.

Setting TS should be done only when entries are read, hence it is a more expensive check (but we might propagate this information from checks in TLBWI/TLBWR).

@vhotspur
Copy link
Member Author

vhotspur commented Jan 3, 2024

And for future reference, some interesting links:

https://student.cs.uwaterloo.ca/~cs350/common/sys161manual/mips.html

One must never load the TLB in such a fashion that two (or more) entries can match the same virtual address. If this happens, the processor shuts down and is unrecoverable except by hard reset. Since there is no way to prevent entries from matching, one should clear the TLB by loading each entry with a distinct VPAGE, and use VPAGEs from the kseg0 or kseg1 regions that will never be presented to the MMU for translation. To reset the TLB at startup, since it is not cleared by processor reset, one should use a second, potentially larger, set of distinct VPAGEs and check that each is not already present before loading it.

https://github.com/torvalds/linux/blob/master/arch/mips/mm/tlb-r4k.c (invalidation uses unique addresses from KSEG to mark entry as ignored/invalid; code below is simplified).

#define _UNIQUE_ENTRYHI(base, idx) (((base) + ((idx) << (PAGE_SHIFT + 1)))
#define UNIQUE_ENTRYHI(idx) _UNIQUE_ENTRYHI(0x80000000, idx)
write_c0_entryhi(UNIQUE_ENTRYHI(entry));

https://www.spinics.net/lists/mips/msg12390.html

I'm told the TLB Shutdown bit in the R4000 is basically implemented as an overcurrent protection. That is on many chips even a hit on several entries won't cause a tlb shutdown until the matches do result in the TLB drawing more than a certain current.

@vhotspur
Copy link
Member Author

vhotspur commented Jan 3, 2024

It might be best if TLB is initialized so that entry->vpn2 points to KSEG (the way Linux invalidates TLB entries) so that the check of if ((virt.lo & entry->mask) == entry->vpn2) { never hits on an entry that was not yet written to (at the moment, both entry->mask and entry->vpn2 are zero and the condition is always true).

Debug dump of TLB can still check for mask == 0 to print a special line for not yet initialized entry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant