#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)(unsigned long addr,
+static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr);
-static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr,
- unsigned long tlb_addr)
+static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
+ target_ulong tlb_addr)
{
DATA_TYPE res;
int index;
res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
#endif
#endif /* SHIFT > 2 */
+#ifdef USE_KQEMU
+ env->last_io_time = cpu_get_time_fast();
+#endif
return res;
}
/* handle all cases except unaligned access which span two pages */
-DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
+DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user)
{
DATA_TYPE res;
int index;
- unsigned long physaddr, tlb_addr;
+ target_ulong tlb_addr;
+ target_phys_addr_t physaddr;
void *retaddr;
/* test if there is match for unaligned or IO access */
/* 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)
goto do_unaligned_access;
res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
- } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+ } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
/* slow unaligned access (it spans two pages or IO) */
do_unaligned_access:
retaddr = GETPC();
+#ifdef ALIGNED_ONLY
+ do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+#endif
res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
is_user, retaddr);
} else {
- /* unaligned access in the same page */
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
+ /* unaligned/aligned access in the same page */
+#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0) {
+ retaddr = GETPC();
+ do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+ }
+#endif
+ res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
}
} else {
/* the page is not in the TLB : fill it */
retaddr = GETPC();
+#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0)
+ do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
+#endif
tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
goto redo;
}
}
/* handle all unaligned cases */
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr,
+static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
int is_user,
void *retaddr)
{
DATA_TYPE res, res1, res2;
int index, shift;
- unsigned long physaddr, tlb_addr, addr1, addr2;
+ target_phys_addr_t physaddr;
+ target_ulong tlb_addr, addr1, addr2;
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)
goto do_unaligned_access;
res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
- } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+ } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
/* slow unaligned access (it spans two pages) */
addr1 = addr & ~(DATA_SIZE - 1);
res = (DATA_TYPE)res;
} else {
/* unaligned/aligned access in the same page */
- res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
+ res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
}
} else {
/* the page is not in the TLB : fill it */
#ifndef SOFTMMU_CODE_ACCESS
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr,
+static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int is_user,
void *retaddr);
-static inline void glue(io_write, SUFFIX)(unsigned long physaddr,
+static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
DATA_TYPE val,
- unsigned long tlb_addr,
+ target_ulong tlb_addr,
void *retaddr)
{
int index;
io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
#endif
#endif /* SHIFT > 2 */
+#ifdef USE_KQEMU
+ env->last_io_time = cpu_get_time_fast();
+#endif
}
-void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr,
+void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int is_user)
{
- unsigned long physaddr, tlb_addr;
+ target_phys_addr_t physaddr;
+ target_ulong tlb_addr;
void *retaddr;
int index;
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)
goto do_unaligned_access;
retaddr = GETPC();
glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr);
- } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+ } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
retaddr = GETPC();
+#ifdef ALIGNED_ONLY
+ do_unaligned_access(addr, 1, is_user, retaddr);
+#endif
glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
is_user, retaddr);
} else {
/* aligned/unaligned access in the same page */
- glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
+#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0) {
+ retaddr = GETPC();
+ do_unaligned_access(addr, 1, is_user, retaddr);
+ }
+#endif
+ glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
}
} else {
/* the page is not in the TLB : fill it */
retaddr = GETPC();
+#ifdef ALIGNED_ONLY
+ if ((addr & (DATA_SIZE - 1)) != 0)
+ do_unaligned_access(addr, 1, is_user, retaddr);
+#endif
tlb_fill(addr, 1, is_user, retaddr);
goto redo;
}
}
/* handles all unaligned cases */
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr,
+static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
DATA_TYPE val,
int is_user,
void *retaddr)
{
- unsigned long physaddr, tlb_addr;
+ target_phys_addr_t physaddr;
+ target_ulong tlb_addr;
int index, i;
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)
goto do_unaligned_access;
glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr);
- } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+ } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
/* XXX: not efficient, but simple */
for(i = 0;i < DATA_SIZE; i++) {
}
} else {
/* aligned/unaligned access in the same page */
- glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val);
+ glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
}
} else {
/* the page is not in the TLB : fill it */
#undef SUFFIX
#undef USUFFIX
#undef DATA_SIZE
+#undef ADDR_READ