Commit 932e71cd57bab4e6206e1355c6425290721bbe34
1 parent
ae1c1a3d
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
Showing
3 changed files
with
274 additions
and
275 deletions
target-mips/helper.c
| ... | ... | @@ -100,6 +100,7 @@ int r4k_map_address (CPUState *env, target_ulong *physical, int *prot, |
| 100 | 100 | return TLBRET_NOMATCH; |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | +#if !defined(CONFIG_USER_ONLY) | |
| 103 | 104 | static int get_physical_address (CPUState *env, target_ulong *physical, |
| 104 | 105 | int *prot, target_ulong address, |
| 105 | 106 | int rw, int access_type) |
| ... | ... | @@ -205,26 +206,29 @@ static int get_physical_address (CPUState *env, target_ulong *physical, |
| 205 | 206 | |
| 206 | 207 | return ret; |
| 207 | 208 | } |
| 209 | +#endif | |
| 208 | 210 | |
| 209 | 211 | target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
| 210 | 212 | { |
| 211 | - if (env->user_mode_only) | |
| 212 | - return addr; | |
| 213 | - else { | |
| 214 | - target_ulong phys_addr; | |
| 215 | - int prot; | |
| 213 | +#if defined(CONFIG_USER_ONLY) | |
| 214 | + return addr; | |
| 215 | +#else | |
| 216 | + target_ulong phys_addr; | |
| 217 | + int prot; | |
| 216 | 218 | |
| 217 | - if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) | |
| 218 | - return -1; | |
| 219 | - return phys_addr; | |
| 220 | - } | |
| 219 | + if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) | |
| 220 | + return -1; | |
| 221 | + return phys_addr; | |
| 222 | +#endif | |
| 221 | 223 | } |
| 222 | 224 | |
| 223 | 225 | int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 224 | 226 | int mmu_idx, int is_softmmu) |
| 225 | 227 | { |
| 228 | +#if !defined(CONFIG_USER_ONLY) | |
| 226 | 229 | target_ulong physical; |
| 227 | 230 | int prot; |
| 231 | +#endif | |
| 228 | 232 | int exception = 0, error_code = 0; |
| 229 | 233 | int access_type; |
| 230 | 234 | int ret = 0; |
| ... | ... | @@ -243,11 +247,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 243 | 247 | /* XXX: put correct access by using cpu_restore_state() |
| 244 | 248 | correctly */ |
| 245 | 249 | access_type = ACCESS_INT; |
| 246 | - if (env->user_mode_only) { | |
| 247 | - /* user mode only emulation */ | |
| 248 | - ret = TLBRET_NOMATCH; | |
| 249 | - goto do_fault; | |
| 250 | - } | |
| 250 | +#if defined(CONFIG_USER_ONLY) | |
| 251 | + ret = TLBRET_NOMATCH; | |
| 252 | +#else | |
| 251 | 253 | ret = get_physical_address(env, &physical, &prot, |
| 252 | 254 | address, rw, access_type); |
| 253 | 255 | if (logfile) { |
| ... | ... | @@ -258,8 +260,9 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 258 | 260 | ret = tlb_set_page(env, address & TARGET_PAGE_MASK, |
| 259 | 261 | physical & TARGET_PAGE_MASK, prot, |
| 260 | 262 | mmu_idx, is_softmmu); |
| 261 | - } else if (ret < 0) { | |
| 262 | - do_fault: | |
| 263 | + } else if (ret < 0) | |
| 264 | +#endif | |
| 265 | + { | |
| 263 | 266 | switch (ret) { |
| 264 | 267 | default: |
| 265 | 268 | case TLBRET_BADADDR: |
| ... | ... | @@ -349,227 +352,227 @@ static const char * const excp_names[EXCP_LAST + 1] = { |
| 349 | 352 | |
| 350 | 353 | void do_interrupt (CPUState *env) |
| 351 | 354 | { |
| 352 | - if (!env->user_mode_only) { | |
| 353 | - target_ulong offset; | |
| 354 | - int cause = -1; | |
| 355 | - const char *name; | |
| 355 | +#if !defined(CONFIG_USER_ONLY) | |
| 356 | + target_ulong offset; | |
| 357 | + int cause = -1; | |
| 358 | + const char *name; | |
| 356 | 359 | |
| 357 | - if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { | |
| 358 | - if (env->exception_index < 0 || env->exception_index > EXCP_LAST) | |
| 359 | - name = "unknown"; | |
| 360 | - else | |
| 361 | - name = excp_names[env->exception_index]; | |
| 360 | + if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { | |
| 361 | + if (env->exception_index < 0 || env->exception_index > EXCP_LAST) | |
| 362 | + name = "unknown"; | |
| 363 | + else | |
| 364 | + name = excp_names[env->exception_index]; | |
| 362 | 365 | |
| 363 | - fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", | |
| 364 | - __func__, env->active_tc.PC, env->CP0_EPC, name); | |
| 365 | - } | |
| 366 | - if (env->exception_index == EXCP_EXT_INTERRUPT && | |
| 367 | - (env->hflags & MIPS_HFLAG_DM)) | |
| 368 | - env->exception_index = EXCP_DINT; | |
| 369 | - offset = 0x180; | |
| 370 | - switch (env->exception_index) { | |
| 371 | - case EXCP_DSS: | |
| 372 | - env->CP0_Debug |= 1 << CP0DB_DSS; | |
| 373 | - /* Debug single step cannot be raised inside a delay slot and | |
| 374 | - resume will always occur on the next instruction | |
| 375 | - (but we assume the pc has always been updated during | |
| 376 | - code translation). */ | |
| 366 | + fprintf(logfile, "%s enter: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " %s exception\n", | |
| 367 | + __func__, env->active_tc.PC, env->CP0_EPC, name); | |
| 368 | + } | |
| 369 | + if (env->exception_index == EXCP_EXT_INTERRUPT && | |
| 370 | + (env->hflags & MIPS_HFLAG_DM)) | |
| 371 | + env->exception_index = EXCP_DINT; | |
| 372 | + offset = 0x180; | |
| 373 | + switch (env->exception_index) { | |
| 374 | + case EXCP_DSS: | |
| 375 | + env->CP0_Debug |= 1 << CP0DB_DSS; | |
| 376 | + /* Debug single step cannot be raised inside a delay slot and | |
| 377 | + resume will always occur on the next instruction | |
| 378 | + (but we assume the pc has always been updated during | |
| 379 | + code translation). */ | |
| 380 | + env->CP0_DEPC = env->active_tc.PC; | |
| 381 | + goto enter_debug_mode; | |
| 382 | + case EXCP_DINT: | |
| 383 | + env->CP0_Debug |= 1 << CP0DB_DINT; | |
| 384 | + goto set_DEPC; | |
| 385 | + case EXCP_DIB: | |
| 386 | + env->CP0_Debug |= 1 << CP0DB_DIB; | |
| 387 | + goto set_DEPC; | |
| 388 | + case EXCP_DBp: | |
| 389 | + env->CP0_Debug |= 1 << CP0DB_DBp; | |
| 390 | + goto set_DEPC; | |
| 391 | + case EXCP_DDBS: | |
| 392 | + env->CP0_Debug |= 1 << CP0DB_DDBS; | |
| 393 | + goto set_DEPC; | |
| 394 | + case EXCP_DDBL: | |
| 395 | + env->CP0_Debug |= 1 << CP0DB_DDBL; | |
| 396 | + set_DEPC: | |
| 397 | + if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 398 | + /* If the exception was raised from a delay slot, | |
| 399 | + come back to the jump. */ | |
| 400 | + env->CP0_DEPC = env->active_tc.PC - 4; | |
| 401 | + env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 402 | + } else { | |
| 377 | 403 | env->CP0_DEPC = env->active_tc.PC; |
| 378 | - goto enter_debug_mode; | |
| 379 | - case EXCP_DINT: | |
| 380 | - env->CP0_Debug |= 1 << CP0DB_DINT; | |
| 381 | - goto set_DEPC; | |
| 382 | - case EXCP_DIB: | |
| 383 | - env->CP0_Debug |= 1 << CP0DB_DIB; | |
| 384 | - goto set_DEPC; | |
| 385 | - case EXCP_DBp: | |
| 386 | - env->CP0_Debug |= 1 << CP0DB_DBp; | |
| 387 | - goto set_DEPC; | |
| 388 | - case EXCP_DDBS: | |
| 389 | - env->CP0_Debug |= 1 << CP0DB_DDBS; | |
| 390 | - goto set_DEPC; | |
| 391 | - case EXCP_DDBL: | |
| 392 | - env->CP0_Debug |= 1 << CP0DB_DDBL; | |
| 393 | - set_DEPC: | |
| 394 | - if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 395 | - /* If the exception was raised from a delay slot, | |
| 396 | - come back to the jump. */ | |
| 397 | - env->CP0_DEPC = env->active_tc.PC - 4; | |
| 398 | - env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 399 | - } else { | |
| 400 | - env->CP0_DEPC = env->active_tc.PC; | |
| 401 | - } | |
| 404 | + } | |
| 402 | 405 | enter_debug_mode: |
| 403 | - env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0; | |
| 404 | - env->hflags &= ~(MIPS_HFLAG_KSU); | |
| 405 | - /* EJTAG probe trap enable is not implemented... */ | |
| 406 | - if (!(env->CP0_Status & (1 << CP0St_EXL))) | |
| 407 | - env->CP0_Cause &= ~(1 << CP0Ca_BD); | |
| 408 | - env->active_tc.PC = (int32_t)0xBFC00480; | |
| 409 | - break; | |
| 410 | - case EXCP_RESET: | |
| 411 | - cpu_reset(env); | |
| 412 | - break; | |
| 413 | - case EXCP_SRESET: | |
| 414 | - env->CP0_Status |= (1 << CP0St_SR); | |
| 415 | - memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo)); | |
| 416 | - goto set_error_EPC; | |
| 417 | - case EXCP_NMI: | |
| 418 | - env->CP0_Status |= (1 << CP0St_NMI); | |
| 406 | + env->hflags |= MIPS_HFLAG_DM | MIPS_HFLAG_64 | MIPS_HFLAG_CP0; | |
| 407 | + env->hflags &= ~(MIPS_HFLAG_KSU); | |
| 408 | + /* EJTAG probe trap enable is not implemented... */ | |
| 409 | + if (!(env->CP0_Status & (1 << CP0St_EXL))) | |
| 410 | + env->CP0_Cause &= ~(1 << CP0Ca_BD); | |
| 411 | + env->active_tc.PC = (int32_t)0xBFC00480; | |
| 412 | + break; | |
| 413 | + case EXCP_RESET: | |
| 414 | + cpu_reset(env); | |
| 415 | + break; | |
| 416 | + case EXCP_SRESET: | |
| 417 | + env->CP0_Status |= (1 << CP0St_SR); | |
| 418 | + memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo)); | |
| 419 | + goto set_error_EPC; | |
| 420 | + case EXCP_NMI: | |
| 421 | + env->CP0_Status |= (1 << CP0St_NMI); | |
| 419 | 422 | set_error_EPC: |
| 420 | - if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 421 | - /* If the exception was raised from a delay slot, | |
| 422 | - come back to the jump. */ | |
| 423 | - env->CP0_ErrorEPC = env->active_tc.PC - 4; | |
| 424 | - env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 425 | - } else { | |
| 426 | - env->CP0_ErrorEPC = env->active_tc.PC; | |
| 427 | - } | |
| 428 | - env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); | |
| 429 | - env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; | |
| 430 | - env->hflags &= ~(MIPS_HFLAG_KSU); | |
| 431 | - if (!(env->CP0_Status & (1 << CP0St_EXL))) | |
| 432 | - env->CP0_Cause &= ~(1 << CP0Ca_BD); | |
| 433 | - env->active_tc.PC = (int32_t)0xBFC00000; | |
| 434 | - break; | |
| 435 | - case EXCP_EXT_INTERRUPT: | |
| 436 | - cause = 0; | |
| 437 | - if (env->CP0_Cause & (1 << CP0Ca_IV)) | |
| 438 | - offset = 0x200; | |
| 439 | - goto set_EPC; | |
| 440 | - case EXCP_LTLBL: | |
| 441 | - cause = 1; | |
| 442 | - goto set_EPC; | |
| 443 | - case EXCP_TLBL: | |
| 444 | - cause = 2; | |
| 445 | - if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 423 | + if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 424 | + /* If the exception was raised from a delay slot, | |
| 425 | + come back to the jump. */ | |
| 426 | + env->CP0_ErrorEPC = env->active_tc.PC - 4; | |
| 427 | + env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 428 | + } else { | |
| 429 | + env->CP0_ErrorEPC = env->active_tc.PC; | |
| 430 | + } | |
| 431 | + env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); | |
| 432 | + env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; | |
| 433 | + env->hflags &= ~(MIPS_HFLAG_KSU); | |
| 434 | + if (!(env->CP0_Status & (1 << CP0St_EXL))) | |
| 435 | + env->CP0_Cause &= ~(1 << CP0Ca_BD); | |
| 436 | + env->active_tc.PC = (int32_t)0xBFC00000; | |
| 437 | + break; | |
| 438 | + case EXCP_EXT_INTERRUPT: | |
| 439 | + cause = 0; | |
| 440 | + if (env->CP0_Cause & (1 << CP0Ca_IV)) | |
| 441 | + offset = 0x200; | |
| 442 | + goto set_EPC; | |
| 443 | + case EXCP_LTLBL: | |
| 444 | + cause = 1; | |
| 445 | + goto set_EPC; | |
| 446 | + case EXCP_TLBL: | |
| 447 | + cause = 2; | |
| 448 | + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 446 | 449 | #if defined(TARGET_MIPS64) |
| 447 | - int R = env->CP0_BadVAddr >> 62; | |
| 448 | - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; | |
| 449 | - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; | |
| 450 | - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; | |
| 450 | + int R = env->CP0_BadVAddr >> 62; | |
| 451 | + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; | |
| 452 | + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; | |
| 453 | + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; | |
| 451 | 454 | |
| 452 | - if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) | |
| 453 | - offset = 0x080; | |
| 454 | - else | |
| 455 | + if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) | |
| 456 | + offset = 0x080; | |
| 457 | + else | |
| 455 | 458 | #endif |
| 456 | - offset = 0x000; | |
| 457 | - } | |
| 458 | - goto set_EPC; | |
| 459 | - case EXCP_TLBS: | |
| 460 | - cause = 3; | |
| 461 | - if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 459 | + offset = 0x000; | |
| 460 | + } | |
| 461 | + goto set_EPC; | |
| 462 | + case EXCP_TLBS: | |
| 463 | + cause = 3; | |
| 464 | + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 462 | 465 | #if defined(TARGET_MIPS64) |
| 463 | - int R = env->CP0_BadVAddr >> 62; | |
| 464 | - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; | |
| 465 | - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; | |
| 466 | - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; | |
| 466 | + int R = env->CP0_BadVAddr >> 62; | |
| 467 | + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; | |
| 468 | + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; | |
| 469 | + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; | |
| 467 | 470 | |
| 468 | - if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) | |
| 469 | - offset = 0x080; | |
| 470 | - else | |
| 471 | + if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) | |
| 472 | + offset = 0x080; | |
| 473 | + else | |
| 471 | 474 | #endif |
| 472 | - offset = 0x000; | |
| 473 | - } | |
| 474 | - goto set_EPC; | |
| 475 | - case EXCP_AdEL: | |
| 476 | - cause = 4; | |
| 477 | - goto set_EPC; | |
| 478 | - case EXCP_AdES: | |
| 479 | - cause = 5; | |
| 480 | - goto set_EPC; | |
| 481 | - case EXCP_IBE: | |
| 482 | - cause = 6; | |
| 483 | - goto set_EPC; | |
| 484 | - case EXCP_DBE: | |
| 485 | - cause = 7; | |
| 486 | - goto set_EPC; | |
| 487 | - case EXCP_SYSCALL: | |
| 488 | - cause = 8; | |
| 489 | - goto set_EPC; | |
| 490 | - case EXCP_BREAK: | |
| 491 | - cause = 9; | |
| 492 | - goto set_EPC; | |
| 493 | - case EXCP_RI: | |
| 494 | - cause = 10; | |
| 495 | - goto set_EPC; | |
| 496 | - case EXCP_CpU: | |
| 497 | - cause = 11; | |
| 498 | - env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | | |
| 499 | - (env->error_code << CP0Ca_CE); | |
| 500 | - goto set_EPC; | |
| 501 | - case EXCP_OVERFLOW: | |
| 502 | - cause = 12; | |
| 503 | - goto set_EPC; | |
| 504 | - case EXCP_TRAP: | |
| 505 | - cause = 13; | |
| 506 | - goto set_EPC; | |
| 507 | - case EXCP_FPE: | |
| 508 | - cause = 15; | |
| 509 | - goto set_EPC; | |
| 510 | - case EXCP_C2E: | |
| 511 | - cause = 18; | |
| 512 | - goto set_EPC; | |
| 513 | - case EXCP_MDMX: | |
| 514 | - cause = 22; | |
| 515 | - goto set_EPC; | |
| 516 | - case EXCP_DWATCH: | |
| 517 | - cause = 23; | |
| 518 | - /* XXX: TODO: manage defered watch exceptions */ | |
| 519 | - goto set_EPC; | |
| 520 | - case EXCP_MCHECK: | |
| 521 | - cause = 24; | |
| 522 | - goto set_EPC; | |
| 523 | - case EXCP_THREAD: | |
| 524 | - cause = 25; | |
| 525 | - goto set_EPC; | |
| 526 | - case EXCP_CACHE: | |
| 527 | - cause = 30; | |
| 528 | - if (env->CP0_Status & (1 << CP0St_BEV)) { | |
| 529 | - offset = 0x100; | |
| 530 | - } else { | |
| 531 | - offset = 0x20000100; | |
| 532 | - } | |
| 475 | + offset = 0x000; | |
| 476 | + } | |
| 477 | + goto set_EPC; | |
| 478 | + case EXCP_AdEL: | |
| 479 | + cause = 4; | |
| 480 | + goto set_EPC; | |
| 481 | + case EXCP_AdES: | |
| 482 | + cause = 5; | |
| 483 | + goto set_EPC; | |
| 484 | + case EXCP_IBE: | |
| 485 | + cause = 6; | |
| 486 | + goto set_EPC; | |
| 487 | + case EXCP_DBE: | |
| 488 | + cause = 7; | |
| 489 | + goto set_EPC; | |
| 490 | + case EXCP_SYSCALL: | |
| 491 | + cause = 8; | |
| 492 | + goto set_EPC; | |
| 493 | + case EXCP_BREAK: | |
| 494 | + cause = 9; | |
| 495 | + goto set_EPC; | |
| 496 | + case EXCP_RI: | |
| 497 | + cause = 10; | |
| 498 | + goto set_EPC; | |
| 499 | + case EXCP_CpU: | |
| 500 | + cause = 11; | |
| 501 | + env->CP0_Cause = (env->CP0_Cause & ~(0x3 << CP0Ca_CE)) | | |
| 502 | + (env->error_code << CP0Ca_CE); | |
| 503 | + goto set_EPC; | |
| 504 | + case EXCP_OVERFLOW: | |
| 505 | + cause = 12; | |
| 506 | + goto set_EPC; | |
| 507 | + case EXCP_TRAP: | |
| 508 | + cause = 13; | |
| 509 | + goto set_EPC; | |
| 510 | + case EXCP_FPE: | |
| 511 | + cause = 15; | |
| 512 | + goto set_EPC; | |
| 513 | + case EXCP_C2E: | |
| 514 | + cause = 18; | |
| 515 | + goto set_EPC; | |
| 516 | + case EXCP_MDMX: | |
| 517 | + cause = 22; | |
| 518 | + goto set_EPC; | |
| 519 | + case EXCP_DWATCH: | |
| 520 | + cause = 23; | |
| 521 | + /* XXX: TODO: manage defered watch exceptions */ | |
| 522 | + goto set_EPC; | |
| 523 | + case EXCP_MCHECK: | |
| 524 | + cause = 24; | |
| 525 | + goto set_EPC; | |
| 526 | + case EXCP_THREAD: | |
| 527 | + cause = 25; | |
| 528 | + goto set_EPC; | |
| 529 | + case EXCP_CACHE: | |
| 530 | + cause = 30; | |
| 531 | + if (env->CP0_Status & (1 << CP0St_BEV)) { | |
| 532 | + offset = 0x100; | |
| 533 | + } else { | |
| 534 | + offset = 0x20000100; | |
| 535 | + } | |
| 533 | 536 | set_EPC: |
| 534 | - if (!(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 535 | - if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 536 | - /* If the exception was raised from a delay slot, | |
| 537 | - come back to the jump. */ | |
| 538 | - env->CP0_EPC = env->active_tc.PC - 4; | |
| 539 | - env->CP0_Cause |= (1 << CP0Ca_BD); | |
| 540 | - } else { | |
| 541 | - env->CP0_EPC = env->active_tc.PC; | |
| 542 | - env->CP0_Cause &= ~(1 << CP0Ca_BD); | |
| 543 | - } | |
| 544 | - env->CP0_Status |= (1 << CP0St_EXL); | |
| 545 | - env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; | |
| 546 | - env->hflags &= ~(MIPS_HFLAG_KSU); | |
| 547 | - } | |
| 548 | - env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 549 | - if (env->CP0_Status & (1 << CP0St_BEV)) { | |
| 550 | - env->active_tc.PC = (int32_t)0xBFC00200; | |
| 537 | + if (!(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 538 | + if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 539 | + /* If the exception was raised from a delay slot, | |
| 540 | + come back to the jump. */ | |
| 541 | + env->CP0_EPC = env->active_tc.PC - 4; | |
| 542 | + env->CP0_Cause |= (1 << CP0Ca_BD); | |
| 551 | 543 | } else { |
| 552 | - env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); | |
| 553 | - } | |
| 554 | - env->active_tc.PC += offset; | |
| 555 | - env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); | |
| 556 | - break; | |
| 557 | - default: | |
| 558 | - if (logfile) { | |
| 559 | - fprintf(logfile, "Invalid MIPS exception %d. Exiting\n", | |
| 560 | - env->exception_index); | |
| 544 | + env->CP0_EPC = env->active_tc.PC; | |
| 545 | + env->CP0_Cause &= ~(1 << CP0Ca_BD); | |
| 561 | 546 | } |
| 562 | - printf("Invalid MIPS exception %d. Exiting\n", env->exception_index); | |
| 563 | - exit(1); | |
| 547 | + env->CP0_Status |= (1 << CP0St_EXL); | |
| 548 | + env->hflags |= MIPS_HFLAG_64 | MIPS_HFLAG_CP0; | |
| 549 | + env->hflags &= ~(MIPS_HFLAG_KSU); | |
| 564 | 550 | } |
| 565 | - if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { | |
| 566 | - fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" | |
| 567 | - " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", | |
| 568 | - __func__, env->active_tc.PC, env->CP0_EPC, cause, | |
| 569 | - env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, | |
| 570 | - env->CP0_DEPC); | |
| 551 | + env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 552 | + if (env->CP0_Status & (1 << CP0St_BEV)) { | |
| 553 | + env->active_tc.PC = (int32_t)0xBFC00200; | |
| 554 | + } else { | |
| 555 | + env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); | |
| 571 | 556 | } |
| 557 | + env->active_tc.PC += offset; | |
| 558 | + env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC); | |
| 559 | + break; | |
| 560 | + default: | |
| 561 | + if (logfile) { | |
| 562 | + fprintf(logfile, "Invalid MIPS exception %d. Exiting\n", | |
| 563 | + env->exception_index); | |
| 564 | + } | |
| 565 | + printf("Invalid MIPS exception %d. Exiting\n", env->exception_index); | |
| 566 | + exit(1); | |
| 567 | + } | |
| 568 | + if (logfile && env->exception_index != EXCP_EXT_INTERRUPT) { | |
| 569 | + fprintf(logfile, "%s: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx " cause %d\n" | |
| 570 | + " S %08x C %08x A " TARGET_FMT_lx " D " TARGET_FMT_lx "\n", | |
| 571 | + __func__, env->active_tc.PC, env->CP0_EPC, cause, | |
| 572 | + env->CP0_Status, env->CP0_Cause, env->CP0_BadVAddr, | |
| 573 | + env->CP0_DEPC); | |
| 572 | 574 | } |
| 575 | +#endif | |
| 573 | 576 | env->exception_index = EXCP_NONE; |
| 574 | 577 | } |
| 575 | 578 | ... | ... |
target-mips/translate.c
| ... | ... | @@ -7859,13 +7859,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 7859 | 7859 | gen_helper_rdhwr_ccres(t0); |
| 7860 | 7860 | break; |
| 7861 | 7861 | case 29: |
| 7862 | - if (env->user_mode_only) { | |
| 7863 | - tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); | |
| 7864 | - break; | |
| 7865 | - } else { | |
| 7866 | - /* XXX: Some CPUs implement this in hardware. | |
| 7867 | - Not supported yet. */ | |
| 7868 | - } | |
| 7862 | +#if defined(CONFIG_USER_ONLY) | |
| 7863 | + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); | |
| 7864 | + break; | |
| 7865 | +#else | |
| 7866 | + /* XXX: Some CPUs implement this in hardware. | |
| 7867 | + Not supported yet. */ | |
| 7868 | +#endif | |
| 7869 | 7869 | default: /* Invalid */ |
| 7870 | 7870 | MIPS_INVAL("rdhwr"); |
| 7871 | 7871 | generate_exception(ctx, EXCP_RI); |
| ... | ... | @@ -7953,19 +7953,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 7953 | 7953 | case OPC_DMTC0: |
| 7954 | 7954 | #endif |
| 7955 | 7955 | #ifndef CONFIG_USER_ONLY |
| 7956 | - if (!env->user_mode_only) | |
| 7957 | - gen_cp0(env, ctx, op1, rt, rd); | |
| 7956 | + gen_cp0(env, ctx, op1, rt, rd); | |
| 7958 | 7957 | #endif /* !CONFIG_USER_ONLY */ |
| 7959 | 7958 | break; |
| 7960 | 7959 | case OPC_C0_FIRST ... OPC_C0_LAST: |
| 7961 | 7960 | #ifndef CONFIG_USER_ONLY |
| 7962 | - if (!env->user_mode_only) | |
| 7963 | - gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); | |
| 7961 | + gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); | |
| 7964 | 7962 | #endif /* !CONFIG_USER_ONLY */ |
| 7965 | 7963 | break; |
| 7966 | 7964 | case OPC_MFMC0: |
| 7967 | 7965 | #ifndef CONFIG_USER_ONLY |
| 7968 | - if (!env->user_mode_only) { | |
| 7966 | + { | |
| 7969 | 7967 | TCGv t0 = tcg_temp_local_new(); |
| 7970 | 7968 | |
| 7971 | 7969 | op2 = MASK_MFMC0(ctx->opcode); |
| ... | ... | @@ -8264,10 +8262,11 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 8264 | 8262 | /* Restore delay slot state from the tb context. */ |
| 8265 | 8263 | ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */ |
| 8266 | 8264 | restore_cpu_state(env, &ctx); |
| 8267 | - if (env->user_mode_only) | |
| 8265 | +#ifdef CONFIG_USER_ONLY | |
| 8268 | 8266 | ctx.mem_idx = MIPS_HFLAG_UM; |
| 8269 | - else | |
| 8267 | +#else | |
| 8270 | 8268 | ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU; |
| 8269 | +#endif | |
| 8271 | 8270 | num_insns = 0; |
| 8272 | 8271 | max_insns = tb->cflags & CF_COUNT_MASK; |
| 8273 | 8272 | if (max_insns == 0) |
| ... | ... | @@ -8583,40 +8582,37 @@ void cpu_reset (CPUMIPSState *env) |
| 8583 | 8582 | |
| 8584 | 8583 | /* Minimal init */ |
| 8585 | 8584 | #if defined(CONFIG_USER_ONLY) |
| 8586 | - env->user_mode_only = 1; | |
| 8587 | -#endif | |
| 8588 | - if (env->user_mode_only) { | |
| 8589 | - env->hflags = MIPS_HFLAG_UM; | |
| 8585 | + env->hflags = MIPS_HFLAG_UM; | |
| 8586 | +#else | |
| 8587 | + if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 8588 | + /* If the exception was raised from a delay slot, | |
| 8589 | + come back to the jump. */ | |
| 8590 | + env->CP0_ErrorEPC = env->active_tc.PC - 4; | |
| 8590 | 8591 | } else { |
| 8591 | - if (env->hflags & MIPS_HFLAG_BMASK) { | |
| 8592 | - /* If the exception was raised from a delay slot, | |
| 8593 | - come back to the jump. */ | |
| 8594 | - env->CP0_ErrorEPC = env->active_tc.PC - 4; | |
| 8595 | - } else { | |
| 8596 | - env->CP0_ErrorEPC = env->active_tc.PC; | |
| 8597 | - } | |
| 8598 | - env->active_tc.PC = (int32_t)0xBFC00000; | |
| 8599 | - env->CP0_Wired = 0; | |
| 8600 | - /* SMP not implemented */ | |
| 8601 | - env->CP0_EBase = 0x80000000; | |
| 8602 | - env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); | |
| 8603 | - /* vectored interrupts not implemented, timer on int 7, | |
| 8604 | - no performance counters. */ | |
| 8605 | - env->CP0_IntCtl = 0xe0000000; | |
| 8606 | - { | |
| 8607 | - int i; | |
| 8608 | - | |
| 8609 | - for (i = 0; i < 7; i++) { | |
| 8610 | - env->CP0_WatchLo[i] = 0; | |
| 8611 | - env->CP0_WatchHi[i] = 0x80000000; | |
| 8612 | - } | |
| 8613 | - env->CP0_WatchLo[7] = 0; | |
| 8614 | - env->CP0_WatchHi[7] = 0; | |
| 8592 | + env->CP0_ErrorEPC = env->active_tc.PC; | |
| 8593 | + } | |
| 8594 | + env->active_tc.PC = (int32_t)0xBFC00000; | |
| 8595 | + env->CP0_Wired = 0; | |
| 8596 | + /* SMP not implemented */ | |
| 8597 | + env->CP0_EBase = 0x80000000; | |
| 8598 | + env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); | |
| 8599 | + /* vectored interrupts not implemented, timer on int 7, | |
| 8600 | + no performance counters. */ | |
| 8601 | + env->CP0_IntCtl = 0xe0000000; | |
| 8602 | + { | |
| 8603 | + int i; | |
| 8604 | + | |
| 8605 | + for (i = 0; i < 7; i++) { | |
| 8606 | + env->CP0_WatchLo[i] = 0; | |
| 8607 | + env->CP0_WatchHi[i] = 0x80000000; | |
| 8615 | 8608 | } |
| 8616 | - /* Count register increments in debug mode, EJTAG version 1 */ | |
| 8617 | - env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); | |
| 8618 | - env->hflags = MIPS_HFLAG_CP0; | |
| 8609 | + env->CP0_WatchLo[7] = 0; | |
| 8610 | + env->CP0_WatchHi[7] = 0; | |
| 8619 | 8611 | } |
| 8612 | + /* Count register increments in debug mode, EJTAG version 1 */ | |
| 8613 | + env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); | |
| 8614 | + env->hflags = MIPS_HFLAG_CP0; | |
| 8615 | +#endif | |
| 8620 | 8616 | env->exception_index = EXCP_NONE; |
| 8621 | 8617 | cpu_mips_register(env, env->cpu_model); |
| 8622 | 8618 | } | ... | ... |
target-mips/translate_init.c
| ... | ... | @@ -495,14 +495,14 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def) |
| 495 | 495 | env->fpus[i].fcr0 = def->CP1_fcr0; |
| 496 | 496 | |
| 497 | 497 | memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); |
| 498 | - if (env->user_mode_only) { | |
| 499 | - if (env->CP0_Config1 & (1 << CP0C1_FP)) | |
| 500 | - env->hflags |= MIPS_HFLAG_FPU; | |
| 498 | +#if defined(CONFIG_USER_ONLY) | |
| 499 | + if (env->CP0_Config1 & (1 << CP0C1_FP)) | |
| 500 | + env->hflags |= MIPS_HFLAG_FPU; | |
| 501 | 501 | #ifdef TARGET_MIPS64 |
| 502 | - if (env->active_fpu.fcr0 & (1 << FCR0_F64)) | |
| 503 | - env->hflags |= MIPS_HFLAG_F64; | |
| 502 | + if (env->active_fpu.fcr0 & (1 << FCR0_F64)) | |
| 503 | + env->hflags |= MIPS_HFLAG_F64; | |
| 504 | +#endif | |
| 504 | 505 | #endif |
| 505 | - } | |
| 506 | 506 | } |
| 507 | 507 | |
| 508 | 508 | static void mvp_init (CPUMIPSState *env, const mips_def_t *def) |
| ... | ... | @@ -520,9 +520,10 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t *def) |
| 520 | 520 | // (0x04 << CP0MVPC0_PTC); |
| 521 | 521 | (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | |
| 522 | 522 | (0x04 << CP0MVPC0_PTC); |
| 523 | +#if !defined(CONFIG_USER_ONLY) | |
| 523 | 524 | /* Usermode has no TLB support */ |
| 524 | - if (!env->user_mode_only) | |
| 525 | - env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); | |
| 525 | + env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE); | |
| 526 | +#endif | |
| 526 | 527 | |
| 527 | 528 | /* Allocatable CP1 have media extensions, allocatable CP1 have FP support, |
| 528 | 529 | no UDI implemented, no CP2 implemented, 1 CP1 implemented. */ |
| ... | ... | @@ -572,8 +573,7 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def) |
| 572 | 573 | env->insn_flags = def->insn_flags; |
| 573 | 574 | |
| 574 | 575 | #ifndef CONFIG_USER_ONLY |
| 575 | - if (!env->user_mode_only) | |
| 576 | - mmu_init(env, def); | |
| 576 | + mmu_init(env, def); | |
| 577 | 577 | #endif |
| 578 | 578 | fpu_init(env, def); |
| 579 | 579 | mvp_init(env, def); | ... | ... |