[libre-riscv-dev] TLB Initial Proposal
Daniel Benusovich
flyingmonkeys1996 at gmail.com
Mon Feb 4 07:11:40 GMT 2019
Would you know why these messages are not going into the mailing list? I
noticed they are not in the log which is odd.
Also sorry for being absent for a bit. Filthy work trainings. Anyways.
The Address-Space Identifier (ASID) works similarly to a process ID.
> Basically, the operating system picks a different ASID when it needs a
> different page table. Having ASIDs allows not having to flush everything
> out of the TLB for every context switch, saving time.
>
> The ASID is a field in the pointer to the page table (the satp register).
> The TLB page table entry is different from the in-memory page table entry:
> 1. The TLB entry doesn't need to encode a non-accessible (non-leaf or
> otherwise) page table entry, allowing us to use the RWX = 0 encoding to
> represent an invalid entry.
> 2. The in-memory entry doesn't have an ASID because that section of the
> page table might be shared between multiple ASIDs to save memory. The TLB
> does have an ASID field to prevent needing to totally reload the whole TLB
> on context switch.
> 3. Probably something else I forgot.
>
Cool makes sense.
No, because there can be multiple entries in the TLB with the same virtual
> address and different ASIDs, and we need the CAM to differentiate between
> them.
>
So the ASID would need to be in the table entry or used as part of the
address selecting algorithm? IE the tag/index when translation the given
virtual memory address. We have to store that sucker somewhere and that
would add another 15 bits to the CAM size. This gives us 32 bit tag (if
fully associative) + 64 bit PTE + 15 bit ASID = 111 bits for the CAM size
which is nice and healthy.
The TLB is basically the MMU when the MMU is set to paged mode (Ignoring
> PMP), so, yes, the TLB should produce protection errors. I had been
> assuming that your implementing the TLB meant you were implementing the MMU.
>
Alrighty sounds good.
would need an input for translation mode, an input for access type (read,
> write, exec), an input for user/supervisor, an input for SUM (accessing
> user memory as supervisor), an input for reset, and an input for command
> (write PTE, clear, etc.).
>
For translation I see that we would need 4 bits to support RV64 mode
options which includes the Sv48 you wanted to have. That sound right?
Another three bits for each access type option (another 3), supervisor or
user (another 1), if supervisor has access (another 1), reset (1), and
commands (nothing, write PTE, reset, and other? lets just give it 2 bits
and call it a day with one command reserved for later).
With a grand total input bit count of: 12 bit command/protection + 48 bit
VMA + 15 bit ASID (rv64 support) + 64 bit PTE (sv48 support) = 139 bits.
ouchie my spleen.
Output would be: 1 bit hit/miss + 1 bit valid/(permission fault) + 64 bit
PTE (sv48 support) = 66 bits. Almost the devil but not quite.
So far this makes sense to me. We need to:
(a => success, b => fail)
1. Check if the VMU mapping exists in the table via Valid Bit
a. 2. Check ASID
a. 3. Check Permissions (read, write, execute, supervisor/user,
supervisor access && Send out the PTE
a. 4. Valid access
b. 4. Begone interloper. Permission fault
b. 3. Wrong address space buddy. Permission Fault
b. 2. Translate the VMU and find the page via walking
a. 3. Write the PTE entry into the TLB while sending the PTE (if
permissions match) to the cache
b. 3. Page Fault. OS should do this part. Eventually the TLB shall be
loaded maybe? :)
To recap:
111 bit CAM entry size
139 bit input to TLB
66 bit output from TLB
Does that sound good? If it does I will start writing the TLB up in nmigen.
More information about the libre-riscv-dev
mailing list