|
3 | 3 | #include "csr/controlstate.h" |
4 | 4 | #include "machine.h" |
5 | 5 | #include "memory/virtual/page_table_walker.h" |
6 | | -#include "memory/virtual/sv32.h" |
7 | 6 |
|
8 | 7 | LOG_CATEGORY("machine.TLB"); |
9 | 8 |
|
@@ -64,6 +63,8 @@ void TLB::on_csr_write(size_t internal_id, RegisterValue val) { |
64 | 63 | update_all_statistics(); |
65 | 64 | } |
66 | 65 |
|
| 66 | + |
| 67 | + |
67 | 68 | void TLB::flush_single(VirtualAddress va, uint16_t asid) { |
68 | 69 | uint64_t vpn = va.get_raw() >> 12; |
69 | 70 | size_t s = set_index(vpn); |
@@ -111,7 +112,9 @@ void TLB::sync() { |
111 | 112 | Address TLB::translate_virtual_to_physical(Address vaddr) { |
112 | 113 | uint64_t virt = vaddr.get_raw(); |
113 | 114 |
|
114 | | - if (!vm_enabled) { return vaddr; } |
| 115 | + if (!vm_enabled || !translation_enabled || is_in_uncached_area(vaddr)) { |
| 116 | + return vaddr; |
| 117 | + } |
115 | 118 |
|
116 | 119 | constexpr unsigned PAGE_SHIFT = 12; |
117 | 120 | constexpr uint64_t PAGE_MASK = (1ULL << PAGE_SHIFT) - 1; |
@@ -191,6 +194,20 @@ bool TLB::reverse_lookup(Address paddr, VirtualAddress &out_va) const { |
191 | 194 | } |
192 | 195 | return false; |
193 | 196 | } |
| 197 | + |
| 198 | +void TLB::handle_control_signal(uint32_t ctrl_info) { |
| 199 | + CSR::PrivilegeLevel priv = unpack_priv(ctrl_info); |
| 200 | + uint16_t asid = unpack_asid(ctrl_info); |
| 201 | + |
| 202 | + bool satp_mode_on = is_mode_enabled_in_satp(current_satp_raw); |
| 203 | + bool should_translate = vm_enabled && satp_mode_on && (priv != CSR::PrivilegeLevel::MACHINE); |
| 204 | + |
| 205 | + if (translation_enabled != should_translate) { |
| 206 | + translation_enabled = should_translate; |
| 207 | + LOG("TLB: translation_enabled -> %d (ASID=%u)", (int)translation_enabled, asid); |
| 208 | + } |
| 209 | +} |
| 210 | + |
194 | 211 | bool TLB::is_in_uncached_area(Address source) const { |
195 | 212 | return (source >= uncached_start && source <= uncached_last); |
196 | 213 | } |
|
0 commit comments