1 /* 2 * Common CPU TLB handling 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "config.h" 21 #include "cpu.h" 22 #include "exec/exec-all.h" 23 #include "exec/cputlb.h" 24 25 /* statistics */ 26 int tlb_flush_count; 27 28 static const CPUTLBEntry s_cputlb_empty_entry = { 29 .addr_read = -1, 30 .addr_write = -1, 31 .addr_code = -1, 32 .addend = -1, 33 }; 34 35 /* NOTE: 36 * If flush_global is true (the usual case), flush all tlb entries. 37 * If flush_global is false, flush (at least) all tlb entries not 38 * marked global. 39 * 40 * Since QEMU doesn't currently implement a global/not-global flag 41 * for tlb entries, at the moment tlb_flush() will also flush all 42 * tlb entries in the flush_global == false case. This is OK because 43 * CPU architectures generally permit an implementation to drop 44 * entries from the TLB at any time, so flushing more entries than 45 * required is only an efficiency issue, not a correctness issue. 46 */ 47 void tlb_flush(CPUArchState *env, int flush_global) 48 { 49 int i; 50 51 #if defined(DEBUG_TLB) 52 printf("tlb_flush:\n"); 53 #endif 54 /* must reset current TB so that interrupts cannot modify the 55 links while we are modifying them */ 56 env->current_tb = NULL; 57 58 for (i = 0; i < CPU_TLB_SIZE; i++) { 59 int mmu_idx; 60 61 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { 62 env->tlb_table[mmu_idx][i] = s_cputlb_empty_entry; 63 } 64 } 65 66 memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *)); 67 68 env->tlb_flush_addr = -1; 69 env->tlb_flush_mask = 0; 70 tlb_flush_count++; 71 } 72 73 static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr) 74 { 75 if (addr == (tlb_entry->addr_read & 76 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) || 77 addr == (tlb_entry->addr_write & 78 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) || 79 addr == (tlb_entry->addr_code & 80 (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 81 *tlb_entry = s_cputlb_empty_entry; 82 } 83 } 84 85 void tlb_flush_page(CPUArchState *env, target_ulong addr) 86 { 87 int i; 88 int mmu_idx; 89 90 #if defined(DEBUG_TLB) 91 printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr); 92 #endif 93 /* Check if we need to flush due to large pages. */ 94 if ((addr & env->tlb_flush_mask) == env->tlb_flush_addr) { 95 #if defined(DEBUG_TLB) 96 printf("tlb_flush_page: forced full flush (" 97 TARGET_FMT_lx "/" TARGET_FMT_lx ")\n", 98 env->tlb_flush_addr, env->tlb_flush_mask); 99 #endif 100 tlb_flush(env, 1); 101 return; 102 } 103 /* must reset current TB so that interrupts cannot modify the 104 links while we are modifying them */ 105 env->current_tb = NULL; 106 107 addr &= TARGET_PAGE_MASK; 108 i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 109 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { 110 tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr); 111 } 112 113 tb_flush_jmp_cache(env, addr); 114 } 115 116 /* update the TLBs so that writes to code in the virtual page 'addr' 117 can be detected */ 118 void tlb_protect_code(ram_addr_t ram_addr) 119 { 120 cpu_physical_memory_reset_dirty(ram_addr, 121 ram_addr + TARGET_PAGE_SIZE, 122 CODE_DIRTY_FLAG); 123 } 124 125 /* update the TLB so that writes in physical page 'phys_addr' are no longer 126 tested for self modifying code */ 127 void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr, 128 target_ulong vaddr) 129 { 130 cpu_physical_memory_set_dirty_flags(ram_addr, CODE_DIRTY_FLAG); 131 } 132 133 static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe) 134 { 135 return (tlbe->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM; 136 } 137 138 void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start, 139 uintptr_t length) 140 { 141 uintptr_t addr; 142 143 if (tlb_is_dirty_ram(tlb_entry)) { 144 addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend; 145 if ((addr - start) < length) { 146 tlb_entry->addr_write &= TARGET_PAGE_MASK; 147 tlb_entry->addr_write |= TLB_NOTDIRTY; 148 } 149 } 150 } 151 152 static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr) 153 { 154 if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY)) { 155 tlb_entry->addr_write = vaddr; 156 } 157 } 158 159 /* update the TLB corresponding to virtual page vaddr 160 so that it is no longer dirty */ 161 void tlb_set_dirty(CPUArchState *env, target_ulong vaddr) 162 { 163 int i; 164 int mmu_idx; 165 166 vaddr &= TARGET_PAGE_MASK; 167 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 168 for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { 169 tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr); 170 } 171 } 172 173 /* Our TLB does not support large pages, so remember the area covered by 174 large pages and trigger a full TLB flush if these are invalidated. */ 175 static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr, 176 target_ulong size) 177 { 178 target_ulong mask = ~(size - 1); 179 180 if (env->tlb_flush_addr == (target_ulong)-1) { 181 env->tlb_flush_addr = vaddr & mask; 182 env->tlb_flush_mask = mask; 183 return; 184 } 185 /* Extend the existing region to include the new page. 186 This is a compromise between unnecessary flushes and the cost 187 of maintaining a full variable size TLB. */ 188 mask &= env->tlb_flush_mask; 189 while (((env->tlb_flush_addr ^ vaddr) & mask) != 0) { 190 mask <<= 1; 191 } 192 env->tlb_flush_addr &= mask; 193 env->tlb_flush_mask = mask; 194 } 195 196 /* Add a new TLB entry. At most one entry for a given virtual address 197 is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the 198 supplied size is only used by tlb_flush_page. */ 199 void tlb_set_page(CPUArchState *env, target_ulong vaddr, 200 hwaddr paddr, int prot, 201 int mmu_idx, target_ulong size) 202 { 203 PhysPageDesc *p; 204 unsigned long pd; 205 unsigned int index; 206 target_ulong address; 207 target_ulong code_address; 208 ptrdiff_t addend; 209 CPUTLBEntry *te; 210 CPUWatchpoint *wp; 211 hwaddr iotlb; 212 213 assert(size >= TARGET_PAGE_SIZE); 214 if (size != TARGET_PAGE_SIZE) { 215 tlb_add_large_page(env, vaddr, size); 216 } 217 p = phys_page_find(paddr >> TARGET_PAGE_BITS); 218 if (!p) { 219 pd = IO_MEM_UNASSIGNED; 220 } else { 221 pd = p->phys_offset; 222 } 223 #if defined(DEBUG_TLB) 224 printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx 225 " prot=%x idx=%d pd=0x%08lx\n", 226 vaddr, paddr, prot, mmu_idx, pd); 227 #endif 228 229 address = vaddr; 230 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { 231 /* IO memory case (romd handled later) */ 232 address |= TLB_MMIO; 233 } 234 addend = (ptrdiff_t)qemu_get_ram_ptr(pd & TARGET_PAGE_MASK); 235 if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) { 236 /* Normal RAM. */ 237 iotlb = pd & TARGET_PAGE_MASK; 238 if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM) 239 iotlb |= IO_MEM_NOTDIRTY; 240 else 241 iotlb |= IO_MEM_ROM; 242 } else { 243 /* IO handlers are currently passed a physical address. 244 It would be nice to pass an offset from the base address 245 of that region. This would avoid having to special case RAM, 246 and avoid full address decoding in every device. 247 We can't use the high bits of pd for this because 248 IO_MEM_ROMD uses these as a ram address. */ 249 iotlb = (pd & ~TARGET_PAGE_MASK); 250 if (p) { 251 iotlb += p->region_offset; 252 } else { 253 iotlb += paddr; 254 } 255 } 256 257 code_address = address; 258 /* Make accesses to pages with watchpoints go via the 259 watchpoint trap routines. */ 260 QTAILQ_FOREACH(wp, &env->watchpoints, entry) { 261 if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) { 262 iotlb = io_mem_watch + paddr; 263 /* TODO: The memory case can be optimized by not trapping 264 reads of pages with a write breakpoint. */ 265 address |= TLB_MMIO; 266 } 267 } 268 269 index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 270 env->iotlb[mmu_idx][index] = iotlb - vaddr; 271 te = &env->tlb_table[mmu_idx][index]; 272 te->addend = addend - vaddr; 273 if (prot & PAGE_READ) { 274 te->addr_read = address; 275 } else { 276 te->addr_read = -1; 277 } 278 279 if (prot & PAGE_EXEC) { 280 te->addr_code = code_address; 281 } else { 282 te->addr_code = -1; 283 } 284 if (prot & PAGE_WRITE) { 285 if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 286 (pd & IO_MEM_ROMD)) { 287 /* Write access calls the I/O callback. */ 288 te->addr_write = address | TLB_MMIO; 289 } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 290 !cpu_physical_memory_is_dirty(pd)) { 291 te->addr_write = address | TLB_NOTDIRTY; 292 } else { 293 te->addr_write = address; 294 } 295 } else { 296 te->addr_write = -1; 297 } 298 } 299 300 /* NOTE: this function can trigger an exception */ 301 /* NOTE2: the returned address is not exactly the physical address: it 302 is the offset relative to phys_ram_base */ 303 tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) 304 { 305 int mmu_idx, page_index, pd; 306 void *p; 307 308 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 309 mmu_idx = cpu_mmu_index(env1); 310 if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code != 311 (addr & TARGET_PAGE_MASK))) { 312 cpu_ldub_code(env1, addr); 313 } 314 pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK; 315 if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { 316 #if defined(TARGET_SPARC) || defined(TARGET_MIPS) 317 cpu_unassigned_access(env1, addr, 0, 1, 0, 4); 318 #else 319 cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr); 320 #endif 321 } 322 p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend); 323 return qemu_ram_addr_from_host_nofail(p); 324 } 325 326 #define MMUSUFFIX _cmmu 327 #define SOFTMMU_CODE_ACCESS 328 329 #define SHIFT 0 330 #include "exec/softmmu_template.h" 331 332 #define SHIFT 1 333 #include "exec/softmmu_template.h" 334 335 #define SHIFT 2 336 #include "exec/softmmu_template.h" 337 338 #define SHIFT 3 339 #include "exec/softmmu_template.h" 340