Commit 24c7b0e330fdbfcfe87f515d79e67156c57cbc4f
1 parent
e69f67b6
Sanitize mips exception handling.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2546 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
66 additions
and
84 deletions
cpu-exec.c
| @@ -461,10 +461,10 @@ int cpu_exec(CPUState *env1) | @@ -461,10 +461,10 @@ int cpu_exec(CPUState *env1) | ||
| 461 | } | 461 | } |
| 462 | #elif defined(TARGET_MIPS) | 462 | #elif defined(TARGET_MIPS) |
| 463 | if ((interrupt_request & CPU_INTERRUPT_HARD) && | 463 | if ((interrupt_request & CPU_INTERRUPT_HARD) && |
| 464 | + (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && | ||
| 464 | (env->CP0_Status & (1 << CP0St_IE)) && | 465 | (env->CP0_Status & (1 << CP0St_IE)) && |
| 465 | - (env->CP0_Status & env->CP0_Cause & 0x0000FF00) && | ||
| 466 | - !(env->hflags & MIPS_HFLAG_EXL) && | ||
| 467 | - !(env->hflags & MIPS_HFLAG_ERL) && | 466 | + !(env->CP0_Status & (1 << CP0St_EXL)) && |
| 467 | + !(env->CP0_Status & (1 << CP0St_ERL)) && | ||
| 468 | !(env->hflags & MIPS_HFLAG_DM)) { | 468 | !(env->hflags & MIPS_HFLAG_DM)) { |
| 469 | /* Raise it */ | 469 | /* Raise it */ |
| 470 | env->exception_index = EXCP_EXT_INTERRUPT; | 470 | env->exception_index = EXCP_EXT_INTERRUPT; |
dyngen-exec.h
| @@ -80,6 +80,7 @@ typedef void * host_reg_t; | @@ -80,6 +80,7 @@ typedef void * host_reg_t; | ||
| 80 | 80 | ||
| 81 | typedef struct FILE FILE; | 81 | typedef struct FILE FILE; |
| 82 | extern int fprintf(FILE *, const char *, ...); | 82 | extern int fprintf(FILE *, const char *, ...); |
| 83 | +extern int fputs(const char *, FILE *); | ||
| 83 | extern int printf(const char *, ...); | 84 | extern int printf(const char *, ...); |
| 84 | #undef NULL | 85 | #undef NULL |
| 85 | #define NULL 0 | 86 | #define NULL 0 |
hw/mips_int.c
| @@ -5,17 +5,16 @@ | @@ -5,17 +5,16 @@ | ||
| 5 | IRQ may change */ | 5 | IRQ may change */ |
| 6 | void cpu_mips_update_irq(CPUState *env) | 6 | void cpu_mips_update_irq(CPUState *env) |
| 7 | { | 7 | { |
| 8 | - if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && | ||
| 9 | - (env->CP0_Status & (1 << CP0St_IE)) && | ||
| 10 | - !(env->hflags & MIPS_HFLAG_EXL) && | ||
| 11 | - !(env->hflags & MIPS_HFLAG_ERL) && | ||
| 12 | - !(env->hflags & MIPS_HFLAG_DM)) { | ||
| 13 | - if (! (env->interrupt_request & CPU_INTERRUPT_HARD)) { | 8 | + if ((env->CP0_Status & (1 << CP0St_IE)) && |
| 9 | + !(env->CP0_Status & (1 << CP0St_EXL)) && | ||
| 10 | + !(env->CP0_Status & (1 << CP0St_ERL)) && | ||
| 11 | + !(env->hflags & MIPS_HFLAG_DM)) { | ||
| 12 | + if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) && | ||
| 13 | + !(env->interrupt_request & CPU_INTERRUPT_HARD)) { | ||
| 14 | cpu_interrupt(env, CPU_INTERRUPT_HARD); | 14 | cpu_interrupt(env, CPU_INTERRUPT_HARD); |
| 15 | } | 15 | } |
| 16 | - } else { | 16 | + } else |
| 17 | cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); | 17 | cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
| 18 | - } | ||
| 19 | } | 18 | } |
| 20 | 19 | ||
| 21 | void cpu_mips_irq_request(void *opaque, int irq, int level) | 20 | void cpu_mips_irq_request(void *opaque, int irq, int level) |
target-mips/cpu.h
| @@ -248,8 +248,6 @@ struct CPUMIPSState { | @@ -248,8 +248,6 @@ struct CPUMIPSState { | ||
| 248 | #define MIPS_HFLAG_TMASK 0x007F | 248 | #define MIPS_HFLAG_TMASK 0x007F |
| 249 | #define MIPS_HFLAG_MODE 0x001F /* execution modes */ | 249 | #define MIPS_HFLAG_MODE 0x001F /* execution modes */ |
| 250 | #define MIPS_HFLAG_UM 0x0001 /* user mode */ | 250 | #define MIPS_HFLAG_UM 0x0001 /* user mode */ |
| 251 | -#define MIPS_HFLAG_ERL 0x0002 /* Error mode */ | ||
| 252 | -#define MIPS_HFLAG_EXL 0x0004 /* Exception mode */ | ||
| 253 | #define MIPS_HFLAG_DM 0x0008 /* Debug mode */ | 251 | #define MIPS_HFLAG_DM 0x0008 /* Debug mode */ |
| 254 | #define MIPS_HFLAG_SM 0x0010 /* Supervisor mode */ | 252 | #define MIPS_HFLAG_SM 0x0010 /* Supervisor mode */ |
| 255 | #define MIPS_HFLAG_RE 0x0040 /* Reversed endianness */ | 253 | #define MIPS_HFLAG_RE 0x0040 /* Reversed endianness */ |
target-mips/helper.c
| @@ -90,7 +90,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical, | @@ -90,7 +90,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical, | ||
| 90 | if (user_mode && address > 0x7FFFFFFFUL) | 90 | if (user_mode && address > 0x7FFFFFFFUL) |
| 91 | return TLBRET_BADADDR; | 91 | return TLBRET_BADADDR; |
| 92 | if (address < (int32_t)0x80000000UL) { | 92 | if (address < (int32_t)0x80000000UL) { |
| 93 | - if (!(env->hflags & MIPS_HFLAG_ERL)) { | 93 | + if (!(env->CP0_Status & (1 << CP0St_ERL))) { |
| 94 | #ifdef MIPS_USES_R4K_TLB | 94 | #ifdef MIPS_USES_R4K_TLB |
| 95 | ret = map_address(env, physical, prot, address, rw, access_type); | 95 | ret = map_address(env, physical, prot, address, rw, access_type); |
| 96 | #else | 96 | #else |
| @@ -289,21 +289,18 @@ void do_interrupt (CPUState *env) | @@ -289,21 +289,18 @@ void do_interrupt (CPUState *env) | ||
| 289 | goto set_DEPC; | 289 | goto set_DEPC; |
| 290 | case EXCP_DDBL: | 290 | case EXCP_DDBL: |
| 291 | env->CP0_Debug |= 1 << CP0DB_DDBL; | 291 | env->CP0_Debug |= 1 << CP0DB_DDBL; |
| 292 | - goto set_DEPC; | ||
| 293 | set_DEPC: | 292 | set_DEPC: |
| 294 | if (env->hflags & MIPS_HFLAG_BMASK) { | 293 | if (env->hflags & MIPS_HFLAG_BMASK) { |
| 295 | /* If the exception was raised from a delay slot, | 294 | /* If the exception was raised from a delay slot, |
| 296 | come back to the jump. */ | 295 | come back to the jump. */ |
| 297 | env->CP0_DEPC = env->PC - 4; | 296 | env->CP0_DEPC = env->PC - 4; |
| 298 | - if (!(env->hflags & MIPS_HFLAG_EXL)) | ||
| 299 | - env->CP0_Cause |= (1 << CP0Ca_BD); | ||
| 300 | env->hflags &= ~MIPS_HFLAG_BMASK; | 297 | env->hflags &= ~MIPS_HFLAG_BMASK; |
| 301 | } else { | 298 | } else { |
| 302 | env->CP0_DEPC = env->PC; | 299 | env->CP0_DEPC = env->PC; |
| 303 | - env->CP0_Cause &= ~(1 << CP0Ca_BD); | ||
| 304 | } | 300 | } |
| 305 | enter_debug_mode: | 301 | enter_debug_mode: |
| 306 | env->hflags |= MIPS_HFLAG_DM; | 302 | env->hflags |= MIPS_HFLAG_DM; |
| 303 | + env->hflags &= ~MIPS_HFLAG_UM; | ||
| 307 | /* EJTAG probe trap enable is not implemented... */ | 304 | /* EJTAG probe trap enable is not implemented... */ |
| 308 | env->PC = (int32_t)0xBFC00480; | 305 | env->PC = (int32_t)0xBFC00480; |
| 309 | break; | 306 | break; |
| @@ -311,25 +308,22 @@ void do_interrupt (CPUState *env) | @@ -311,25 +308,22 @@ void do_interrupt (CPUState *env) | ||
| 311 | cpu_reset(env); | 308 | cpu_reset(env); |
| 312 | break; | 309 | break; |
| 313 | case EXCP_SRESET: | 310 | case EXCP_SRESET: |
| 314 | - env->CP0_Status = (1 << CP0St_SR); | 311 | + env->CP0_Status |= (1 << CP0St_SR); |
| 315 | env->CP0_WatchLo = 0; | 312 | env->CP0_WatchLo = 0; |
| 316 | goto set_error_EPC; | 313 | goto set_error_EPC; |
| 317 | case EXCP_NMI: | 314 | case EXCP_NMI: |
| 318 | - env->CP0_Status = (1 << CP0St_NMI); | 315 | + env->CP0_Status |= (1 << CP0St_NMI); |
| 319 | set_error_EPC: | 316 | set_error_EPC: |
| 320 | if (env->hflags & MIPS_HFLAG_BMASK) { | 317 | if (env->hflags & MIPS_HFLAG_BMASK) { |
| 321 | /* If the exception was raised from a delay slot, | 318 | /* If the exception was raised from a delay slot, |
| 322 | come back to the jump. */ | 319 | come back to the jump. */ |
| 323 | env->CP0_ErrorEPC = env->PC - 4; | 320 | env->CP0_ErrorEPC = env->PC - 4; |
| 324 | - if (!(env->hflags & MIPS_HFLAG_EXL)) | ||
| 325 | - env->CP0_Cause |= (1 << CP0Ca_BD); | ||
| 326 | env->hflags &= ~MIPS_HFLAG_BMASK; | 321 | env->hflags &= ~MIPS_HFLAG_BMASK; |
| 327 | } else { | 322 | } else { |
| 328 | env->CP0_ErrorEPC = env->PC; | 323 | env->CP0_ErrorEPC = env->PC; |
| 329 | - env->CP0_Cause &= ~(1 << CP0Ca_BD); | ||
| 330 | } | 324 | } |
| 331 | - env->hflags |= MIPS_HFLAG_ERL; | ||
| 332 | - env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); | 325 | + env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); |
| 326 | + env->hflags &= ~MIPS_HFLAG_UM; | ||
| 333 | env->PC = (int32_t)0xBFC00000; | 327 | env->PC = (int32_t)0xBFC00000; |
| 334 | break; | 328 | break; |
| 335 | case EXCP_MCHECK: | 329 | case EXCP_MCHECK: |
| @@ -350,7 +344,7 @@ void do_interrupt (CPUState *env) | @@ -350,7 +344,7 @@ void do_interrupt (CPUState *env) | ||
| 350 | goto set_EPC; | 344 | goto set_EPC; |
| 351 | case EXCP_TLBL: | 345 | case EXCP_TLBL: |
| 352 | cause = 2; | 346 | cause = 2; |
| 353 | - if (env->error_code == 1 && !(env->hflags & MIPS_HFLAG_EXL)) | 347 | + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) |
| 354 | offset = 0x000; | 348 | offset = 0x000; |
| 355 | goto set_EPC; | 349 | goto set_EPC; |
| 356 | case EXCP_IBE: | 350 | case EXCP_IBE: |
| @@ -384,28 +378,29 @@ void do_interrupt (CPUState *env) | @@ -384,28 +378,29 @@ void do_interrupt (CPUState *env) | ||
| 384 | goto set_EPC; | 378 | goto set_EPC; |
| 385 | case EXCP_TLBS: | 379 | case EXCP_TLBS: |
| 386 | cause = 3; | 380 | cause = 3; |
| 387 | - if (env->error_code == 1 && !(env->hflags & MIPS_HFLAG_EXL)) | 381 | + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) |
| 388 | offset = 0x000; | 382 | offset = 0x000; |
| 389 | - goto set_EPC; | ||
| 390 | set_EPC: | 383 | set_EPC: |
| 391 | - if (env->hflags & MIPS_HFLAG_BMASK) { | ||
| 392 | - /* If the exception was raised from a delay slot, | ||
| 393 | - come back to the jump. */ | ||
| 394 | - env->CP0_EPC = env->PC - 4; | ||
| 395 | - if (!(env->hflags & MIPS_HFLAG_EXL)) | 384 | + if (!(env->CP0_Status & (1 << CP0St_EXL))) { |
| 385 | + if (env->hflags & MIPS_HFLAG_BMASK) { | ||
| 386 | + /* If the exception was raised from a delay slot, | ||
| 387 | + come back to the jump. */ | ||
| 388 | + env->CP0_EPC = env->PC - 4; | ||
| 396 | env->CP0_Cause |= (1 << CP0Ca_BD); | 389 | env->CP0_Cause |= (1 << CP0Ca_BD); |
| 397 | - env->hflags &= ~MIPS_HFLAG_BMASK; | 390 | + env->hflags &= ~MIPS_HFLAG_BMASK; |
| 391 | + } else { | ||
| 392 | + env->CP0_EPC = env->PC; | ||
| 393 | + env->CP0_Cause &= ~(1 << CP0Ca_BD); | ||
| 394 | + } | ||
| 398 | } else { | 395 | } else { |
| 399 | - env->CP0_EPC = env->PC; | ||
| 400 | - env->CP0_Cause &= ~(1 << CP0Ca_BD); | 396 | + env->CP0_Status |= (1 << CP0St_EXL); |
| 397 | + env->hflags &= ~MIPS_HFLAG_UM; | ||
| 401 | } | 398 | } |
| 402 | if (env->CP0_Status & (1 << CP0St_BEV)) { | 399 | if (env->CP0_Status & (1 << CP0St_BEV)) { |
| 403 | env->PC = (int32_t)0xBFC00200; | 400 | env->PC = (int32_t)0xBFC00200; |
| 404 | } else { | 401 | } else { |
| 405 | env->PC = (int32_t)0x80000000; | 402 | env->PC = (int32_t)0x80000000; |
| 406 | } | 403 | } |
| 407 | - env->hflags |= MIPS_HFLAG_EXL; | ||
| 408 | - env->CP0_Status |= (1 << CP0St_EXL); | ||
| 409 | env->PC += offset; | 404 | env->PC += offset; |
| 410 | env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2); | 405 | env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2); |
| 411 | break; | 406 | break; |
target-mips/op.c
| @@ -1105,12 +1105,6 @@ void op_mfc0_compare (void) | @@ -1105,12 +1105,6 @@ void op_mfc0_compare (void) | ||
| 1105 | void op_mfc0_status (void) | 1105 | void op_mfc0_status (void) |
| 1106 | { | 1106 | { |
| 1107 | T0 = env->CP0_Status; | 1107 | T0 = env->CP0_Status; |
| 1108 | - if (env->hflags & MIPS_HFLAG_UM) | ||
| 1109 | - T0 |= (1 << CP0St_UM); | ||
| 1110 | - if (env->hflags & MIPS_HFLAG_ERL) | ||
| 1111 | - T0 |= (1 << CP0St_ERL); | ||
| 1112 | - if (env->hflags & MIPS_HFLAG_EXL) | ||
| 1113 | - T0 |= (1 << CP0St_EXL); | ||
| 1114 | RETURN(); | 1108 | RETURN(); |
| 1115 | } | 1109 | } |
| 1116 | 1110 | ||
| @@ -1365,20 +1359,10 @@ void op_mtc0_status (void) | @@ -1365,20 +1359,10 @@ void op_mtc0_status (void) | ||
| 1365 | { | 1359 | { |
| 1366 | uint32_t val, old; | 1360 | uint32_t val, old; |
| 1367 | 1361 | ||
| 1368 | - val = (int32_t)T0 & 0xFA78FF01; | 1362 | + /* No 64bit FPU, no reverse endianness, no MDMX/DSP, no 64bit ops, |
| 1363 | + no 64bit addressing implemented. */ | ||
| 1364 | + val = (int32_t)T0 & 0xF878FF17; | ||
| 1369 | old = env->CP0_Status; | 1365 | old = env->CP0_Status; |
| 1370 | - if (T0 & (1 << CP0St_UM)) | ||
| 1371 | - env->hflags |= MIPS_HFLAG_UM; | ||
| 1372 | - else | ||
| 1373 | - env->hflags &= ~MIPS_HFLAG_UM; | ||
| 1374 | - if (T0 & (1 << CP0St_ERL)) | ||
| 1375 | - env->hflags |= MIPS_HFLAG_ERL; | ||
| 1376 | - else | ||
| 1377 | - env->hflags &= ~MIPS_HFLAG_ERL; | ||
| 1378 | - if (T0 & (1 << CP0St_EXL)) | ||
| 1379 | - env->hflags |= MIPS_HFLAG_EXL; | ||
| 1380 | - else | ||
| 1381 | - env->hflags &= ~MIPS_HFLAG_EXL; | ||
| 1382 | env->CP0_Status = val; | 1366 | env->CP0_Status = val; |
| 1383 | if (loglevel & CPU_LOG_TB_IN_ASM) | 1367 | if (loglevel & CPU_LOG_TB_IN_ASM) |
| 1384 | CALL_FROM_TB2(do_mtc0_status_debug, old, val); | 1368 | CALL_FROM_TB2(do_mtc0_status_debug, old, val); |
| @@ -1662,6 +1646,15 @@ void op_dmtc0_errorepc (void) | @@ -1662,6 +1646,15 @@ void op_dmtc0_errorepc (void) | ||
| 1662 | # define DEBUG_FPU_STATE() do { } while(0) | 1646 | # define DEBUG_FPU_STATE() do { } while(0) |
| 1663 | #endif | 1647 | #endif |
| 1664 | 1648 | ||
| 1649 | +void op_cp0_enabled(void) | ||
| 1650 | +{ | ||
| 1651 | + if (!(env->CP0_Status & (1 << CP0St_CU0)) && | ||
| 1652 | + (env->hflags & MIPS_HFLAG_UM)) { | ||
| 1653 | + CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 0); | ||
| 1654 | + } | ||
| 1655 | + RETURN(); | ||
| 1656 | +} | ||
| 1657 | + | ||
| 1665 | void op_cp1_enabled(void) | 1658 | void op_cp1_enabled(void) |
| 1666 | { | 1659 | { |
| 1667 | if (!(env->CP0_Status & (1 << CP0St_CU1))) { | 1660 | if (!(env->CP0_Status & (1 << CP0St_CU1))) { |
| @@ -2091,15 +2084,18 @@ void debug_eret (void); | @@ -2091,15 +2084,18 @@ void debug_eret (void); | ||
| 2091 | void op_eret (void) | 2084 | void op_eret (void) |
| 2092 | { | 2085 | { |
| 2093 | CALL_FROM_TB0(debug_eret); | 2086 | CALL_FROM_TB0(debug_eret); |
| 2094 | - if (env->hflags & MIPS_HFLAG_ERL) { | 2087 | + if (env->CP0_Status & (1 << CP0St_ERL)) { |
| 2095 | env->PC = env->CP0_ErrorEPC; | 2088 | env->PC = env->CP0_ErrorEPC; |
| 2096 | - env->hflags &= ~MIPS_HFLAG_ERL; | ||
| 2097 | - env->CP0_Status &= ~(1 << CP0St_ERL); | 2089 | + env->CP0_Status &= ~(1 << CP0St_ERL); |
| 2098 | } else { | 2090 | } else { |
| 2099 | env->PC = env->CP0_EPC; | 2091 | env->PC = env->CP0_EPC; |
| 2100 | - env->hflags &= ~MIPS_HFLAG_EXL; | ||
| 2101 | - env->CP0_Status &= ~(1 << CP0St_EXL); | 2092 | + env->CP0_Status &= ~(1 << CP0St_EXL); |
| 2102 | } | 2093 | } |
| 2094 | + if (!(env->CP0_Status & (1 << CP0St_EXL)) && | ||
| 2095 | + !(env->CP0_Status & (1 << CP0St_ERL)) && | ||
| 2096 | + !(env->hflags & MIPS_HFLAG_DM) && | ||
| 2097 | + (env->CP0_Status & (1 << CP0St_UM))) | ||
| 2098 | + env->hflags |= MIPS_HFLAG_UM; | ||
| 2103 | env->CP0_LLAddr = 1; | 2099 | env->CP0_LLAddr = 1; |
| 2104 | RETURN(); | 2100 | RETURN(); |
| 2105 | } | 2101 | } |
| @@ -2108,6 +2104,13 @@ void op_deret (void) | @@ -2108,6 +2104,13 @@ void op_deret (void) | ||
| 2108 | { | 2104 | { |
| 2109 | CALL_FROM_TB0(debug_eret); | 2105 | CALL_FROM_TB0(debug_eret); |
| 2110 | env->PC = env->CP0_DEPC; | 2106 | env->PC = env->CP0_DEPC; |
| 2107 | + env->hflags |= MIPS_HFLAG_DM; | ||
| 2108 | + if (!(env->CP0_Status & (1 << CP0St_EXL)) && | ||
| 2109 | + !(env->CP0_Status & (1 << CP0St_ERL)) && | ||
| 2110 | + !(env->hflags & MIPS_HFLAG_DM) && | ||
| 2111 | + (env->CP0_Status & (1 << CP0St_UM))) | ||
| 2112 | + env->hflags |= MIPS_HFLAG_UM; | ||
| 2113 | + env->CP0_LLAddr = 1; | ||
| 2111 | RETURN(); | 2114 | RETURN(); |
| 2112 | } | 2115 | } |
| 2113 | 2116 |
target-mips/op_helper.c
| @@ -509,9 +509,11 @@ void dump_sc (void) | @@ -509,9 +509,11 @@ void dump_sc (void) | ||
| 509 | void debug_eret (void) | 509 | void debug_eret (void) |
| 510 | { | 510 | { |
| 511 | if (loglevel) { | 511 | if (loglevel) { |
| 512 | - fprintf(logfile, "ERET: pc " TARGET_FMT_lx " EPC " TARGET_FMT_lx " ErrorEPC " TARGET_FMT_lx " (%d)\n", | ||
| 513 | - env->PC, env->CP0_EPC, env->CP0_ErrorEPC, | ||
| 514 | - env->hflags & MIPS_HFLAG_ERL ? 1 : 0); | 512 | + fprintf(logfile, "ERET: pc " TARGET_FMT_lx " EPC " TARGET_FMT_lx, |
| 513 | + env->PC, env->CP0_EPC); | ||
| 514 | + if (env->CP0_Status & (1 << CP0St_ERL)) | ||
| 515 | + fprintf(logfile, " ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC); | ||
| 516 | + fputs("\n", logfile); | ||
| 515 | } | 517 | } |
| 516 | } | 518 | } |
| 517 | 519 |
target-mips/translate.c
| @@ -4022,17 +4022,6 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd) | @@ -4022,17 +4022,6 @@ static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd) | ||
| 4022 | { | 4022 | { |
| 4023 | const char *opn = "unk"; | 4023 | const char *opn = "unk"; |
| 4024 | 4024 | ||
| 4025 | - if ((!ctx->CP0_Status & (1 << CP0St_CU0) && | ||
| 4026 | - (ctx->hflags & MIPS_HFLAG_UM)) && | ||
| 4027 | - !(ctx->hflags & MIPS_HFLAG_ERL) && | ||
| 4028 | - !(ctx->hflags & MIPS_HFLAG_EXL)) { | ||
| 4029 | - if (loglevel & CPU_LOG_TB_IN_ASM) { | ||
| 4030 | - fprintf(logfile, "CP0 is not usable\n"); | ||
| 4031 | - } | ||
| 4032 | - generate_exception (ctx, EXCP_CpU); | ||
| 4033 | - return; | ||
| 4034 | - } | ||
| 4035 | - | ||
| 4036 | switch (opc) { | 4025 | switch (opc) { |
| 4037 | case OPC_MFC0: | 4026 | case OPC_MFC0: |
| 4038 | if (rt == 0) { | 4027 | if (rt == 0) { |
| @@ -4809,7 +4798,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4809,7 +4798,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 4809 | gen_trap(ctx, op1, rs, -1, imm); | 4798 | gen_trap(ctx, op1, rs, -1, imm); |
| 4810 | break; | 4799 | break; |
| 4811 | case OPC_SYNCI: | 4800 | case OPC_SYNCI: |
| 4812 | - /* treat as noop */ | 4801 | + /* treat as noop */ |
| 4813 | break; | 4802 | break; |
| 4814 | default: /* Invalid */ | 4803 | default: /* Invalid */ |
| 4815 | MIPS_INVAL("REGIMM"); | 4804 | MIPS_INVAL("REGIMM"); |
| @@ -4818,6 +4807,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4818,6 +4807,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
| 4818 | } | 4807 | } |
| 4819 | break; | 4808 | break; |
| 4820 | case OPC_CP0: | 4809 | case OPC_CP0: |
| 4810 | + gen_op_cp0_enabled(); | ||
| 4821 | op1 = MASK_CP0(ctx->opcode); | 4811 | op1 = MASK_CP0(ctx->opcode); |
| 4822 | switch (op1) { | 4812 | switch (op1) { |
| 4823 | case OPC_MFC0: | 4813 | case OPC_MFC0: |
| @@ -5258,12 +5248,6 @@ void cpu_dump_state (CPUState *env, FILE *f, | @@ -5258,12 +5248,6 @@ void cpu_dump_state (CPUState *env, FILE *f, | ||
| 5258 | } | 5248 | } |
| 5259 | 5249 | ||
| 5260 | c0_status = env->CP0_Status; | 5250 | c0_status = env->CP0_Status; |
| 5261 | - if (env->hflags & MIPS_HFLAG_UM) | ||
| 5262 | - c0_status |= (1 << CP0St_UM); | ||
| 5263 | - if (env->hflags & MIPS_HFLAG_ERL) | ||
| 5264 | - c0_status |= (1 << CP0St_ERL); | ||
| 5265 | - if (env->hflags & MIPS_HFLAG_EXL) | ||
| 5266 | - c0_status |= (1 << CP0St_EXL); | ||
| 5267 | 5251 | ||
| 5268 | cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n", | 5252 | cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n", |
| 5269 | c0_status, env->CP0_Cause, env->CP0_EPC); | 5253 | c0_status, env->CP0_Cause, env->CP0_EPC); |
| @@ -5304,6 +5288,7 @@ void cpu_reset (CPUMIPSState *env) | @@ -5304,6 +5288,7 @@ void cpu_reset (CPUMIPSState *env) | ||
| 5304 | } else { | 5288 | } else { |
| 5305 | env->CP0_ErrorEPC = env->PC; | 5289 | env->CP0_ErrorEPC = env->PC; |
| 5306 | } | 5290 | } |
| 5291 | + env->hflags = 0; | ||
| 5307 | env->PC = (int32_t)0xBFC00000; | 5292 | env->PC = (int32_t)0xBFC00000; |
| 5308 | #if defined (MIPS_USES_R4K_TLB) | 5293 | #if defined (MIPS_USES_R4K_TLB) |
| 5309 | env->CP0_Random = MIPS_TLB_NB - 1; | 5294 | env->CP0_Random = MIPS_TLB_NB - 1; |
| @@ -5314,7 +5299,6 @@ void cpu_reset (CPUMIPSState *env) | @@ -5314,7 +5299,6 @@ void cpu_reset (CPUMIPSState *env) | ||
| 5314 | env->CP0_EBase = 0x80000000; | 5299 | env->CP0_EBase = 0x80000000; |
| 5315 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); | 5300 | env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); |
| 5316 | env->CP0_WatchLo = 0; | 5301 | env->CP0_WatchLo = 0; |
| 5317 | - env->hflags = MIPS_HFLAG_ERL; | ||
| 5318 | /* Count register increments in debug mode, EJTAG version 1 */ | 5302 | /* Count register increments in debug mode, EJTAG version 1 */ |
| 5319 | env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); | 5303 | env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); |
| 5320 | #endif | 5304 | #endif |