tum-ei-eda / etiss

Extendable Translating Instruction Set Simulator
https://tum-ei-eda.github.io/etiss/
Other
29 stars 36 forks source link

RISC-V MMU Rework #113

Open js97nMH opened 2 years ago

js97nMH commented 2 years ago

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:

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:

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.