Revision 932e71cd

b/target-mips/helper.c
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 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 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 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 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

  
b/target-mips/translate.c
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 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 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 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
}
b/target-mips/translate_init.c
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 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 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);

Also available in: Unified diff