Revision 100ce988

b/target-mips/helper.c
76 76
        target_ulong mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
77 77
        target_ulong tag = address & ~mask;
78 78
        target_ulong VPN = tlb->VPN & ~mask;
79
#ifdef TARGET_MIPS64
80
        tag &= 0xC00000FFFFFFFFFFULL;
81
#endif
79 82

  
80 83
        /* Check ASID, virtual page number & size */
81 84
        if ((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag) {
......
295 298
        }
296 299
        /* Raise exception */
297 300
        env->CP0_BadVAddr = address;
298
        env->CP0_Context = (env->CP0_Context & 0xff800000) |
301
        env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
299 302
	                   ((address >> 9) &   0x007ffff0);
300 303
        env->CP0_EntryHi =
301 304
            (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
305
#ifdef TARGET_MIPS64
306
        env->CP0_EntryHi &= 0xc00000ffffffffffULL;
307
        env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) |
308
                            ((address >> 31) & 0x0000000180000000ULL) |
309
                            ((address >> 9) & 0x000000007ffffff0ULL);
310
#endif
302 311
        env->exception_index = exception;
303 312
        env->error_code = error_code;
304 313
        ret = 1;
......
411 420
        goto set_EPC;
412 421
    case EXCP_TLBL:
413 422
        cause = 2;
414
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
415
            offset = 0x000;
423
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
424
#ifdef TARGET_MIPS64
425
            int R = env->CP0_BadVAddr >> 62;
426
            int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
427
            int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
428
            int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
429

  
430
            if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
431
                offset = 0x080;
432
            else
433
#endif
434
                offset = 0x000;
435
        }
416 436
        goto set_EPC;
417 437
    case EXCP_IBE:
418 438
        cause = 6;
......
448 468
        goto set_EPC;
449 469
    case EXCP_TLBS:
450 470
        cause = 3;
451
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
452
            offset = 0x000;
471
        if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) {
472
#ifdef TARGET_MIPS64
473
            int R = env->CP0_BadVAddr >> 62;
474
            int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
475
            int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
476
            int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
477

  
478
            if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX))
479
                offset = 0x080;
480
            else
481
#endif
482
                offset = 0x000;
483
        }
453 484
    set_EPC:
454 485
        if (!(env->CP0_Status & (1 << CP0St_EXL))) {
455 486
            if (env->hflags & MIPS_HFLAG_BMASK) {
......
520 551
    mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
521 552
    if (tlb->V0) {
522 553
        addr = tlb->VPN & ~mask;
554
#ifdef TARGET_MIPS64
555
        if (addr >= 0xC00000FF80000000ULL) {
556
            addr |= 0x3FFFFF0000000000ULL;
557
        }
558
#endif
523 559
        end = addr | (mask >> 1);
524 560
        while (addr < end) {
525 561
            tlb_flush_page (env, addr);
......
528 564
    }
529 565
    if (tlb->V1) {
530 566
        addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
567
#ifdef TARGET_MIPS64
568
        if (addr >= 0xC00000FF80000000ULL) {
569
            addr |= 0x3FFFFF0000000000ULL;
570
        }
571
#endif
531 572
        end = addr | mask;
532 573
        while (addr < end) {
533 574
            tlb_flush_page (env, addr);
b/target-mips/op.c
1317 1317
    target_ulong old, val;
1318 1318

  
1319 1319
    /* 1k pages not implemented */
1320
    /* Ignore MIPS64 TLB for now */
1321
    val = (target_ulong)(int32_t)T0 & ~(target_ulong)0x1F00;
1320
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1321
#ifdef TARGET_MIPS64
1322
    val = T0 & 0xC00000FFFFFFFFFFULL;
1323
#endif
1322 1324
    old = env->CP0_EntryHi;
1323 1325
    env->CP0_EntryHi = val;
1324 1326
    /* If the ASID changes, flush qemu's TLB.  */
b/target-mips/op_helper.c
391 391
    /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
392 392
    tlb = &env->mmu.r4k.tlb[idx];
393 393
    tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
394
#ifdef TARGET_MIPS64
395
    tlb->VPN &= 0xC00000FFFFFFFFFFULL;
396
#endif
394 397
    tlb->ASID = env->CP0_EntryHi & 0xFF;
395 398
    tlb->PageMask = env->CP0_PageMask;
396 399
    tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;

Also available in: Unified diff