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

RISC-V MMU Rework #113

Open
wants to merge 77 commits into
base: master
Choose a base branch
from
Open

Conversation

js97nMH
Copy link

@js97nMH js97nMH commented May 25, 2022

ETISS

This section lists changes made to ETISS that are independent of the Instruction Set Architecture.

Simulation Loop

Removing Address Translation before calling GetBlockFast() and cache flushing. Adding call to exception handler if fetching block failed with error-code extracted from translation object.

Translation Cache Flush

Added function unloadBlocksAll() that efficiently flushes ETISS' translation cache. That function is called by unloadBlocks() if the entire cache is to be flushed.

Exception Handling

Statement added after the architecture dependent trap handler is called in etiss_CPUCore_handleException() to flush ETISS' translation cache if necessary.

Architecture Independent MMU

MMU System Wrapper Plugin

Memory access functions in DMMUWrapper.cpp have been altered to allow for accesses over a page boundary.

Address Translation

The address translation function MMU::Translate() has been changed to also calculate the page overlap, by calling function GetPageOverlap(). It also calls the function UpdatePTEFlags () to change PTE flags when a page is accessed and relay the changes back to memory to be visible by software running on the simulator.

TLB Entry Eviction

The function MMU::EvictTLBEntry() has been added. It can be called to evict a PTE from the TLB and the tlb_entry_map_.

PTE Creation

An overload to function PTE::Update() has been added, which stores two additional attributes in the PTE object. The first is the page table level pte_lvl_, which is used for calculating the page boundary overlap. The second is the physical address of the PTE pte_addr_, which is used during PTE eviction and flag updates to memory.

Cache Flush

The function ETISS_TLB_FLUSH() can be called by instructions to flush ETISS’ translation cache and the TLB.
The function ETISS_TLB_EVICT_VMA() can be called by instructions to evict a virtual address from ETISS’ translation cache and the TLB. It calls the function MMU::EvictTLBEntry() to evict the corresponding PTE and returns the error-code RELOADBLOCKS to flush ETISS' translation cache. In the future only those blocks that contain the virtual page should be evicted, but for now this is not possible.

RISC-V

This section lists the changes made to the RISCV64 architecture implementation in ETISS.

Exception Handling

The exception handling in function RISCV64Arch::handleException() was appended to more granularly differentiate between page faults, since different register assignments are performed. When a trap is delegated to M-mode, the return value is set to RELOADBLOCKS to flush the translation cache, since when transitioning to M-mode, address translation is paused.

Architecture Dependent MMU

MMU Update

The function RISCV64MMU::SignalMMU() updates the internal state of the MMU object. A CSR instruction, that modifies the satp register, calls this function. Depending on the MODE bitfield value, the MMU is either enabled or disabled. Then the the modified CSR value is stored in the MMU object's attribute mmu_control_reg_val_.

Memory Protection

The function RISCV64MMU::CheckProtection() is called by the address translation function and enforces memory protection. A switch statement checks if the requested page can be accessed with the current privilege level. If a privilege violation occurs, a second switch statement returns the correct exception, depending on the access type.

PTE Flag Update

The RISCV64MMU::UpdatePTEFlags() function is called by the address translation function to update the PTE flags when accessing the respective page, and propagating the change to main memory, to be visible by software. If the A -accessed- flag is not yet set, it is set now and the PTE is written back to memory. If the D -dirty- flag is not yet set and the page is accessed to write, the flag is now set and the PTE is written back to memory.

Page Boundary Overlap

The function RISCV64MMU::GetPageOverlap() is called by the address translation function to calculate an overlap over a virtual page boundary. The virtual address of the following page iscalculated from the page table level and the original virtual address. From that, the overlap can be calculated. If no positive overlap was calculated, zero is returned, representing no overlap. Otherwise, the positive overlap is returned.

Page Table Walk

The function RISCV64MMU::WalkPageTable() is modified to set the stval and mtval CSRs with the virtual address, that caused the page fault, if a page fault occurs.

Manual Changes to RISC-V Instructions

Load Instructions

The load instructions are modified by moving the exception check and return statements in front of the destination register assignment. This change has to be included in all load instructions. They include:

  • lb, lbu, lh, lhu, lw, lwu, and ld from the base integer ISA
  • flw and fld from the floating-point extension
  • lr.w and lr.d from the atomic memory operation extension

Store Instructions

A if statement replaces a solitary return statement to increase performance by not returning if no exception occured. This is functionally not necessary but an optional improvement. The change presented here has to be included in all load instructions. They include:

  • sb, sh, sw, and sd from the base integer ISA
  • fsw and fsd from the floating-point extension
  • sc.w and sc.d from the atomic memory operation extension

CSR Instructions

At the end of the instruction definition of the CSR instructions the line partInit.code() += "return ret;\n"; is added, to return to the main simulation loop to flush ETISS’ translation cache.

SFENCE.VMA Instruction

At the end of the instruction definition of SFENCE.VMA the line partInit.code() += "return ret;\n"; is manually added to return to the main simulation loop for translation cache flushing.

js97nMH and others added 30 commits January 11, 2022 14:38
create new main branch for project
This reverts commit 32e0000.

revert to previous commit
js97nMH and others added 29 commits April 14, 2022 17:10
Memory access over page boundary

Implementing a way to access memory over a page boundary.
DMMUWrapper splits a memory access that overlaps a page in two accesses.
Address translations have to be performed for both accesses.
Rework of PTE-updates and SFENCE.VMA

This reworks the way that PTEs get updated, when their linked page is accessed or written to.
Previously this was done only when a PTE was loaded into the TLB by a Page-Table-Walk.
Now PTEs that are already in the TLB can be updated as well, ensuring that all flags are set correctly.

This rework also includes an updated SFENCE.VMA, which can now evict single addresses from the TLB.
Reloading blocks with that address is not yet implemented.
@js97nMH js97nMH marked this pull request as ready for review June 5, 2022 14:44
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

Successfully merging this pull request may close these issues.

1 participant