Commit 84b7b8e778937f1ec3cbdb8914261a2fe0067ef2

Authored by bellard
1 parent 5cf38396

PAGE_EXEC support in TLBs


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1676 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-defs.h
... ... @@ -80,7 +80,8 @@ typedef unsigned long ram_addr_t;
80 80 #define TB_JMP_CACHE_BITS 12
81 81 #define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
82 82  
83   -#define CPU_TLB_SIZE 256
  83 +#define CPU_TLB_BITS 8
  84 +#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
84 85  
85 86 typedef struct CPUTLBEntry {
86 87 /* bit 31 to TARGET_PAGE_BITS : virtual address
... ... @@ -89,7 +90,9 @@ typedef struct CPUTLBEntry {
89 90 bit 3 : indicates that the entry is invalid
90 91 bit 2..0 : zero
91 92 */
92   - target_ulong address;
  93 + target_ulong addr_read;
  94 + target_ulong addr_write;
  95 + target_ulong addr_code;
93 96 /* addend to virtual address to get physical address */
94 97 target_phys_addr_t addend;
95 98 } CPUTLBEntry;
... ... @@ -105,8 +108,7 @@ typedef struct CPUTLBEntry {
105 108 target_ulong mem_write_vaddr; /* target virtual addr at which the \
106 109 memory was written */ \
107 110 /* 0 = kernel, 1 = user */ \
108   - CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; \
109   - CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; \
  111 + CPUTLBEntry tlb_table[2][CPU_TLB_SIZE]; \
110 112 struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
111 113 \
112 114 /* from this point: preserved by CPU reset */ \
... ...
exec-all.h
... ... @@ -98,9 +98,17 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
98 98 void tb_invalidate_page_range(target_ulong start, target_ulong end);
99 99 void tlb_flush_page(CPUState *env, target_ulong addr);
100 100 void tlb_flush(CPUState *env, int flush_global);
101   -int tlb_set_page(CPUState *env, target_ulong vaddr,
102   - target_phys_addr_t paddr, int prot,
103   - int is_user, int is_softmmu);
  101 +int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
  102 + target_phys_addr_t paddr, int prot,
  103 + int is_user, int is_softmmu);
  104 +static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
  105 + target_phys_addr_t paddr, int prot,
  106 + int is_user, int is_softmmu)
  107 +{
  108 + if (prot & PAGE_READ)
  109 + prot |= PAGE_EXEC;
  110 + return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
  111 +}
104 112  
105 113 #define CODE_GEN_MAX_SIZE 65536
106 114 #define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
... ... @@ -554,15 +562,15 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
554 562 #else
555 563 #error unimplemented CPU
556 564 #endif
557   - if (__builtin_expect(env->tlb_read[is_user][index].address !=
  565 + if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
558 566 (addr & TARGET_PAGE_MASK), 0)) {
559 567 ldub_code(addr);
560 568 }
561   - pd = env->tlb_read[is_user][index].address & ~TARGET_PAGE_MASK;
  569 + pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
562 570 if (pd > IO_MEM_ROM) {
563 571 cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
564 572 }
565   - return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
  573 + return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
566 574 }
567 575 #endif
568 576  
... ...
... ... @@ -1209,10 +1209,12 @@ void tlb_flush(CPUState *env, int flush_global)
1209 1209 env->current_tb = NULL;
1210 1210  
1211 1211 for(i = 0; i < CPU_TLB_SIZE; i++) {
1212   - env->tlb_read[0][i].address = -1;
1213   - env->tlb_write[0][i].address = -1;
1214   - env->tlb_read[1][i].address = -1;
1215   - env->tlb_write[1][i].address = -1;
  1212 + env->tlb_table[0][i].addr_read = -1;
  1213 + env->tlb_table[0][i].addr_write = -1;
  1214 + env->tlb_table[0][i].addr_code = -1;
  1215 + env->tlb_table[1][i].addr_read = -1;
  1216 + env->tlb_table[1][i].addr_write = -1;
  1217 + env->tlb_table[1][i].addr_code = -1;
1216 1218 }
1217 1219  
1218 1220 memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
... ... @@ -1230,9 +1232,16 @@ void tlb_flush(CPUState *env, int flush_global)
1230 1232  
1231 1233 static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
1232 1234 {
1233   - if (addr == (tlb_entry->address &
1234   - (TARGET_PAGE_MASK | TLB_INVALID_MASK)))
1235   - tlb_entry->address = -1;
  1235 + if (addr == (tlb_entry->addr_read &
  1236 + (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
  1237 + addr == (tlb_entry->addr_write &
  1238 + (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
  1239 + addr == (tlb_entry->addr_code &
  1240 + (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
  1241 + tlb_entry->addr_read = -1;
  1242 + tlb_entry->addr_write = -1;
  1243 + tlb_entry->addr_code = -1;
  1244 + }
1236 1245 }
1237 1246  
1238 1247 void tlb_flush_page(CPUState *env, target_ulong addr)
... ... @@ -1249,10 +1258,8 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1249 1258  
1250 1259 addr &= TARGET_PAGE_MASK;
1251 1260 i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1252   - tlb_flush_entry(&env->tlb_read[0][i], addr);
1253   - tlb_flush_entry(&env->tlb_write[0][i], addr);
1254   - tlb_flush_entry(&env->tlb_read[1][i], addr);
1255   - tlb_flush_entry(&env->tlb_write[1][i], addr);
  1261 + tlb_flush_entry(&env->tlb_table[0][i], addr);
  1262 + tlb_flush_entry(&env->tlb_table[1][i], addr);
1256 1263  
1257 1264 for(i = 0; i < TB_JMP_CACHE_SIZE; i++) {
1258 1265 tb = env->tb_jmp_cache[i];
... ... @@ -1295,10 +1302,10 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
1295 1302 unsigned long start, unsigned long length)
1296 1303 {
1297 1304 unsigned long addr;
1298   - if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1299   - addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
  1305 + if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
  1306 + addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
1300 1307 if ((addr - start) < length) {
1301   - tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
  1308 + tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1302 1309 }
1303 1310 }
1304 1311 }
... ... @@ -1340,9 +1347,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1340 1347 start1 = start + (unsigned long)phys_ram_base;
1341 1348 for(env = first_cpu; env != NULL; env = env->next_cpu) {
1342 1349 for(i = 0; i < CPU_TLB_SIZE; i++)
1343   - tlb_reset_dirty_range(&env->tlb_write[0][i], start1, length);
  1350 + tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
1344 1351 for(i = 0; i < CPU_TLB_SIZE; i++)
1345   - tlb_reset_dirty_range(&env->tlb_write[1][i], start1, length);
  1352 + tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
1346 1353 }
1347 1354  
1348 1355 #if !defined(CONFIG_SOFTMMU)
... ... @@ -1378,11 +1385,11 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
1378 1385 {
1379 1386 ram_addr_t ram_addr;
1380 1387  
1381   - if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1382   - ram_addr = (tlb_entry->address & TARGET_PAGE_MASK) +
  1388 + if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
  1389 + ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
1383 1390 tlb_entry->addend - (unsigned long)phys_ram_base;
1384 1391 if (!cpu_physical_memory_is_dirty(ram_addr)) {
1385   - tlb_entry->address |= IO_MEM_NOTDIRTY;
  1392 + tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
1386 1393 }
1387 1394 }
1388 1395 }
... ... @@ -1392,19 +1399,19 @@ void cpu_tlb_update_dirty(CPUState *env)
1392 1399 {
1393 1400 int i;
1394 1401 for(i = 0; i < CPU_TLB_SIZE; i++)
1395   - tlb_update_dirty(&env->tlb_write[0][i]);
  1402 + tlb_update_dirty(&env->tlb_table[0][i]);
1396 1403 for(i = 0; i < CPU_TLB_SIZE; i++)
1397   - tlb_update_dirty(&env->tlb_write[1][i]);
  1404 + tlb_update_dirty(&env->tlb_table[1][i]);
1398 1405 }
1399 1406  
1400 1407 static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
1401 1408 unsigned long start)
1402 1409 {
1403 1410 unsigned long addr;
1404   - if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
1405   - addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
  1411 + if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
  1412 + addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
1406 1413 if (addr == start) {
1407   - tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_RAM;
  1414 + tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM;
1408 1415 }
1409 1416 }
1410 1417 }
... ... @@ -1418,17 +1425,17 @@ static inline void tlb_set_dirty(CPUState *env,
1418 1425  
1419 1426 addr &= TARGET_PAGE_MASK;
1420 1427 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1421   - tlb_set_dirty1(&env->tlb_write[0][i], addr);
1422   - tlb_set_dirty1(&env->tlb_write[1][i], addr);
  1428 + tlb_set_dirty1(&env->tlb_table[0][i], addr);
  1429 + tlb_set_dirty1(&env->tlb_table[1][i], addr);
1423 1430 }
1424 1431  
1425 1432 /* add a new TLB entry. At most one entry for a given virtual address
1426 1433 is permitted. Return 0 if OK or 2 if the page could not be mapped
1427 1434 (can only happen in non SOFTMMU mode for I/O pages or pages
1428 1435 conflicting with the host address space). */
1429   -int tlb_set_page(CPUState *env, target_ulong vaddr,
1430   - target_phys_addr_t paddr, int prot,
1431   - int is_user, int is_softmmu)
  1436 +int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
  1437 + target_phys_addr_t paddr, int prot,
  1438 + int is_user, int is_softmmu)
1432 1439 {
1433 1440 PhysPageDesc *p;
1434 1441 unsigned long pd;
... ... @@ -1436,6 +1443,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
1436 1443 target_ulong address;
1437 1444 target_phys_addr_t addend;
1438 1445 int ret;
  1446 + CPUTLBEntry *te;
1439 1447  
1440 1448 p = phys_page_find(paddr >> TARGET_PAGE_BITS);
1441 1449 if (!p) {
... ... @@ -1445,7 +1453,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
1445 1453 }
1446 1454 #if defined(DEBUG_TLB)
1447 1455 printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
1448   - vaddr, paddr, prot, is_user, is_softmmu, pd);
  1456 + vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
1449 1457 #endif
1450 1458  
1451 1459 ret = 0;
... ... @@ -1465,29 +1473,30 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
1465 1473  
1466 1474 index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1467 1475 addend -= vaddr;
  1476 + te = &env->tlb_table[is_user][index];
  1477 + te->addend = addend;
1468 1478 if (prot & PAGE_READ) {
1469   - env->tlb_read[is_user][index].address = address;
1470   - env->tlb_read[is_user][index].addend = addend;
  1479 + te->addr_read = address;
  1480 + } else {
  1481 + te->addr_read = -1;
  1482 + }
  1483 + if (prot & PAGE_EXEC) {
  1484 + te->addr_code = address;
1471 1485 } else {
1472   - env->tlb_read[is_user][index].address = -1;
1473   - env->tlb_read[is_user][index].addend = -1;
  1486 + te->addr_code = -1;
1474 1487 }
1475 1488 if (prot & PAGE_WRITE) {
1476 1489 if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
1477 1490 /* ROM: access is ignored (same as unassigned) */
1478   - env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
1479   - env->tlb_write[is_user][index].addend = addend;
  1491 + te->addr_write = vaddr | IO_MEM_ROM;
1480 1492 } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
1481 1493 !cpu_physical_memory_is_dirty(pd)) {
1482   - env->tlb_write[is_user][index].address = vaddr | IO_MEM_NOTDIRTY;
1483   - env->tlb_write[is_user][index].addend = addend;
  1494 + te->addr_write = vaddr | IO_MEM_NOTDIRTY;
1484 1495 } else {
1485   - env->tlb_write[is_user][index].address = address;
1486   - env->tlb_write[is_user][index].addend = addend;
  1496 + te->addr_write = address;
1487 1497 }
1488 1498 } else {
1489   - env->tlb_write[is_user][index].address = -1;
1490   - env->tlb_write[is_user][index].addend = -1;
  1499 + te->addr_write = -1;
1491 1500 }
1492 1501 }
1493 1502 #if !defined(CONFIG_SOFTMMU)
... ... @@ -1586,9 +1595,9 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1586 1595 {
1587 1596 }
1588 1597  
1589   -int tlb_set_page(CPUState *env, target_ulong vaddr,
1590   - target_phys_addr_t paddr, int prot,
1591   - int is_user, int is_softmmu)
  1598 +int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
  1599 + target_phys_addr_t paddr, int prot,
  1600 + int is_user, int is_softmmu)
1592 1601 {
1593 1602 return 0;
1594 1603 }
... ... @@ -2052,6 +2061,41 @@ uint32_t ldl_phys(target_phys_addr_t addr)
2052 2061 return val;
2053 2062 }
2054 2063  
  2064 +/* warning: addr must be aligned */
  2065 +uint64_t ldq_phys(target_phys_addr_t addr)
  2066 +{
  2067 + int io_index;
  2068 + uint8_t *ptr;
  2069 + uint64_t val;
  2070 + unsigned long pd;
  2071 + PhysPageDesc *p;
  2072 +
  2073 + p = phys_page_find(addr >> TARGET_PAGE_BITS);
  2074 + if (!p) {
  2075 + pd = IO_MEM_UNASSIGNED;
  2076 + } else {
  2077 + pd = p->phys_offset;
  2078 + }
  2079 +
  2080 + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
  2081 + /* I/O case */
  2082 + io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
  2083 +#ifdef TARGET_WORDS_BIGENDIAN
  2084 + val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
  2085 + val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
  2086 +#else
  2087 + val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
  2088 + val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
  2089 +#endif
  2090 + } else {
  2091 + /* RAM case */
  2092 + ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
  2093 + (addr & ~TARGET_PAGE_MASK);
  2094 + val = ldq_p(ptr);
  2095 + }
  2096 + return val;
  2097 +}
  2098 +
2055 2099 /* XXX: optimize */
2056 2100 uint32_t ldub_phys(target_phys_addr_t addr)
2057 2101 {
... ... @@ -2068,14 +2112,6 @@ uint32_t lduw_phys(target_phys_addr_t addr)
2068 2112 return tswap16(val);
2069 2113 }
2070 2114  
2071   -/* XXX: optimize */
2072   -uint64_t ldq_phys(target_phys_addr_t addr)
2073   -{
2074   - uint64_t val;
2075   - cpu_physical_memory_read(addr, (uint8_t *)&val, 8);
2076   - return tswap64(val);
2077   -}
2078   -
2079 2115 /* warning: addr must be aligned. The ram page is not masked as dirty
2080 2116 and the code inside is not invalidated. It is useful if the dirty
2081 2117 bits are used to track modified PTEs */
... ...
softmmu_header.h
... ... @@ -93,6 +93,11 @@
93 93 #define RES_TYPE int
94 94 #endif
95 95  
  96 +#if ACCESS_TYPE == 3
  97 +#define ADDR_READ addr_code
  98 +#else
  99 +#define ADDR_READ addr_read
  100 +#endif
96 101  
97 102 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
98 103 int is_user);
... ... @@ -101,6 +106,8 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE
101 106 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
102 107 (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
103 108  
  109 +#define CPU_TLB_ENTRY_BITS 4
  110 +
104 111 static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
105 112 {
106 113 int res;
... ... @@ -120,7 +127,7 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
120 127 "movl %%eax, %0\n"
121 128 "jmp 2f\n"
122 129 "1:\n"
123   - "addl 4(%%edx), %%eax\n"
  130 + "addl 12(%%edx), %%eax\n"
124 131 #if DATA_SIZE == 1
125 132 "movzbl (%%eax), %0\n"
126 133 #elif DATA_SIZE == 2
... ... @@ -133,10 +140,10 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
133 140 "2:\n"
134 141 : "=r" (res)
135 142 : "r" (ptr),
136   - "i" ((CPU_TLB_SIZE - 1) << 3),
137   - "i" (TARGET_PAGE_BITS - 3),
  143 + "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
  144 + "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
138 145 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
139   - "m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)),
  146 + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
140 147 "i" (CPU_MEM_INDEX),
141 148 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
142 149 : "%eax", "%ecx", "%edx", "memory", "cc");
... ... @@ -169,7 +176,7 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
169 176 #endif
170 177 "jmp 2f\n"
171 178 "1:\n"
172   - "addl 4(%%edx), %%eax\n"
  179 + "addl 12(%%edx), %%eax\n"
173 180 #if DATA_SIZE == 1
174 181 "movsbl (%%eax), %0\n"
175 182 #elif DATA_SIZE == 2
... ... @@ -180,10 +187,10 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
180 187 "2:\n"
181 188 : "=r" (res)
182 189 : "r" (ptr),
183   - "i" ((CPU_TLB_SIZE - 1) << 3),
184   - "i" (TARGET_PAGE_BITS - 3),
  190 + "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
  191 + "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
185 192 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
186   - "m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)),
  193 + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
187 194 "i" (CPU_MEM_INDEX),
188 195 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
189 196 : "%eax", "%ecx", "%edx", "memory", "cc");
... ... @@ -216,7 +223,7 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
216 223 "popl %%eax\n"
217 224 "jmp 2f\n"
218 225 "1:\n"
219   - "addl 4(%%edx), %%eax\n"
  226 + "addl 8(%%edx), %%eax\n"
220 227 #if DATA_SIZE == 1
221 228 "movb %b1, (%%eax)\n"
222 229 #elif DATA_SIZE == 2
... ... @@ -232,10 +239,10 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
232 239 /* NOTE: 'q' would be needed as constraint, but we could not use it
233 240 with T1 ! */
234 241 "r" (v),
235   - "i" ((CPU_TLB_SIZE - 1) << 3),
236   - "i" (TARGET_PAGE_BITS - 3),
  242 + "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
  243 + "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
237 244 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
238   - "m" (*(uint32_t *)offsetof(CPUState, tlb_write[CPU_MEM_INDEX][0].address)),
  245 + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
239 246 "i" (CPU_MEM_INDEX),
240 247 "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
241 248 : "%eax", "%ecx", "%edx", "memory", "cc");
... ... @@ -256,11 +263,11 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
256 263 addr = ptr;
257 264 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
258 265 is_user = CPU_MEM_INDEX;
259   - if (__builtin_expect(env->tlb_read[is_user][index].address !=
  266 + if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
260 267 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
261 268 res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
262 269 } else {
263   - physaddr = addr + env->tlb_read[is_user][index].addend;
  270 + physaddr = addr + env->tlb_table[is_user][index].addend;
264 271 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
265 272 }
266 273 return res;
... ... @@ -277,17 +284,19 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
277 284 addr = ptr;
278 285 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
279 286 is_user = CPU_MEM_INDEX;
280   - if (__builtin_expect(env->tlb_read[is_user][index].address !=
  287 + if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
281 288 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
282 289 res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
283 290 } else {
284   - physaddr = addr + env->tlb_read[is_user][index].addend;
  291 + physaddr = addr + env->tlb_table[is_user][index].addend;
285 292 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
286 293 }
287 294 return res;
288 295 }
289 296 #endif
290 297  
  298 +#if ACCESS_TYPE != 3
  299 +
291 300 /* generic store macro */
292 301  
293 302 static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
... ... @@ -300,16 +309,20 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
300 309 addr = ptr;
301 310 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
302 311 is_user = CPU_MEM_INDEX;
303   - if (__builtin_expect(env->tlb_write[is_user][index].address !=
  312 + if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
304 313 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
305 314 glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
306 315 } else {
307   - physaddr = addr + env->tlb_write[is_user][index].addend;
  316 + physaddr = addr + env->tlb_table[is_user][index].addend;
308 317 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
309 318 }
310 319 }
311 320  
312   -#endif
  321 +#endif /* ACCESS_TYPE != 3 */
  322 +
  323 +#endif /* !asm */
  324 +
  325 +#if ACCESS_TYPE != 3
313 326  
314 327 #if DATA_SIZE == 8
315 328 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
... ... @@ -355,6 +368,8 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
355 368 }
356 369 #endif /* DATA_SIZE == 4 */
357 370  
  371 +#endif /* ACCESS_TYPE != 3 */
  372 +
358 373 #undef RES_TYPE
359 374 #undef DATA_TYPE
360 375 #undef DATA_STYPE
... ... @@ -363,3 +378,4 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
363 378 #undef DATA_SIZE
364 379 #undef CPU_MEM_INDEX
365 380 #undef MMUSUFFIX
  381 +#undef ADDR_READ
... ...
softmmu_template.h
... ... @@ -41,8 +41,10 @@
41 41  
42 42 #ifdef SOFTMMU_CODE_ACCESS
43 43 #define READ_ACCESS_TYPE 2
  44 +#define ADDR_READ addr_code
44 45 #else
45 46 #define READ_ACCESS_TYPE 0
  47 +#define ADDR_READ addr_read
46 48 #endif
47 49  
48 50 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
... ... @@ -83,9 +85,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
83 85 /* XXX: could done more in memory macro in a non portable way */
84 86 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
85 87 redo:
86   - tlb_addr = env->tlb_read[is_user][index].address;
  88 + tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
87 89 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
88   - physaddr = addr + env->tlb_read[is_user][index].addend;
  90 + physaddr = addr + env->tlb_table[is_user][index].addend;
89 91 if (tlb_addr & ~TARGET_PAGE_MASK) {
90 92 /* IO access */
91 93 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -122,9 +124,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
122 124  
123 125 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
124 126 redo:
125   - tlb_addr = env->tlb_read[is_user][index].address;
  127 + tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
126 128 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
127   - physaddr = addr + env->tlb_read[is_user][index].addend;
  129 + physaddr = addr + env->tlb_table[is_user][index].addend;
128 130 if (tlb_addr & ~TARGET_PAGE_MASK) {
129 131 /* IO access */
130 132 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -199,9 +201,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
199 201  
200 202 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
201 203 redo:
202   - tlb_addr = env->tlb_write[is_user][index].address;
  204 + tlb_addr = env->tlb_table[is_user][index].addr_write;
203 205 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
204   - physaddr = addr + env->tlb_write[is_user][index].addend;
  206 + physaddr = addr + env->tlb_table[is_user][index].addend;
205 207 if (tlb_addr & ~TARGET_PAGE_MASK) {
206 208 /* IO access */
207 209 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -237,9 +239,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
237 239  
238 240 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
239 241 redo:
240   - tlb_addr = env->tlb_write[is_user][index].address;
  242 + tlb_addr = env->tlb_table[is_user][index].addr_write;
241 243 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
242   - physaddr = addr + env->tlb_write[is_user][index].addend;
  244 + physaddr = addr + env->tlb_table[is_user][index].addend;
243 245 if (tlb_addr & ~TARGET_PAGE_MASK) {
244 246 /* IO access */
245 247 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -276,3 +278,4 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
276 278 #undef SUFFIX
277 279 #undef USUFFIX
278 280 #undef DATA_SIZE
  281 +#undef ADDR_READ
... ...