33#include " csr/controlstate.h"
44#include " machine.h"
55#include " memory/virtual/page_table_walker.h"
6- #include " memory/virtual/sv32.h"
76
87LOG_CATEGORY (" machine.TLB" );
98
109namespace machine {
1110
12- static bool is_mmio_region (uint64_t virt) {
13- if (virt >= 0xFFFFC000u && virt <= 0xFFFFC1FFu ) return true ;
14- if (virt >= 0xFFE00000u && virt <= 0xFFE4AFFFu ) return true ;
15- if (virt >= 0xFFFD0000u && virt <= 0xFFFDBFFFu ) return true ;
16- return false ;
17- }
18-
19- static Address bypass_mmio (Address vaddr) {
20- return vaddr; // VA == PA for devices
11+ inline bool is_mode_enabled_in_satp (uint32_t satp_raw) {
12+ return (satp_raw & (1u << 31 )) != 0 ;
2113}
2214
2315TLB::TLB (
@@ -31,6 +23,8 @@ TLB::TLB(
3123 bool memory_access_enable_b)
3224 : FrontendMemory(memory->simulated_machine_endian)
3325 , mem(memory)
26+ , uncached_start(0xf0000000_addr)
27+ , uncached_last(0xfffffffe_addr)
3428 , type(type_)
3529 , tlb_config(config)
3630 , vm_enabled(vm_enabled)
@@ -73,6 +67,18 @@ void TLB::on_csr_write(size_t internal_id, RegisterValue val) {
7367 update_all_statistics ();
7468}
7569
70+ void TLB::on_privilege_changed (CSR::PrivilegeLevel new_priv) {
71+ if (new_priv == current_priv_) return ;
72+
73+ current_priv_ = new_priv;
74+ flush ();
75+ LOG (" TLB: privilege changed -> %d; flushed TLB" , static_cast <int >(new_priv));
76+ }
77+
78+ bool TLB::is_in_uncached_area (Address source) const {
79+ return (source >= uncached_start && source <= uncached_last);
80+ }
81+
7682void TLB::flush_single (VirtualAddress va, uint16_t asid) {
7783 uint64_t vpn = va.get_raw () >> 12 ;
7884 size_t s = set_index (vpn);
@@ -119,9 +125,11 @@ void TLB::sync() {
119125
120126Address TLB::translate_virtual_to_physical (Address vaddr) {
121127 uint64_t virt = vaddr.get_raw ();
122- if (is_mmio_region (virt)) { return bypass_mmio (vaddr); }
123128
124- if (!vm_enabled) { return vaddr; }
129+ if (!vm_enabled || current_priv_ == CSR::PrivilegeLevel::MACHINE
130+ || !is_mode_enabled_in_satp (current_satp_raw) || is_in_uncached_area (vaddr)) {
131+ return vaddr;
132+ }
125133
126134 constexpr unsigned PAGE_SHIFT = 12 ;
127135 constexpr uint64_t PAGE_MASK = (1ULL << PAGE_SHIFT) - 1 ;
0 commit comments