Commit 84b7b8e7 authored by bellard's avatar bellard
Browse files

PAGE_EXEC support in TLBs


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1676 c046a42c-6fe2-441c-8c8c-71466251a162
parent 5cf38396
......@@ -80,7 +80,8 @@ typedef unsigned long ram_addr_t;
#define TB_JMP_CACHE_BITS 12
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
#define CPU_TLB_SIZE 256
#define CPU_TLB_BITS 8
#define CPU_TLB_SIZE (1 << CPU_TLB_BITS)
typedef struct CPUTLBEntry {
/* bit 31 to TARGET_PAGE_BITS : virtual address
......@@ -89,7 +90,9 @@ typedef struct CPUTLBEntry {
bit 3 : indicates that the entry is invalid
bit 2..0 : zero
*/
target_ulong address;
target_ulong addr_read;
target_ulong addr_write;
target_ulong addr_code;
/* addend to virtual address to get physical address */
target_phys_addr_t addend;
} CPUTLBEntry;
......@@ -105,8 +108,7 @@ typedef struct CPUTLBEntry {
target_ulong mem_write_vaddr; /* target virtual addr at which the \
memory was written */ \
/* 0 = kernel, 1 = user */ \
CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; \
CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; \
CPUTLBEntry tlb_table[2][CPU_TLB_SIZE]; \
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
\
/* from this point: preserved by CPU reset */ \
......
......@@ -98,9 +98,17 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
void tb_invalidate_page_range(target_ulong start, target_ulong end);
void tlb_flush_page(CPUState *env, target_ulong addr);
void tlb_flush(CPUState *env, int flush_global);
int tlb_set_page(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu);
int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu);
static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
{
if (prot & PAGE_READ)
prot |= PAGE_EXEC;
return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
}
#define CODE_GEN_MAX_SIZE 65536
#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)
#else
#error unimplemented CPU
#endif
if (__builtin_expect(env->tlb_read[is_user][index].address !=
if (__builtin_expect(env->tlb_table[is_user][index].addr_code !=
(addr & TARGET_PAGE_MASK), 0)) {
ldub_code(addr);
}
pd = env->tlb_read[is_user][index].address & ~TARGET_PAGE_MASK;
pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK;
if (pd > IO_MEM_ROM) {
cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
}
return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base;
}
#endif
......
......@@ -1209,10 +1209,12 @@ void tlb_flush(CPUState *env, int flush_global)
env->current_tb = NULL;
for(i = 0; i < CPU_TLB_SIZE; i++) {
env->tlb_read[0][i].address = -1;
env->tlb_write[0][i].address = -1;
env->tlb_read[1][i].address = -1;
env->tlb_write[1][i].address = -1;
env->tlb_table[0][i].addr_read = -1;
env->tlb_table[0][i].addr_write = -1;
env->tlb_table[0][i].addr_code = -1;
env->tlb_table[1][i].addr_read = -1;
env->tlb_table[1][i].addr_write = -1;
env->tlb_table[1][i].addr_code = -1;
}
memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
......@@ -1230,9 +1232,16 @@ void tlb_flush(CPUState *env, int flush_global)
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
{
if (addr == (tlb_entry->address &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)))
tlb_entry->address = -1;
if (addr == (tlb_entry->addr_read &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
addr == (tlb_entry->addr_write &
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
addr == (tlb_entry->addr_code &
(TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
tlb_entry->addr_read = -1;
tlb_entry->addr_write = -1;
tlb_entry->addr_code = -1;
}
}
void tlb_flush_page(CPUState *env, target_ulong addr)
......@@ -1249,10 +1258,8 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
addr &= TARGET_PAGE_MASK;
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_flush_entry(&env->tlb_read[0][i], addr);
tlb_flush_entry(&env->tlb_write[0][i], addr);
tlb_flush_entry(&env->tlb_read[1][i], addr);
tlb_flush_entry(&env->tlb_write[1][i], addr);
tlb_flush_entry(&env->tlb_table[0][i], addr);
tlb_flush_entry(&env->tlb_table[1][i], addr);
for(i = 0; i < TB_JMP_CACHE_SIZE; i++) {
tb = env->tb_jmp_cache[i];
......@@ -1295,10 +1302,10 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
unsigned long start, unsigned long length)
{
unsigned long addr;
if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
if ((addr - start) < length) {
tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
}
}
}
......@@ -1340,9 +1347,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
start1 = start + (unsigned long)phys_ram_base;
for(env = first_cpu; env != NULL; env = env->next_cpu) {
for(i = 0; i < CPU_TLB_SIZE; i++)
tlb_reset_dirty_range(&env->tlb_write[0][i], start1, length);
tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
for(i = 0; i < CPU_TLB_SIZE; i++)
tlb_reset_dirty_range(&env->tlb_write[1][i], start1, length);
tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
}
#if !defined(CONFIG_SOFTMMU)
......@@ -1378,11 +1385,11 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
{
ram_addr_t ram_addr;
if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
ram_addr = (tlb_entry->address & TARGET_PAGE_MASK) +
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
tlb_entry->addend - (unsigned long)phys_ram_base;
if (!cpu_physical_memory_is_dirty(ram_addr)) {
tlb_entry->address |= IO_MEM_NOTDIRTY;
tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
}
}
}
......@@ -1392,19 +1399,19 @@ void cpu_tlb_update_dirty(CPUState *env)
{
int i;
for(i = 0; i < CPU_TLB_SIZE; i++)
tlb_update_dirty(&env->tlb_write[0][i]);
tlb_update_dirty(&env->tlb_table[0][i]);
for(i = 0; i < CPU_TLB_SIZE; i++)
tlb_update_dirty(&env->tlb_write[1][i]);
tlb_update_dirty(&env->tlb_table[1][i]);
}
static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
unsigned long start)
{
unsigned long addr;
if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
if (addr == start) {
tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_RAM;
tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM;
}
}
}
......@@ -1418,17 +1425,17 @@ static inline void tlb_set_dirty(CPUState *env,
addr &= TARGET_PAGE_MASK;
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
tlb_set_dirty1(&env->tlb_write[0][i], addr);
tlb_set_dirty1(&env->tlb_write[1][i], addr);
tlb_set_dirty1(&env->tlb_table[0][i], addr);
tlb_set_dirty1(&env->tlb_table[1][i], addr);
}
/* add a new TLB entry. At most one entry for a given virtual address
is permitted. Return 0 if OK or 2 if the page could not be mapped
(can only happen in non SOFTMMU mode for I/O pages or pages
conflicting with the host address space). */
int tlb_set_page(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
{
PhysPageDesc *p;
unsigned long pd;
......@@ -1436,6 +1443,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
target_ulong address;
target_phys_addr_t addend;
int ret;
CPUTLBEntry *te;
p = phys_page_find(paddr >> TARGET_PAGE_BITS);
if (!p) {
......@@ -1445,7 +1453,7 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
}
#if defined(DEBUG_TLB)
printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
vaddr, paddr, prot, is_user, is_softmmu, pd);
vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
#endif
ret = 0;
......@@ -1465,29 +1473,30 @@ int tlb_set_page(CPUState *env, target_ulong vaddr,
index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
addend -= vaddr;
te = &env->tlb_table[is_user][index];
te->addend = addend;
if (prot & PAGE_READ) {
env->tlb_read[is_user][index].address = address;
env->tlb_read[is_user][index].addend = addend;
te->addr_read = address;
} else {
te->addr_read = -1;
}
if (prot & PAGE_EXEC) {
te->addr_code = address;
} else {
env->tlb_read[is_user][index].address = -1;
env->tlb_read[is_user][index].addend = -1;
te->addr_code = -1;
}
if (prot & PAGE_WRITE) {
if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
/* ROM: access is ignored (same as unassigned) */
env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
env->tlb_write[is_user][index].addend = addend;
te->addr_write = vaddr | IO_MEM_ROM;
} else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
!cpu_physical_memory_is_dirty(pd)) {
env->tlb_write[is_user][index].address = vaddr | IO_MEM_NOTDIRTY;
env->tlb_write[is_user][index].addend = addend;
te->addr_write = vaddr | IO_MEM_NOTDIRTY;
} else {
env->tlb_write[is_user][index].address = address;
env->tlb_write[is_user][index].addend = addend;
te->addr_write = address;
}
} else {
env->tlb_write[is_user][index].address = -1;
env->tlb_write[is_user][index].addend = -1;
te->addr_write = -1;
}
}
#if !defined(CONFIG_SOFTMMU)
......@@ -1586,9 +1595,9 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
{
}
int tlb_set_page(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int is_user, int is_softmmu)
{
return 0;
}
......@@ -2052,6 +2061,41 @@ uint32_t ldl_phys(target_phys_addr_t addr)
return val;
}
/* warning: addr must be aligned */
uint64_t ldq_phys(target_phys_addr_t addr)
{
int io_index;
uint8_t *ptr;
uint64_t val;
unsigned long pd;
PhysPageDesc *p;
p = phys_page_find(addr >> TARGET_PAGE_BITS);
if (!p) {
pd = IO_MEM_UNASSIGNED;
} else {
pd = p->phys_offset;
}
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
/* I/O case */
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
#ifdef TARGET_WORDS_BIGENDIAN
val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
#else
val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
#endif
} else {
/* RAM case */
ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
(addr & ~TARGET_PAGE_MASK);
val = ldq_p(ptr);
}
return val;
}
/* XXX: optimize */
uint32_t ldub_phys(target_phys_addr_t addr)
{
......@@ -2068,14 +2112,6 @@ uint32_t lduw_phys(target_phys_addr_t addr)
return tswap16(val);
}
/* XXX: optimize */
uint64_t ldq_phys(target_phys_addr_t addr)
{
uint64_t val;
cpu_physical_memory_read(addr, (uint8_t *)&val, 8);
return tswap64(val);
}
/* warning: addr must be aligned. The ram page is not masked as dirty
and the code inside is not invalidated. It is useful if the dirty
bits are used to track modified PTEs */
......
......@@ -93,6 +93,11 @@
#define RES_TYPE int
#endif
#if ACCESS_TYPE == 3
#define ADDR_READ addr_code
#else
#define ADDR_READ addr_read
#endif
DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user);
......@@ -101,6 +106,8 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE
#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
(ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU)
#define CPU_TLB_ENTRY_BITS 4
static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
{
int res;
......@@ -120,7 +127,7 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
"movl %%eax, %0\n"
"jmp 2f\n"
"1:\n"
"addl 4(%%edx), %%eax\n"
"addl 12(%%edx), %%eax\n"
#if DATA_SIZE == 1
"movzbl (%%eax), %0\n"
#elif DATA_SIZE == 2
......@@ -133,10 +140,10 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
"2:\n"
: "=r" (res)
: "r" (ptr),
"i" ((CPU_TLB_SIZE - 1) << 3),
"i" (TARGET_PAGE_BITS - 3),
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
"i" (CPU_MEM_INDEX),
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
: "%eax", "%ecx", "%edx", "memory", "cc");
......@@ -169,7 +176,7 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
#endif
"jmp 2f\n"
"1:\n"
"addl 4(%%edx), %%eax\n"
"addl 12(%%edx), %%eax\n"
#if DATA_SIZE == 1
"movsbl (%%eax), %0\n"
#elif DATA_SIZE == 2
......@@ -180,10 +187,10 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
"2:\n"
: "=r" (res)
: "r" (ptr),
"i" ((CPU_TLB_SIZE - 1) << 3),
"i" (TARGET_PAGE_BITS - 3),
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_read[CPU_MEM_INDEX][0].address)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),
"i" (CPU_MEM_INDEX),
"m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
: "%eax", "%ecx", "%edx", "memory", "cc");
......@@ -216,7 +223,7 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
"popl %%eax\n"
"jmp 2f\n"
"1:\n"
"addl 4(%%edx), %%eax\n"
"addl 8(%%edx), %%eax\n"
#if DATA_SIZE == 1
"movb %b1, (%%eax)\n"
#elif DATA_SIZE == 2
......@@ -232,10 +239,10 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
/* NOTE: 'q' would be needed as constraint, but we could not use it
with T1 ! */
"r" (v),
"i" ((CPU_TLB_SIZE - 1) << 3),
"i" (TARGET_PAGE_BITS - 3),
"i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
"i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_write[CPU_MEM_INDEX][0].address)),
"m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),
"i" (CPU_MEM_INDEX),
"m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
: "%eax", "%ecx", "%edx", "memory", "cc");
......@@ -256,11 +263,11 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
addr = ptr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
is_user = CPU_MEM_INDEX;
if (__builtin_expect(env->tlb_read[is_user][index].address !=
if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
} else {
physaddr = addr + env->tlb_read[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
}
return res;
......@@ -277,17 +284,19 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
addr = ptr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
is_user = CPU_MEM_INDEX;
if (__builtin_expect(env->tlb_read[is_user][index].address !=
if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user);
} else {
physaddr = addr + env->tlb_read[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
}
return res;
}
#endif
#if ACCESS_TYPE != 3
/* generic store macro */
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
addr = ptr;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
is_user = CPU_MEM_INDEX;
if (__builtin_expect(env->tlb_write[is_user][index].address !=
if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user);
} else {
physaddr = addr + env->tlb_write[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
}
}
#endif
#endif /* ACCESS_TYPE != 3 */
#endif /* !asm */
#if ACCESS_TYPE != 3
#if DATA_SIZE == 8
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
......@@ -355,6 +368,8 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
}
#endif /* DATA_SIZE == 4 */
#endif /* ACCESS_TYPE != 3 */
#undef RES_TYPE
#undef DATA_TYPE
#undef DATA_STYPE
......@@ -363,3 +378,4 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
#undef DATA_SIZE
#undef CPU_MEM_INDEX
#undef MMUSUFFIX
#undef ADDR_READ
......@@ -41,8 +41,10 @@
#ifdef SOFTMMU_CODE_ACCESS
#define READ_ACCESS_TYPE 2
#define ADDR_READ addr_code
#else
#define READ_ACCESS_TYPE 0
#define ADDR_READ addr_read
#endif
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,
/* XXX: could done more in memory macro in a non portable way */
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
redo:
tlb_addr = env->tlb_read[is_user][index].address;
tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
physaddr = addr + env->tlb_read[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
if (tlb_addr & ~TARGET_PAGE_MASK) {
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
......@@ -122,9 +124,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
redo:
tlb_addr = env->tlb_read[is_user][index].address;
tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
physaddr = addr + env->tlb_read[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
if (tlb_addr & ~TARGET_PAGE_MASK) {
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
......@@ -199,9 +201,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
redo:
tlb_addr = env->tlb_write[is_user][index].address;
tlb_addr = env->tlb_table[is_user][index].addr_write;
if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
physaddr = addr + env->tlb_write[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
if (tlb_addr & ~TARGET_PAGE_MASK) {
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
......@@ -237,9 +239,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
redo:
tlb_addr = env->tlb_write[is_user][index].address;
tlb_addr = env->tlb_table[is_user][index].addr_write;
if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
physaddr = addr + env->tlb_write[is_user][index].addend;
physaddr = addr + env->tlb_table[is_user][index].addend;
if (tlb_addr & ~TARGET_PAGE_MASK) {
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
......@@ -276,3 +278,4 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
#undef SUFFIX
#undef USUFFIX
#undef DATA_SIZE
#undef ADDR_READ
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment