diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-01-12 21:33:13 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-01-12 21:33:13 +0000 |
commit | 932e71cd57bab4e6206e1355c6425290721bbe34 (patch) | |
tree | ff7567c8318ff81adfb798b1ff8f7e3d63120e83 /target-mips/helper.c | |
parent | ae1c1a3d68c75ebc5487f123c73dcfff5844b02a (diff) |
target-mips: get rid of tests on env->user_mode_only
Replace runtime checks on env->user_mode_only by compile time
checks on CONFIG_USER_ONLY.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6276 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/helper.c')
-rw-r--r-- | target-mips/helper.c | 443 |
1 files changed, 223 insertions, 220 deletions
diff --git a/target-mips/helper.c b/target-mips/helper.c index 0a3b913f19..c4fd9574e6 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -100,6 +100,7 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot, return TLBRET_NOMATCH; } +#if !defined(CONFIG_USER_ONLY) static int get_physical_address (CPUState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type) @@ -205,26 +206,29 @@ static int get_physical_address (CPUState *env, target_ulong *physical, return ret; } +#endif target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) { - if (env->user_mode_only) - return addr; - else { - target_ulong phys_addr; - int prot; +#if defined(CONFIG_USER_ONLY) + return addr; +#else + target_ulong phys_addr; + int prot; - if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) - return -1; - return phys_addr; - } + if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) + return -1; + return phys_addr; +#endif } int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int mmu_idx, int is_softmmu) { +#if !defined(CONFIG_USER_ONLY) target_ulong physical; int prot; +#endif int exception = 0, error_code = 0; int access_type; int ret = 0; @@ -243,11 +247,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, /* XXX: put correct access by using cpu_restore_state() correctly */ access_type = ACCESS_INT; - if (env->user_mode_only) { - /* user mode only emulation */ - ret = TLBRET_NOMATCH; - goto do_fault; - } +#if defined(CONFIG_USER_ONLY) + ret = TLBRET_NOMATCH; +#else ret = get_physical_address(env, &physical, &prot, address, rw, access_type); if (logfile) { @@ -258,8 +260,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, ret = tlb_set_page(env, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot, mmu_idx, is_softmmu); - } else if (ret < 0) { - do_fault: + } else if (ret < 0) +#endif + { switch (ret) { default: case TLBRET_BADADDR: @@ -349,227 +352,227 @@ static const char * const excp_names[EXCP_LAST + 1] = { void do_interrupt (CPUState *env) { - if (!env->user_mode_only) { - target_ulong offset; - int cause = -1; - const char *name; +#if !defined(CONFIG_USER_ONLY) + target_ulong offset; + int cause = -1; + const char *name; - if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { - if (env->exception_index < 0 || env->exception_index > EXCP_LAST) - name = "unknown"; - else - name = excp_names[env->exception_index]; + if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { + if (env->exception_index < 0 || env->exception_index > EXCP_LAST) + name = "unknown"; + else + name = excp_names[env->exception_index]; - fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", - __func__, env->active_tc.PC, env->CP0_EPC, name); - } - if (env->exception_index == EXCP_EXT_INTERRUPT && - (env->hflags & MIPS_HFLAG_DM)) - env->exception_index = EXCP_DINT; - offset = 0x180; - switch (env->exception_index) { - case EXCP_DSS: - env->CP0_Debug |= 1 << CP0DB_DSS; - /* Debug single step cannot be raised inside a delay slot and - resume will always occur on the next instruction - (but we assume the pc has always been updated during - code translation). */ + fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", + __func__, env->active_tc.PC, env->CP0_EPC, name); + } + if (env->exception_index == EXCP_EXT_INTERRUPT && + (env->hflags & MIPS_HFLAG_DM)) + env->exception_index = EXCP_DINT; + offset = 0x180; + switch (env->exception_index) { + case EXCP_DSS: + env->CP0_Debug |= 1 << CP0DB_DSS; + /* Debug single step cannot be raised inside a delay slot and + resume will always occur on the next instruction + (but we assume the pc has always been updated during + code translation). */ + env->CP0_DEPC = env->active_tc.PC; + goto enter_debug_mode; + case EXCP_DINT: + env->CP0_Debug |= 1 << CP0DB_DINT; + goto set_DEPC; + case EXCP_DIB: + env->CP0_Debug |= 1 << CP0DB_DIB; + goto set_DEPC; + case EXCP_DBp: + env->CP0_Debug |= 1 << CP0DB_DBp; + goto set_DEPC; + case EXCP_DDBS: + env->CP0_Debug |= 1 << CP0DB_DDBS; + goto set_DEPC; + case EXCP_DDBL: + env->CP0_Debug |= 1 << CP0DB_DDBL; + set_DEPC: + if (env->hflags & MIPS_HFLAG_BMASK) { + /* If the exception was raised from a delay slot, + come back to the jump. */ + env->CP0_DEPC = env->active_tc.PC - 4; + env->hflags &= ~MIPS_HFLAG_BMASK; + } else { env->CP0_DEPC = env->active_tc.PC; - goto enter_debug_mode; - case EXCP_DINT: - env->CP0_Debug |= 1 << CP0DB_DINT; - goto set_DEPC; - case EXCP_DIB: - env->CP0_Debug |= 1 << CP0DB_DIB; - goto set_DEPC; - case EXCP_DBp: - env->CP0_Debug |= 1 << CP0DB_DBp; - goto set_DEPC; - case EXCP_DDBS: - env->CP0_Debug |= 1 << CP0DB_DDBS; - goto set_DEPC; - case EXCP_DDBL: - env->CP0_Debug |= 1 << CP0DB_DDBL; - set_DEPC: - if (env->hflags & MIPS_HFLAG_BMASK) { - /* If the exception was raised from a delay slot, - come back to the jump. */ - env->CP0_DEPC = env->active_tc.PC - 4; - env->hflags &= ~MIPS_HFLAG_BMASK; - } else { - env->CP0_DEPC = env->active_tc.PC; - } + } enter_debug_mode: - env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0; - env->hflags &= ~(MIPS_HFLAG_KSU); - /* EJTAG probe trap enable is not implemented... */ - if (!(env->CP0_Status & (1 << CP0St_EXL))) - env->CP0_Cause &= ~(1 << CP0Ca_BD); - env->active_tc.PC = (int32_t)0xBFC00480; - break; - case EXCP_RESET: - cpu_reset(env); - break; - case EXCP_SRESET: - env->CP0_Status |= (1 << CP0St_SR); - memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo)); - goto set_error_EPC; - case EXCP_NMI: - env->CP0_Status |= (1 << CP0St_NMI); + env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0; + env->hflags &= ~(MIPS_HFLAG_KSU); + /* EJTAG probe trap enable is not implemented... */ + if (!(env->CP0_Status & (1 << CP0St_EXL))) + env->CP0_Cause &= ~(1 << CP0Ca_BD); + env->active_tc.PC = (int32_t)0xBFC00480; + break; + case EXCP_RESET: + cpu_reset(env); + break; + case EXCP_SRESET: + env->CP0_Status |= (1 << CP0St_SR); + memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo)); + goto set_error_EPC; + case EXCP_NMI: + env->CP0_Status |= (1 << CP0St_NMI); set_error_EPC: - if (env->hflags & MIPS_HFLAG_BMASK) { - /* If the exception was raised from a delay slot, - come back to the jump. */ - env->CP0_ErrorEPC = env->active_tc.PC - 4; - env->hflags &= ~MIPS_HFLAG_BMASK; - } else { - env->CP0_ErrorEPC = env->active_tc.PC; - } - env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); - env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; - env->hflags &= ~(MIPS_HFLAG_KSU); - if (!(env->CP0_Status & (1 << CP0St_EXL))) - env->CP0_Cause &= ~(1 << CP0Ca_BD); - env->active_tc.PC = (int32_t)0xBFC00000; - break; - case EXCP_EXT_INTERRUPT: - cause = 0; - if (env->CP0_Cause & (1 << CP0Ca_IV)) - offset = 0x200; - goto set_EPC; - case EXCP_LTLBL: - cause = 1; - goto set_EPC; - case EXCP_TLBL: - cause = 2; - if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { + if (env->hflags & MIPS_HFLAG_BMASK) { + /* If the exception was raised from a delay slot, + come back to the jump. */ + env->CP0_ErrorEPC = env->active_tc.PC - 4; + env->hflags &= ~MIPS_HFLAG_BMASK; + } else { + env->CP0_ErrorEPC = env->active_tc.PC; + } + env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); + env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; + env->hflags &= ~(MIPS_HFLAG_KSU); + if (!(env->CP0_Status & (1 << CP0St_EXL))) + env->CP0_Cause &= ~(1 << CP0Ca_BD); + env->active_tc.PC = (int32_t)0xBFC00000; + break; + case EXCP_EXT_INTERRUPT: + cause = 0; + if (env->CP0_Cause & (1 << CP0Ca_IV)) + offset = 0x200; + goto set_EPC; + case EXCP_LTLBL: + cause = 1; + goto set_EPC; + case EXCP_TLBL: + cause = 2; + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { #if defined(TARGET_MIPS64) - int R = env->CP0_BadVAddr >> 62; - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; + int R = env->CP0_BadVAddr >> 62; + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; - if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) - offset = 0x080; - else + if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) + offset = 0x080; + else #endif - offset = 0x000; - } - goto set_EPC; - case EXCP_TLBS: - cause = 3; - if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { + offset = 0x000; + } + goto set_EPC; + case EXCP_TLBS: + cause = 3; + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { #if defined(TARGET_MIPS64) - int R = env->CP0_BadVAddr >> 62; - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; + int R = env->CP0_BadVAddr >> 62; + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; - if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) - offset = 0x080; - else + if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) + offset = 0x080; + else #endif - offset = 0x000; - } - goto set_EPC; - case EXCP_AdEL: - cause = 4; - goto set_EPC; - case EXCP_AdES: - cause = 5; - goto set_EPC; - case EXCP_IBE: - cause = 6; - goto set_EPC; - case EXCP_DBE: - cause = 7; - goto set_EPC; - case EXCP_SYSCALL: - cause = 8; - goto set_EPC; - case EXCP_BREAK: - cause = 9; - goto set_EPC; - case EXCP_RI: - cause = 10; - goto set_EPC; - case EXCP_CpU: - cause = 11; - env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | - (env->error_code << CP0Ca_CE); - goto set_EPC; - case EXCP_OVERFLOW: - cause = 12; - goto set_EPC; - case EXCP_TRAP: - cause = 13; - goto set_EPC; - case EXCP_FPE: - cause = 15; - goto set_EPC; - case EXCP_C2E: - cause = 18; - goto set_EPC; - case EXCP_MDMX: - cause = 22; - goto set_EPC; - case EXCP_DWATCH: - cause = 23; - /* XXX: TODO: manage defered watch exceptions */ - goto set_EPC; - case EXCP_MCHECK: - cause = 24; - goto set_EPC; - case EXCP_THREAD: - cause = 25; - goto set_EPC; - case EXCP_CACHE: - cause = 30; - if (env->CP0_Status & (1 << CP0St_BEV)) { - offset = 0x100; - } else { - offset = 0x20000100; - } + offset = 0x000; + } + goto set_EPC; + case EXCP_AdEL: + cause = 4; + goto set_EPC; + case EXCP_AdES: + cause = 5; + goto set_EPC; + case EXCP_IBE: + cause = 6; + goto set_EPC; + case EXCP_DBE: + cause = 7; + goto set_EPC; + case EXCP_SYSCALL: + cause = 8; + goto set_EPC; + case EXCP_BREAK: + cause = 9; + goto set_EPC; + case EXCP_RI: + cause = 10; + goto set_EPC; + case EXCP_CpU: + cause = 11; + env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | + (env->error_code << CP0Ca_CE); + goto set_EPC; + case EXCP_OVERFLOW: + cause = 12; + goto set_EPC; + case EXCP_TRAP: + cause = 13; + goto set_EPC; + case EXCP_FPE: + cause = 15; + goto set_EPC; + case EXCP_C2E: + cause = 18; + goto set_EPC; + case EXCP_MDMX: + cause = 22; + goto set_EPC; + case EXCP_DWATCH: + cause = 23; + /* XXX: TODO: manage defered watch exceptions */ + goto set_EPC; + case EXCP_MCHECK: + cause = 24; + goto set_EPC; + case EXCP_THREAD: + cause = 25; + goto set_EPC; + case EXCP_CACHE: + cause = 30; + if (env->CP0_Status & (1 << CP0St_BEV)) { + offset = 0x100; + } else { + offset = 0x20000100; + } set_EPC: - if (!(env->CP0_Status & (1 << CP0St_EXL))) { - if (env->hflags & MIPS_HFLAG_BMASK) { - /* If the exception was raised from a delay slot, - come back to the jump. */ - env->CP0_EPC = env->active_tc.PC - 4; - env->CP0_Cause |= (1 << CP0Ca_BD); - } else { - env->CP0_EPC = env->active_tc.PC; - env->CP0_Cause &= ~(1 << CP0Ca_BD); - } - env->CP0_Status |= (1 << CP0St_EXL); - env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; - env->hflags &= ~(MIPS_HFLAG_KSU); - } - env->hflags &= ~MIPS_HFLAG_BMASK; - if (env->CP0_Status & (1 << CP0St_BEV)) { - env->active_tc.PC = (int32_t)0xBFC00200; + if (!(env->CP0_Status & (1 << CP0St_EXL))) { + if (env->hflags & MIPS_HFLAG_BMASK) { + /* If the exception was raised from a delay slot, + come back to the jump. */ + env->CP0_EPC = env->active_tc.PC - 4; + env->CP0_Cause |= (1 << CP0Ca_BD); } else { - env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); - } - env->active_tc.PC += offset; - env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); - break; - default: - if (logfile) { - fprintf(logfile, "Invalid MIPS exception %d. Exiting\n", - env->exception_index); + env->CP0_EPC = env->active_tc.PC; + env->CP0_Cause &= ~(1 << CP0Ca_BD); } - printf("Invalid MIPS exception %d. Exiting\n", env->exception_index); - exit(1); + env->CP0_Status |= (1 << CP0St_EXL); + env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; + env->hflags &= ~(MIPS_HFLAG_KSU); } - if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { - fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" - " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", - __func__, env->active_tc.PC, env->CP0_EPC, cause, - env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, - env->CP0_DEPC); + env->hflags &= ~MIPS_HFLAG_BMASK; + if (env->CP0_Status & (1 << CP0St_BEV)) { + env->active_tc.PC = (int32_t)0xBFC00200; + } else { + env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); } + env->active_tc.PC += offset; + env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); + break; + default: + if (logfile) { + fprintf(logfile, "Invalid MIPS exception %d. Exiting\n", + env->exception_index); + } + printf("Invalid MIPS exception %d. Exiting\n", env->exception_index); + exit(1); + } + if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { + fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" + " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", + __func__, env->active_tc.PC, env->CP0_EPC, cause, + env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, + env->CP0_DEPC); } +#endif env->exception_index = EXCP_NONE; } |