Commit a8dea12f453851d68c968d23faff2f1b9205d811
1 parent
1d0a48fb
Merge PowerPC 405 MMU model.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2554 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
243 additions
and
50 deletions
target-ppc/helper.c
@@ -549,8 +549,6 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | @@ -549,8 +549,6 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | ||
549 | if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) { | 549 | if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) { |
550 | /* Software TLB search */ | 550 | /* Software TLB search */ |
551 | ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); | 551 | ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); |
552 | - } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { | ||
553 | - /* XXX: TODO */ | ||
554 | } else { | 552 | } else { |
555 | #if defined (DEBUG_MMU) | 553 | #if defined (DEBUG_MMU) |
556 | if (loglevel > 0) { | 554 | if (loglevel > 0) { |
@@ -632,6 +630,115 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | @@ -632,6 +630,115 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx, | ||
632 | return ret; | 630 | return ret; |
633 | } | 631 | } |
634 | 632 | ||
633 | +int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
634 | + uint32_t address, int rw, int access_type) | ||
635 | +{ | ||
636 | + ppcemb_tlb_t *tlb; | ||
637 | + target_phys_addr_t raddr; | ||
638 | + target_ulong mask; | ||
639 | + int i, ret, zsel, zpr; | ||
640 | + | ||
641 | + ret = -6; | ||
642 | + for (i = 0; i < env->nb_tlb; i++) { | ||
643 | + tlb = &env->tlb[i].tlbe; | ||
644 | + /* Check valid flag */ | ||
645 | + if (!(tlb->prot & PAGE_VALID)) { | ||
646 | + if (loglevel) | ||
647 | + fprintf(logfile, "%s: TLB %d not valid\n", __func__, i); | ||
648 | + continue; | ||
649 | + } | ||
650 | + mask = ~(tlb->size - 1); | ||
651 | + if (loglevel) { | ||
652 | + fprintf(logfile, "%s: TLB %d address %08x PID %04x <=> " | ||
653 | + "%08x %08x %04x\n", | ||
654 | + __func__, i, address, env->spr[SPR_40x_PID], | ||
655 | + tlb->EPN, mask, tlb->PID); | ||
656 | + } | ||
657 | + /* Check PID */ | ||
658 | + if (tlb->PID != 0 && tlb->PID != env->spr[SPR_40x_PID]) | ||
659 | + continue; | ||
660 | + /* Check effective address */ | ||
661 | + if ((address & mask) != tlb->EPN) | ||
662 | + continue; | ||
663 | + raddr = (tlb->RPN & mask) | (address & ~mask); | ||
664 | + zsel = (tlb->attr >> 4) & 0xF; | ||
665 | + zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3; | ||
666 | + if (loglevel) { | ||
667 | + fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n", | ||
668 | + __func__, i, zsel, zpr, rw, tlb->attr); | ||
669 | + } | ||
670 | + if (access_type == ACCESS_CODE) { | ||
671 | + /* Check execute enable bit */ | ||
672 | + switch (zpr) { | ||
673 | + case 0x0: | ||
674 | + if (msr_pr) { | ||
675 | + ret = -3; | ||
676 | + ctx->prot = 0; | ||
677 | + break; | ||
678 | + } | ||
679 | + /* No break here */ | ||
680 | + case 0x1: | ||
681 | + case 0x2: | ||
682 | + /* Check from TLB entry */ | ||
683 | + if (!(tlb->prot & PAGE_EXEC)) { | ||
684 | + ret = -3; | ||
685 | + } else { | ||
686 | + if (tlb->prot & PAGE_WRITE) | ||
687 | + ctx->prot = PAGE_READ | PAGE_WRITE; | ||
688 | + else | ||
689 | + ctx->prot = PAGE_READ; | ||
690 | + ret = 0; | ||
691 | + } | ||
692 | + break; | ||
693 | + case 0x3: | ||
694 | + /* All accesses granted */ | ||
695 | + ret = 0; | ||
696 | + ctx->prot = PAGE_READ | PAGE_WRITE; | ||
697 | + break; | ||
698 | + } | ||
699 | + } else { | ||
700 | + switch (zpr) { | ||
701 | + case 0x0: | ||
702 | + if (msr_pr) { | ||
703 | + ret = -2; | ||
704 | + ctx->prot = 0; | ||
705 | + break; | ||
706 | + } | ||
707 | + /* No break here */ | ||
708 | + case 0x1: | ||
709 | + case 0x2: | ||
710 | + /* Check from TLB entry */ | ||
711 | + /* Check write protection bit */ | ||
712 | + if (rw && !(tlb->prot & PAGE_WRITE)) { | ||
713 | + ret = -2; | ||
714 | + } else { | ||
715 | + ret = 2; | ||
716 | + if (tlb->prot & PAGE_WRITE) | ||
717 | + ctx->prot = PAGE_READ | PAGE_WRITE; | ||
718 | + else | ||
719 | + ctx->prot = PAGE_READ; | ||
720 | + } | ||
721 | + break; | ||
722 | + case 0x3: | ||
723 | + /* All accesses granted */ | ||
724 | + ret = 2; | ||
725 | + ctx->prot = PAGE_READ | PAGE_WRITE; | ||
726 | + break; | ||
727 | + } | ||
728 | + } | ||
729 | + if (ret >= 0) { | ||
730 | + ctx->raddr = raddr; | ||
731 | + if (loglevel) { | ||
732 | + fprintf(logfile, "%s: access granted " ADDRX " => " REGX | ||
733 | + " %d\n", __func__, address, ctx->raddr, ctx->prot); | ||
734 | + } | ||
735 | + return i; | ||
736 | + } | ||
737 | + } | ||
738 | + | ||
739 | + return ret; | ||
740 | +} | ||
741 | + | ||
635 | static int check_physical (CPUState *env, mmu_ctx_t *ctx, | 742 | static int check_physical (CPUState *env, mmu_ctx_t *ctx, |
636 | target_ulong eaddr, int rw) | 743 | target_ulong eaddr, int rw) |
637 | { | 744 | { |
@@ -682,13 +789,26 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | @@ -682,13 +789,26 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | ||
682 | /* No address translation */ | 789 | /* No address translation */ |
683 | ret = check_physical(env, ctx, eaddr, rw); | 790 | ret = check_physical(env, ctx, eaddr, rw); |
684 | } else { | 791 | } else { |
685 | - /* Try to find a BAT */ | ||
686 | - ret = -1; | ||
687 | - if (check_BATs) | ||
688 | - ret = get_bat(env, ctx, eaddr, rw, access_type); | ||
689 | - if (ret < 0) { | ||
690 | - /* We didn't match any BAT entry */ | ||
691 | - ret = get_segment(env, ctx, eaddr, rw, access_type); | 792 | + switch (PPC_MMU(env)) { |
793 | + case PPC_FLAGS_MMU_32B: | ||
794 | + case PPC_FLAGS_MMU_SOFT_6xx: | ||
795 | + /* Try to find a BAT */ | ||
796 | + ret = -1; | ||
797 | + if (check_BATs) | ||
798 | + ret = get_bat(env, ctx, eaddr, rw, access_type); | ||
799 | + if (ret < 0) { | ||
800 | + /* We didn't match any BAT entry */ | ||
801 | + ret = get_segment(env, ctx, eaddr, rw, access_type); | ||
802 | + } | ||
803 | + break; | ||
804 | + case PPC_FLAGS_MMU_SOFT_4xx: | ||
805 | + ret = mmu4xx_get_physical_address(env, ctx, eaddr, | ||
806 | + rw, access_type); | ||
807 | + break; | ||
808 | + default: | ||
809 | + /* XXX: TODO */ | ||
810 | + cpu_abort(env, "MMU model not implemented\n"); | ||
811 | + return -1; | ||
692 | } | 812 | } |
693 | } | 813 | } |
694 | #if 0 | 814 | #if 0 |
@@ -753,7 +873,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | @@ -753,7 +873,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | ||
753 | error_code = 1 << 18; | 873 | error_code = 1 << 18; |
754 | goto tlb_miss; | 874 | goto tlb_miss; |
755 | } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { | 875 | } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { |
756 | - /* XXX: TODO */ | 876 | + exception = EXCP_40x_ITLBMISS; |
877 | + error_code = 0; | ||
878 | + env->spr[SPR_40x_DEAR] = address; | ||
879 | + env->spr[SPR_40x_ESR] = 0x00000000; | ||
757 | } else { | 880 | } else { |
758 | error_code = 0x40000000; | 881 | error_code = 0x40000000; |
759 | } | 882 | } |
@@ -799,7 +922,13 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | @@ -799,7 +922,13 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | ||
799 | /* Do not alter DAR nor DSISR */ | 922 | /* Do not alter DAR nor DSISR */ |
800 | goto out; | 923 | goto out; |
801 | } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { | 924 | } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { |
802 | - /* XXX: TODO */ | 925 | + exception = EXCP_40x_DTLBMISS; |
926 | + error_code = 0; | ||
927 | + env->spr[SPR_40x_DEAR] = address; | ||
928 | + if (rw) | ||
929 | + env->spr[SPR_40x_ESR] = 0x00800000; | ||
930 | + else | ||
931 | + env->spr[SPR_40x_ESR] = 0x00000000; | ||
803 | } else { | 932 | } else { |
804 | error_code = 0x40000000; | 933 | error_code = 0x40000000; |
805 | } | 934 | } |
@@ -1518,9 +1647,7 @@ void do_interrupt (CPUState *env) | @@ -1518,9 +1647,7 @@ void do_interrupt (CPUState *env) | ||
1518 | switch (PPC_EXCP(env)) { | 1647 | switch (PPC_EXCP(env)) { |
1519 | case PPC_FLAGS_EXCP_40x: | 1648 | case PPC_FLAGS_EXCP_40x: |
1520 | /* DTLBMISS on 4xx */ | 1649 | /* DTLBMISS on 4xx */ |
1521 | - /* XXX: TODO */ | ||
1522 | - cpu_abort(env, | ||
1523 | - "40x DTLBMISS exception is not implemented yet !\n"); | 1650 | + msr &= ~0xFFFF0000; |
1524 | goto store_next; | 1651 | goto store_next; |
1525 | case PPC_FLAGS_EXCP_602: | 1652 | case PPC_FLAGS_EXCP_602: |
1526 | case PPC_FLAGS_EXCP_603: | 1653 | case PPC_FLAGS_EXCP_603: |
@@ -1538,9 +1665,7 @@ void do_interrupt (CPUState *env) | @@ -1538,9 +1665,7 @@ void do_interrupt (CPUState *env) | ||
1538 | switch (PPC_EXCP(env)) { | 1665 | switch (PPC_EXCP(env)) { |
1539 | case PPC_FLAGS_EXCP_40x: | 1666 | case PPC_FLAGS_EXCP_40x: |
1540 | /* ITLBMISS on 4xx */ | 1667 | /* ITLBMISS on 4xx */ |
1541 | - /* XXX: TODO */ | ||
1542 | - cpu_abort(env, | ||
1543 | - "40x ITLBMISS exception is not implemented yet !\n"); | 1668 | + msr &= ~0xFFFF0000; |
1544 | goto store_next; | 1669 | goto store_next; |
1545 | case PPC_FLAGS_EXCP_602: | 1670 | case PPC_FLAGS_EXCP_602: |
1546 | case PPC_FLAGS_EXCP_603: | 1671 | case PPC_FLAGS_EXCP_603: |
target-ppc/op_helper.c
@@ -2365,65 +2365,139 @@ void do_load_6xx_tlb (int is_code) | @@ -2365,65 +2365,139 @@ void do_load_6xx_tlb (int is_code) | ||
2365 | way, is_code, CMP, RPN); | 2365 | way, is_code, CMP, RPN); |
2366 | } | 2366 | } |
2367 | 2367 | ||
2368 | +static target_ulong booke_tlb_to_page_size (int size) | ||
2369 | +{ | ||
2370 | + return 1024 << (2 * size); | ||
2371 | +} | ||
2372 | + | ||
2373 | +static int booke_page_size_to_tlb (target_ulong page_size) | ||
2374 | +{ | ||
2375 | + int size; | ||
2376 | + | ||
2377 | + switch (page_size) { | ||
2378 | + case 0x00000400UL: | ||
2379 | + size = 0x0; | ||
2380 | + break; | ||
2381 | + case 0x00001000UL: | ||
2382 | + size = 0x1; | ||
2383 | + break; | ||
2384 | + case 0x00004000UL: | ||
2385 | + size = 0x2; | ||
2386 | + break; | ||
2387 | + case 0x00010000UL: | ||
2388 | + size = 0x3; | ||
2389 | + break; | ||
2390 | + case 0x00040000UL: | ||
2391 | + size = 0x4; | ||
2392 | + break; | ||
2393 | + case 0x00100000UL: | ||
2394 | + size = 0x5; | ||
2395 | + break; | ||
2396 | + case 0x00400000UL: | ||
2397 | + size = 0x6; | ||
2398 | + break; | ||
2399 | + case 0x01000000UL: | ||
2400 | + size = 0x7; | ||
2401 | + break; | ||
2402 | + case 0x04000000UL: | ||
2403 | + size = 0x8; | ||
2404 | + break; | ||
2405 | + case 0x10000000UL: | ||
2406 | + size = 0x9; | ||
2407 | + break; | ||
2408 | + case 0x40000000UL: | ||
2409 | + size = 0xA; | ||
2410 | + break; | ||
2411 | +#if defined (TARGET_PPC64) | ||
2412 | + case 0x000100000000ULL: | ||
2413 | + size = 0xB; | ||
2414 | + break; | ||
2415 | + case 0x000400000000ULL: | ||
2416 | + size = 0xC; | ||
2417 | + break; | ||
2418 | + case 0x001000000000ULL: | ||
2419 | + size = 0xD; | ||
2420 | + break; | ||
2421 | + case 0x004000000000ULL: | ||
2422 | + size = 0xE; | ||
2423 | + break; | ||
2424 | + case 0x010000000000ULL: | ||
2425 | + size = 0xF; | ||
2426 | + break; | ||
2427 | +#endif | ||
2428 | + default: | ||
2429 | + size = -1; | ||
2430 | + break; | ||
2431 | + } | ||
2432 | + | ||
2433 | + return size; | ||
2434 | +} | ||
2435 | + | ||
2368 | /* Helpers for 4xx TLB management */ | 2436 | /* Helpers for 4xx TLB management */ |
2369 | void do_4xx_tlbia (void) | 2437 | void do_4xx_tlbia (void) |
2370 | { | 2438 | { |
2371 | -#if 0 | ||
2372 | - ppc_tlb_t *tlb; | ||
2373 | - target_ulong page, end; | 2439 | + ppcemb_tlb_t *tlb; |
2374 | int i; | 2440 | int i; |
2375 | 2441 | ||
2376 | for (i = 0; i < 64; i++) { | 2442 | for (i = 0; i < 64; i++) { |
2377 | - tlb = &env->tlb[i]; | 2443 | + tlb = &env->tlb[i].tlbe; |
2378 | if (tlb->prot & PAGE_VALID) { | 2444 | if (tlb->prot & PAGE_VALID) { |
2445 | +#if 0 | ||
2379 | end = tlb->EPN + tlb->size; | 2446 | end = tlb->EPN + tlb->size; |
2380 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) | 2447 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) |
2381 | tlb_flush_page(env, page); | 2448 | tlb_flush_page(env, page); |
2449 | +#endif | ||
2382 | tlb->prot &= ~PAGE_VALID; | 2450 | tlb->prot &= ~PAGE_VALID; |
2383 | } | 2451 | } |
2384 | } | 2452 | } |
2385 | -#endif | 2453 | + tlb_flush(env, 1); |
2386 | } | 2454 | } |
2387 | 2455 | ||
2388 | void do_4xx_tlbre_lo (void) | 2456 | void do_4xx_tlbre_lo (void) |
2389 | { | 2457 | { |
2390 | -#if 0 | ||
2391 | - ppc_tlb_t *tlb; | 2458 | + ppcemb_tlb_t *tlb; |
2459 | + int size; | ||
2392 | 2460 | ||
2393 | T0 &= 0x3F; | 2461 | T0 &= 0x3F; |
2394 | - tlb = &env->tlb[T0]; | ||
2395 | - T0 = tlb->stor[0]; | ||
2396 | - env->spr[SPR_40x_PID] = tlb->pid; | ||
2397 | -#endif | 2462 | + tlb = &env->tlb[T0].tlbe; |
2463 | + T0 = tlb->EPN; | ||
2464 | + if (tlb->prot & PAGE_VALID) | ||
2465 | + T0 |= 0x400; | ||
2466 | + size = booke_page_size_to_tlb(tlb->size); | ||
2467 | + if (size < 0 || size > 0x7) | ||
2468 | + size = 1; | ||
2469 | + T0 |= size << 7; | ||
2470 | + env->spr[SPR_40x_PID] = tlb->PID; | ||
2398 | } | 2471 | } |
2399 | 2472 | ||
2400 | void do_4xx_tlbre_hi (void) | 2473 | void do_4xx_tlbre_hi (void) |
2401 | { | 2474 | { |
2402 | -#if 0 | ||
2403 | - ppc_tlb_t *tlb; | 2475 | + ppcemb_tlb_t *tlb; |
2404 | 2476 | ||
2405 | T0 &= 0x3F; | 2477 | T0 &= 0x3F; |
2406 | - tlb = &env->tlb[T0]; | ||
2407 | - T0 = tlb->stor[1]; | ||
2408 | -#endif | 2478 | + tlb = &env->tlb[T0].tlbe; |
2479 | + T0 = tlb->RPN; | ||
2480 | + if (tlb->prot & PAGE_EXEC) | ||
2481 | + T0 |= 0x200; | ||
2482 | + if (tlb->prot & PAGE_WRITE) | ||
2483 | + T0 |= 0x100; | ||
2409 | } | 2484 | } |
2410 | 2485 | ||
2411 | static int tlb_4xx_search (target_ulong virtual) | 2486 | static int tlb_4xx_search (target_ulong virtual) |
2412 | { | 2487 | { |
2413 | -#if 0 | ||
2414 | - ppc_tlb_t *tlb; | 2488 | + ppcemb_tlb_t *tlb; |
2415 | target_ulong base, mask; | 2489 | target_ulong base, mask; |
2416 | int i, ret; | 2490 | int i, ret; |
2417 | 2491 | ||
2418 | /* Default return value is no match */ | 2492 | /* Default return value is no match */ |
2419 | ret = -1; | 2493 | ret = -1; |
2420 | for (i = 0; i < 64; i++) { | 2494 | for (i = 0; i < 64; i++) { |
2421 | - tlb = &env->tlb[i]; | 2495 | + tlb = &env->tlb[i].tlbe; |
2422 | /* Check TLB validity */ | 2496 | /* Check TLB validity */ |
2423 | if (!(tlb->prot & PAGE_VALID)) | 2497 | if (!(tlb->prot & PAGE_VALID)) |
2424 | continue; | 2498 | continue; |
2425 | /* Check TLB PID vs current PID */ | 2499 | /* Check TLB PID vs current PID */ |
2426 | - if (tlb->pid != 0 && tlb->pid != env->spr[SPR_40x_PID]) | 2500 | + if (tlb->PID != 0 && tlb->PID != env->spr[SPR_40x_PID]) |
2427 | continue; | 2501 | continue; |
2428 | /* Check TLB address vs virtual address */ | 2502 | /* Check TLB address vs virtual address */ |
2429 | base = tlb->EPN; | 2503 | base = tlb->EPN; |
@@ -2435,9 +2509,6 @@ static int tlb_4xx_search (target_ulong virtual) | @@ -2435,9 +2509,6 @@ static int tlb_4xx_search (target_ulong virtual) | ||
2435 | } | 2509 | } |
2436 | 2510 | ||
2437 | return ret; | 2511 | return ret; |
2438 | -#else | ||
2439 | - return -1; | ||
2440 | -#endif | ||
2441 | } | 2512 | } |
2442 | 2513 | ||
2443 | void do_4xx_tlbsx (void) | 2514 | void do_4xx_tlbsx (void) |
@@ -2457,47 +2528,44 @@ void do_4xx_tlbsx_ (void) | @@ -2457,47 +2528,44 @@ void do_4xx_tlbsx_ (void) | ||
2457 | 2528 | ||
2458 | void do_4xx_tlbwe_lo (void) | 2529 | void do_4xx_tlbwe_lo (void) |
2459 | { | 2530 | { |
2460 | -#if 0 | ||
2461 | - ppc_tlb_t *tlb; | 2531 | + ppcemb_tlb_t *tlb; |
2462 | target_ulong page, end; | 2532 | target_ulong page, end; |
2463 | 2533 | ||
2464 | T0 &= 0x3F; | 2534 | T0 &= 0x3F; |
2465 | - tlb = &env->tlb[T0]; | 2535 | + tlb = &env->tlb[T0].tlbe; |
2466 | /* Invalidate previous TLB (if it's valid) */ | 2536 | /* Invalidate previous TLB (if it's valid) */ |
2467 | if (tlb->prot & PAGE_VALID) { | 2537 | if (tlb->prot & PAGE_VALID) { |
2468 | end = tlb->EPN + tlb->size; | 2538 | end = tlb->EPN + tlb->size; |
2469 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) | 2539 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) |
2470 | tlb_flush_page(env, page); | 2540 | tlb_flush_page(env, page); |
2471 | } | 2541 | } |
2472 | - tlb->size = 1024 << (2 * ((T1 >> 7) & 0x7)); | 2542 | + tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7); |
2473 | tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1); | 2543 | tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1); |
2474 | if (T1 & 0x400) | 2544 | if (T1 & 0x400) |
2475 | tlb->prot |= PAGE_VALID; | 2545 | tlb->prot |= PAGE_VALID; |
2476 | else | 2546 | else |
2477 | tlb->prot &= ~PAGE_VALID; | 2547 | tlb->prot &= ~PAGE_VALID; |
2478 | - tlb->pid = env->spr[SPR_BOOKE_PID]; /* PID */ | 2548 | + tlb->PID = env->spr[SPR_BOOKE_PID]; /* PID */ |
2549 | + tlb->attr = T1 & 0xFF; | ||
2479 | /* Invalidate new TLB (if valid) */ | 2550 | /* Invalidate new TLB (if valid) */ |
2480 | if (tlb->prot & PAGE_VALID) { | 2551 | if (tlb->prot & PAGE_VALID) { |
2481 | end = tlb->EPN + tlb->size; | 2552 | end = tlb->EPN + tlb->size; |
2482 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) | 2553 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) |
2483 | tlb_flush_page(env, page); | 2554 | tlb_flush_page(env, page); |
2484 | } | 2555 | } |
2485 | -#endif | ||
2486 | } | 2556 | } |
2487 | 2557 | ||
2488 | void do_4xx_tlbwe_hi (void) | 2558 | void do_4xx_tlbwe_hi (void) |
2489 | { | 2559 | { |
2490 | -#if 0 | ||
2491 | - ppc_tlb_t *tlb; | 2560 | + ppcemb_tlb_t *tlb; |
2492 | 2561 | ||
2493 | T0 &= 0x3F; | 2562 | T0 &= 0x3F; |
2494 | - tlb = &env->tlb[T0]; | 2563 | + tlb = &env->tlb[T0].tlbe; |
2495 | tlb->RPN = T1 & 0xFFFFFC00; | 2564 | tlb->RPN = T1 & 0xFFFFFC00; |
2496 | tlb->prot = PAGE_READ; | 2565 | tlb->prot = PAGE_READ; |
2497 | if (T1 & 0x200) | 2566 | if (T1 & 0x200) |
2498 | tlb->prot |= PAGE_EXEC; | 2567 | tlb->prot |= PAGE_EXEC; |
2499 | if (T1 & 0x100) | 2568 | if (T1 & 0x100) |
2500 | tlb->prot |= PAGE_WRITE; | 2569 | tlb->prot |= PAGE_WRITE; |
2501 | -#endif | ||
2502 | } | 2570 | } |
2503 | #endif /* !CONFIG_USER_ONLY */ | 2571 | #endif /* !CONFIG_USER_ONLY */ |