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); | ... | ... |