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