diff --git a/exec-all.h b/exec-all.h index 2e886e07c..8a47f1bb1 100644 --- a/exec-all.h +++ b/exec-all.h @@ -592,13 +592,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) #endif if (__builtin_expect(env->tlb_read[is_user][index].address != (addr & TARGET_PAGE_MASK), 0)) { -#if defined (TARGET_PPC) - env->access_type = ACCESS_CODE; - ldub_code((void *)addr); - env->access_type = ACCESS_INT; -#else ldub_code((void *)addr); -#endif } return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base; } diff --git a/exec.c b/exec.c index 5f2f69642..8732377ab 100644 --- a/exec.c +++ b/exec.c @@ -2115,6 +2115,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, #define MMUSUFFIX _cmmu #define GETPC() NULL #define env cpu_single_env +#define SOFTMMU_CODE_ACCESS #define SHIFT 0 #include "softmmu_template.h" diff --git a/softmmu_template.h b/softmmu_template.h index 73fdbecb3..f1abee8ac 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -39,14 +39,15 @@ #error unsupported data size #endif +#ifdef SOFTMMU_CODE_ACCESS +#define READ_ACCESS_TYPE 2 +#else +#define READ_ACCESS_TYPE 0 +#endif + static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, int is_user, void *retaddr); -static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, - DATA_TYPE val, - int is_user, - void *retaddr); - static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, unsigned long tlb_addr) { @@ -68,29 +69,6 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, return res; } -static inline void glue(io_write, SUFFIX)(unsigned long physaddr, - DATA_TYPE val, - unsigned long tlb_addr, - void *retaddr) -{ - int index; - - index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); - env->mem_write_vaddr = tlb_addr; - env->mem_write_pc = (unsigned long)retaddr; -#if SHIFT <= 2 - io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); -#else -#ifdef TARGET_WORDS_BIGENDIAN - io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32); - io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val); -#else - io_mem_write[index][2](io_mem_opaque[index], physaddr, val); - io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32); -#endif -#endif /* SHIFT > 2 */ -} - /* handle all cases except unaligned access which span two pages */ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, int is_user) @@ -125,7 +103,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, } else { /* the page is not in the TLB : fill it */ retaddr = GETPC(); - tlb_fill(addr, 0, is_user, retaddr); + tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); goto redo; } return res; @@ -172,12 +150,41 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, } } else { /* the page is not in the TLB : fill it */ - tlb_fill(addr, 0, is_user, retaddr); + tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); goto redo; } return res; } +#ifndef SOFTMMU_CODE_ACCESS + +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, + DATA_TYPE val, + int is_user, + void *retaddr); + +static inline void glue(io_write, SUFFIX)(unsigned long physaddr, + DATA_TYPE val, + unsigned long tlb_addr, + void *retaddr) +{ + int index; + + index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + env->mem_write_vaddr = tlb_addr; + env->mem_write_pc = (unsigned long)retaddr; +#if SHIFT <= 2 + io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); +#else +#ifdef TARGET_WORDS_BIGENDIAN + io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32); + io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val); +#else + io_mem_write[index][2](io_mem_opaque[index], physaddr, val); + io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32); +#endif +#endif /* SHIFT > 2 */ +} void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, DATA_TYPE val, @@ -257,6 +264,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, } } +#endif /* !defined(SOFTMMU_CODE_ACCESS) */ + +#undef READ_ACCESS_TYPE #undef SHIFT #undef DATA_TYPE #undef SUFFIX diff --git a/target-i386/helper2.c b/target-i386/helper2.c index 06c732edc..0d5f439d1 100644 --- a/target-i386/helper2.c +++ b/target-i386/helper2.c @@ -331,7 +331,8 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", addr, is_write, is_user, env->eip); #endif - + is_write &= 1; + if (env->user_mode_only) { /* user mode only emulation */ error_code = 0; diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 55fe2b224..1ed07e833 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -432,13 +432,13 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) generated code */ saved_env = env; env = cpu_single_env; +#if 0 { unsigned long tlb_addrr, tlb_addrw; int index; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); tlb_addrr = env->tlb_read[is_user][index].address; tlb_addrw = env->tlb_write[is_user][index].address; -#if 0 if (loglevel) { fprintf(logfile, "%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " @@ -447,8 +447,8 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); } -#endif } +#endif ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); if (ret) { if (retaddr) { @@ -463,20 +463,20 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) } do_raise_exception_err(env->exception_index, env->error_code); } +#if 0 { unsigned long tlb_addrr, tlb_addrw; int index; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); tlb_addrr = env->tlb_read[is_user][index].address; tlb_addrw = env->tlb_write[is_user][index].address; -#if 0 printf("%s 2 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " "(0x%08lx 0x%08lx)\n", __func__, env, &env->tlb_read[is_user][index], index, addr, tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); -#endif } +#endif env = saved_env; } @@ -496,18 +496,22 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, int access_type; int ret = 0; -// printf("%s 0\n", __func__); - access_type = env->access_type; + if (rw == 2) { + /* code access */ + rw = 0; + access_type = ACCESS_CODE; + } else { + /* data access */ + /* XXX: put correct access by using cpu_restore_state() + correctly */ + access_type = ACCESS_INT; + // access_type = env->access_type; + } if (env->user_mode_only) { /* user mode only emulation */ ret = -2; goto do_fault; } - /* NASTY BUG workaround */ - if (access_type == ACCESS_CODE && rw) { - printf("%s: ERROR WRITE CODE ACCESS\n", __func__); - access_type = ACCESS_INT; - } ret = get_physical_address(env, &physical, &prot, address, rw, access_type); if (ret == 0) { @@ -590,7 +594,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, env->error_code = error_code; ret = 1; } - return ret; } @@ -671,11 +674,15 @@ void do_interrupt (CPUState *env) if (loglevel > 0) { fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n", env->nip, excp << 8, env->error_code); - } + } if (loglevel > 0) cpu_ppc_dump_state(env, logfile, 0); } #endif + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n", + env->nip, excp << 8, env->error_code); + } /* Generate informations in save/restore registers */ switch (excp) { case EXCP_OFCALL: @@ -824,19 +831,29 @@ void do_interrupt (CPUState *env) } goto store_next; case EXCP_SYSCALL: -#if defined (DEBUG_EXCEPTIONS) - if (msr_pr) { - if (loglevel) { - fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", - env->gpr[0], env->gpr[3], env->gpr[4], - env->gpr[5], env->gpr[6]); - } else { - printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", - env->gpr[0], env->nip, env->gpr[3], env->gpr[4], - env->gpr[5], env->gpr[6]); - } - } -#endif + if (loglevel & CPU_LOG_INT) { + fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", + env->gpr[0], env->gpr[3], env->gpr[4], + env->gpr[5], env->gpr[6]); + if (env->gpr[0] == 4 && env->gpr[3] == 1) { + int len, addr, i; + uint8_t c; + + fprintf(logfile, "write: "); + addr = env->gpr[4]; + len = env->gpr[5]; + if (len > 64) + len = 64; + for(i = 0; i < len; i++) { + c = 0; + cpu_memory_rw_debug(env, addr + i, &c, 1, 0); + if (c < 32 || c > 126) + c = '.'; + fprintf(logfile, "%c", c); + } + fprintf(logfile, "\n"); + } + } goto store_next; case EXCP_TRACE: goto store_next; diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 7e684495d..fd52f73cc 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3002,7 +3002,6 @@ CPUPPCState *cpu_ppc_init(void) #else env->nip = 0xFFFFFFFC; #endif - env->access_type = ACCESS_INT; cpu_single_env = env; return env; } @@ -3050,12 +3049,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, /* Single step trace mode */ msr_se = 1; #endif - env->access_type = ACCESS_CODE; /* Set env in case of segfault during code fetch */ while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { if (search_pc) { - if (loglevel > 0) - fprintf(logfile, "Search PC...\n"); j = gen_opc_ptr - gen_opc_buf; if (lj < j) { lj++; @@ -3187,8 +3183,6 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, fprintf(logfile, "\n"); } #endif - env->access_type = ACCESS_INT; - return 0; } diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index ec9bba76a..4c23b924a 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -86,10 +86,6 @@ #define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT) #define PG_CACHE_MASK (1 << PG_CACHE_BIT) -#define ACCESS_DATA 0 -#define ACCESS_CODE 1 -#define ACCESS_MMU 2 - #define NWINDOWS 32 typedef struct CPUSPARCState { @@ -131,7 +127,6 @@ typedef struct CPUSPARCState { CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; int error_code; - int access_type; /* MMU regs */ uint32_t mmuregs[16]; /* temporary float registers */ diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 036720045..ae70595c5 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -132,13 +132,12 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, int is_user, int is_softmmu) { int exception = 0; - int access_type, access_perms = 0, access_index = 0; + int access_perms = 0, access_index = 0; uint8_t *pde_ptr; uint32_t pde, virt_addr; int error_code = 0, is_dirty, prot, ret = 0; unsigned long paddr, vaddr, page_offset; - access_type = env->access_type; if (env->user_mode_only) { /* user mode only emulation */ ret = -2; @@ -156,7 +155,6 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ /* Context base + context number */ pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4); - env->access_type = ACCESS_MMU; pde = ldl_raw(pde_ptr); /* Ctx pde */ @@ -219,7 +217,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, } /* update page modified and dirty bits */ - is_dirty = rw && !(pde & PG_MODIFIED_MASK); + is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK); if (!(pde & PG_ACCESSED_MASK) || is_dirty) { pde |= PG_ACCESSED_MASK; if (is_dirty) @@ -228,7 +226,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, } /* check access */ - access_index = (rw << 2) | ((access_type == ACCESS_CODE)? 2 : 0) | (is_user? 0 : 1); + access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT; error_code = access_table[access_index][access_perms]; if (error_code) @@ -249,14 +247,12 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset; do_mapping: - env->access_type = access_type; vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); return ret; do_fault: - env->access_type = access_type; if (env->mmuregs[3]) /* Fault status register */ env->mmuregs[3] = 1; /* overflow (not read before another fault) */ env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 852507ab1..d06886c84 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1278,8 +1278,6 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; - env->access_type = ACCESS_CODE; - do { if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { @@ -1352,8 +1350,6 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, } } #endif - - env->access_type = ACCESS_DATA; return 0; } @@ -1379,7 +1375,6 @@ CPUSPARCState *cpu_sparc_init(void) env->cwp = 0; env->wim = 1; env->regwptr = env->regbase + (env->cwp * 16); - env->access_type = ACCESS_DATA; #if defined(CONFIG_USER_ONLY) env->user_mode_only = 1; #else