Commit c55e9aefa7c151176e2e88c0f79044580930a970
1 parent
0a032cbe
PowerPC 4xx software driven TLB fixes + debug traces.
Add code provision for more MMU models support. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2683 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
163 additions
and
39 deletions
target-ppc/cpu.h
| @@ -581,12 +581,12 @@ struct ppc6xx_tlb_t { | @@ -581,12 +581,12 @@ struct ppc6xx_tlb_t { | ||
| 581 | 581 | ||
| 582 | typedef struct ppcemb_tlb_t ppcemb_tlb_t; | 582 | typedef struct ppcemb_tlb_t ppcemb_tlb_t; |
| 583 | struct ppcemb_tlb_t { | 583 | struct ppcemb_tlb_t { |
| 584 | - target_ulong RPN; | 584 | + target_phys_addr_t RPN; |
| 585 | target_ulong EPN; | 585 | target_ulong EPN; |
| 586 | target_ulong PID; | 586 | target_ulong PID; |
| 587 | - int size; | ||
| 588 | - int prot; | ||
| 589 | - int attr; /* Storage attributes */ | 587 | + target_ulong size; |
| 588 | + uint32_t prot; | ||
| 589 | + uint32_t attr; /* Storage attributes */ | ||
| 590 | }; | 590 | }; |
| 591 | 591 | ||
| 592 | union ppc_tlb_t { | 592 | union ppc_tlb_t { |
| @@ -765,10 +765,6 @@ struct CPUPPCState { | @@ -765,10 +765,6 @@ struct CPUPPCState { | ||
| 765 | int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */ | 765 | int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */ |
| 766 | int nb_pids; /* Number of available PID registers */ | 766 | int nb_pids; /* Number of available PID registers */ |
| 767 | ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ | 767 | ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */ |
| 768 | - /* Callbacks for specific checks on some implementations */ | ||
| 769 | - int (*tlb_check_more)(CPUPPCState *env, ppc_tlb_t *tlb, int *prot, | ||
| 770 | - target_ulong vaddr, int rw, int acc_type, | ||
| 771 | - int is_user); | ||
| 772 | /* 403 dedicated access protection registers */ | 768 | /* 403 dedicated access protection registers */ |
| 773 | target_ulong pb[4]; | 769 | target_ulong pb[4]; |
| 774 | 770 |
target-ppc/helper.c
| @@ -657,7 +657,8 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | @@ -657,7 +657,8 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
| 657 | target_ulong mask; | 657 | target_ulong mask; |
| 658 | int i, ret, zsel, zpr; | 658 | int i, ret, zsel, zpr; |
| 659 | 659 | ||
| 660 | - ret = -6; | 660 | + ret = -1; |
| 661 | + raddr = -1; | ||
| 661 | for (i = 0; i < env->nb_tlb; i++) { | 662 | for (i = 0; i < env->nb_tlb; i++) { |
| 662 | tlb = &env->tlb[i].tlbe; | 663 | tlb = &env->tlb[i].tlbe; |
| 663 | /* Check valid flag */ | 664 | /* Check valid flag */ |
| @@ -691,8 +692,8 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | @@ -691,8 +692,8 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
| 691 | switch (zpr) { | 692 | switch (zpr) { |
| 692 | case 0x0: | 693 | case 0x0: |
| 693 | if (msr_pr) { | 694 | if (msr_pr) { |
| 694 | - ret = -3; | ||
| 695 | ctx->prot = 0; | 695 | ctx->prot = 0; |
| 696 | + ret = -3; | ||
| 696 | break; | 697 | break; |
| 697 | } | 698 | } |
| 698 | /* No break here */ | 699 | /* No break here */ |
| @@ -702,25 +703,26 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | @@ -702,25 +703,26 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
| 702 | if (!(tlb->prot & PAGE_EXEC)) { | 703 | if (!(tlb->prot & PAGE_EXEC)) { |
| 703 | ret = -3; | 704 | ret = -3; |
| 704 | } else { | 705 | } else { |
| 705 | - if (tlb->prot & PAGE_WRITE) | 706 | + if (tlb->prot & PAGE_WRITE) { |
| 706 | ctx->prot = PAGE_READ | PAGE_WRITE; | 707 | ctx->prot = PAGE_READ | PAGE_WRITE; |
| 707 | - else | 708 | + } else { |
| 708 | ctx->prot = PAGE_READ; | 709 | ctx->prot = PAGE_READ; |
| 710 | + } | ||
| 709 | ret = 0; | 711 | ret = 0; |
| 710 | } | 712 | } |
| 711 | break; | 713 | break; |
| 712 | case 0x3: | 714 | case 0x3: |
| 713 | /* All accesses granted */ | 715 | /* All accesses granted */ |
| 714 | - ret = 0; | ||
| 715 | ctx->prot = PAGE_READ | PAGE_WRITE; | 716 | ctx->prot = PAGE_READ | PAGE_WRITE; |
| 717 | + ret = 0; | ||
| 716 | break; | 718 | break; |
| 717 | } | 719 | } |
| 718 | } else { | 720 | } else { |
| 719 | switch (zpr) { | 721 | switch (zpr) { |
| 720 | case 0x0: | 722 | case 0x0: |
| 721 | if (msr_pr) { | 723 | if (msr_pr) { |
| 722 | - ret = -2; | ||
| 723 | ctx->prot = 0; | 724 | ctx->prot = 0; |
| 725 | + ret = -2; | ||
| 724 | break; | 726 | break; |
| 725 | } | 727 | } |
| 726 | /* No break here */ | 728 | /* No break here */ |
| @@ -728,20 +730,21 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | @@ -728,20 +730,21 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
| 728 | case 0x2: | 730 | case 0x2: |
| 729 | /* Check from TLB entry */ | 731 | /* Check from TLB entry */ |
| 730 | /* Check write protection bit */ | 732 | /* Check write protection bit */ |
| 731 | - if (rw && !(tlb->prot & PAGE_WRITE)) { | ||
| 732 | - ret = -2; | 733 | + if (tlb->prot & PAGE_WRITE) { |
| 734 | + ctx->prot = PAGE_READ | PAGE_WRITE; | ||
| 735 | + ret = 0; | ||
| 733 | } else { | 736 | } else { |
| 734 | - ret = 2; | ||
| 735 | - if (tlb->prot & PAGE_WRITE) | ||
| 736 | - ctx->prot = PAGE_READ | PAGE_WRITE; | 737 | + ctx->prot = PAGE_READ; |
| 738 | + if (rw) | ||
| 739 | + ret = -2; | ||
| 737 | else | 740 | else |
| 738 | - ctx->prot = PAGE_READ; | 741 | + ret = 0; |
| 739 | } | 742 | } |
| 740 | break; | 743 | break; |
| 741 | case 0x3: | 744 | case 0x3: |
| 742 | /* All accesses granted */ | 745 | /* All accesses granted */ |
| 743 | - ret = 2; | ||
| 744 | ctx->prot = PAGE_READ | PAGE_WRITE; | 746 | ctx->prot = PAGE_READ | PAGE_WRITE; |
| 747 | + ret = 0; | ||
| 745 | break; | 748 | break; |
| 746 | } | 749 | } |
| 747 | } | 750 | } |
| @@ -749,11 +752,17 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | @@ -749,11 +752,17 @@ int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx, | ||
| 749 | ctx->raddr = raddr; | 752 | ctx->raddr = raddr; |
| 750 | if (loglevel) { | 753 | if (loglevel) { |
| 751 | fprintf(logfile, "%s: access granted " ADDRX " => " REGX | 754 | fprintf(logfile, "%s: access granted " ADDRX " => " REGX |
| 752 | - " %d\n", __func__, address, ctx->raddr, ctx->prot); | 755 | + " %d %d\n", __func__, address, ctx->raddr, ctx->prot, |
| 756 | + ret); | ||
| 753 | } | 757 | } |
| 754 | - return i; | 758 | + return 0; |
| 755 | } | 759 | } |
| 756 | } | 760 | } |
| 761 | + if (loglevel) { | ||
| 762 | + fprintf(logfile, "%s: access refused " ADDRX " => " REGX | ||
| 763 | + " %d %d\n", __func__, address, raddr, ctx->prot, | ||
| 764 | + ret); | ||
| 765 | + } | ||
| 757 | 766 | ||
| 758 | return ret; | 767 | return ret; |
| 759 | } | 768 | } |
| @@ -808,32 +817,49 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | @@ -808,32 +817,49 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, | ||
| 808 | /* No address translation */ | 817 | /* No address translation */ |
| 809 | ret = check_physical(env, ctx, eaddr, rw); | 818 | ret = check_physical(env, ctx, eaddr, rw); |
| 810 | } else { | 819 | } else { |
| 820 | + ret = -1; | ||
| 811 | switch (PPC_MMU(env)) { | 821 | switch (PPC_MMU(env)) { |
| 812 | case PPC_FLAGS_MMU_32B: | 822 | case PPC_FLAGS_MMU_32B: |
| 813 | case PPC_FLAGS_MMU_SOFT_6xx: | 823 | case PPC_FLAGS_MMU_SOFT_6xx: |
| 814 | /* Try to find a BAT */ | 824 | /* Try to find a BAT */ |
| 815 | - ret = -1; | ||
| 816 | if (check_BATs) | 825 | if (check_BATs) |
| 817 | ret = get_bat(env, ctx, eaddr, rw, access_type); | 826 | ret = get_bat(env, ctx, eaddr, rw, access_type); |
| 827 | + /* No break here */ | ||
| 828 | +#if defined(TARGET_PPC64) | ||
| 829 | + case PPC_FLAGS_MMU_64B: | ||
| 830 | + case PPC_FLAGS_MMU_64BRIDGE: | ||
| 831 | +#endif | ||
| 818 | if (ret < 0) { | 832 | if (ret < 0) { |
| 819 | - /* We didn't match any BAT entry */ | 833 | + /* We didn't match any BAT entry or don't have BATs */ |
| 820 | ret = get_segment(env, ctx, eaddr, rw, access_type); | 834 | ret = get_segment(env, ctx, eaddr, rw, access_type); |
| 821 | } | 835 | } |
| 822 | break; | 836 | break; |
| 823 | case PPC_FLAGS_MMU_SOFT_4xx: | 837 | case PPC_FLAGS_MMU_SOFT_4xx: |
| 838 | + case PPC_FLAGS_MMU_403: | ||
| 824 | ret = mmu4xx_get_physical_address(env, ctx, eaddr, | 839 | ret = mmu4xx_get_physical_address(env, ctx, eaddr, |
| 825 | rw, access_type); | 840 | rw, access_type); |
| 826 | break; | 841 | break; |
| 827 | - default: | 842 | + case PPC_FLAGS_MMU_601: |
| 843 | + /* XXX: TODO */ | ||
| 844 | + cpu_abort(env, "601 MMU model not implemented\n"); | ||
| 845 | + return -1; | ||
| 846 | + case PPC_FLAGS_MMU_BOOKE: | ||
| 828 | /* XXX: TODO */ | 847 | /* XXX: TODO */ |
| 829 | - cpu_abort(env, "MMU model not implemented\n"); | 848 | + cpu_abort(env, "BookeE MMU model not implemented\n"); |
| 849 | + return -1; | ||
| 850 | + case PPC_FLAGS_MMU_BOOKE_FSL: | ||
| 851 | + /* XXX: TODO */ | ||
| 852 | + cpu_abort(env, "BookE FSL MMU model not implemented\n"); | ||
| 853 | + return -1; | ||
| 854 | + default: | ||
| 855 | + cpu_abort(env, "Unknown or invalid MMU model\n"); | ||
| 830 | return -1; | 856 | return -1; |
| 831 | } | 857 | } |
| 832 | } | 858 | } |
| 833 | #if 0 | 859 | #if 0 |
| 834 | if (loglevel > 0) { | 860 | if (loglevel > 0) { |
| 835 | - fprintf(logfile, "%s address " ADDRX " => " ADDRX "\n", | ||
| 836 | - __func__, eaddr, ctx->raddr); | 861 | + fprintf(logfile, "%s address " ADDRX " => %d " ADDRX "\n", |
| 862 | + __func__, eaddr, ret, ctx->raddr); | ||
| 837 | } | 863 | } |
| 838 | #endif | 864 | #endif |
| 839 | 865 | ||
| @@ -885,19 +911,48 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | @@ -885,19 +911,48 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
| 885 | switch (ret) { | 911 | switch (ret) { |
| 886 | case -1: | 912 | case -1: |
| 887 | /* No matches in page tables or TLB */ | 913 | /* No matches in page tables or TLB */ |
| 888 | - if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) { | 914 | + switch (PPC_MMU(env)) { |
| 915 | + case PPC_FLAGS_MMU_SOFT_6xx: | ||
| 889 | exception = EXCP_I_TLBMISS; | 916 | exception = EXCP_I_TLBMISS; |
| 890 | env->spr[SPR_IMISS] = address; | 917 | env->spr[SPR_IMISS] = address; |
| 891 | env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; | 918 | env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; |
| 892 | error_code = 1 << 18; | 919 | error_code = 1 << 18; |
| 893 | goto tlb_miss; | 920 | goto tlb_miss; |
| 894 | - } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { | 921 | + case PPC_FLAGS_MMU_SOFT_4xx: |
| 922 | + case PPC_FLAGS_MMU_403: | ||
| 895 | exception = EXCP_40x_ITLBMISS; | 923 | exception = EXCP_40x_ITLBMISS; |
| 896 | error_code = 0; | 924 | error_code = 0; |
| 897 | env->spr[SPR_40x_DEAR] = address; | 925 | env->spr[SPR_40x_DEAR] = address; |
| 898 | env->spr[SPR_40x_ESR] = 0x00000000; | 926 | env->spr[SPR_40x_ESR] = 0x00000000; |
| 899 | - } else { | 927 | + break; |
| 928 | + case PPC_FLAGS_MMU_32B: | ||
| 900 | error_code = 0x40000000; | 929 | error_code = 0x40000000; |
| 930 | + break; | ||
| 931 | +#if defined(TARGET_PPC64) | ||
| 932 | + case PPC_FLAGS_MMU_64B: | ||
| 933 | + /* XXX: TODO */ | ||
| 934 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 935 | + return -1; | ||
| 936 | + case PPC_FLAGS_MMU_64BRIDGE: | ||
| 937 | + /* XXX: TODO */ | ||
| 938 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 939 | + return -1; | ||
| 940 | +#endif | ||
| 941 | + case PPC_FLAGS_MMU_601: | ||
| 942 | + /* XXX: TODO */ | ||
| 943 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 944 | + return -1; | ||
| 945 | + case PPC_FLAGS_MMU_BOOKE: | ||
| 946 | + /* XXX: TODO */ | ||
| 947 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 948 | + return -1; | ||
| 949 | + case PPC_FLAGS_MMU_BOOKE_FSL: | ||
| 950 | + /* XXX: TODO */ | ||
| 951 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 952 | + return -1; | ||
| 953 | + default: | ||
| 954 | + cpu_abort(env, "Unknown or invalid MMU model\n"); | ||
| 955 | + return -1; | ||
| 901 | } | 956 | } |
| 902 | break; | 957 | break; |
| 903 | case -2: | 958 | case -2: |
| @@ -924,7 +979,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | @@ -924,7 +979,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
| 924 | switch (ret) { | 979 | switch (ret) { |
| 925 | case -1: | 980 | case -1: |
| 926 | /* No matches in page tables or TLB */ | 981 | /* No matches in page tables or TLB */ |
| 927 | - if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) { | 982 | + switch (PPC_MMU(env)) { |
| 983 | + case PPC_FLAGS_MMU_SOFT_6xx: | ||
| 928 | if (rw == 1) { | 984 | if (rw == 1) { |
| 929 | exception = EXCP_DS_TLBMISS; | 985 | exception = EXCP_DS_TLBMISS; |
| 930 | error_code = 1 << 16; | 986 | error_code = 1 << 16; |
| @@ -940,7 +996,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | @@ -940,7 +996,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
| 940 | env->spr[SPR_HASH2] = ctx.pg_addr[1]; | 996 | env->spr[SPR_HASH2] = ctx.pg_addr[1]; |
| 941 | /* Do not alter DAR nor DSISR */ | 997 | /* Do not alter DAR nor DSISR */ |
| 942 | goto out; | 998 | goto out; |
| 943 | - } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) { | 999 | + case PPC_FLAGS_MMU_SOFT_4xx: |
| 1000 | + case PPC_FLAGS_MMU_403: | ||
| 944 | exception = EXCP_40x_DTLBMISS; | 1001 | exception = EXCP_40x_DTLBMISS; |
| 945 | error_code = 0; | 1002 | error_code = 0; |
| 946 | env->spr[SPR_40x_DEAR] = address; | 1003 | env->spr[SPR_40x_DEAR] = address; |
| @@ -948,8 +1005,35 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | @@ -948,8 +1005,35 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
| 948 | env->spr[SPR_40x_ESR] = 0x00800000; | 1005 | env->spr[SPR_40x_ESR] = 0x00800000; |
| 949 | else | 1006 | else |
| 950 | env->spr[SPR_40x_ESR] = 0x00000000; | 1007 | env->spr[SPR_40x_ESR] = 0x00000000; |
| 951 | - } else { | 1008 | + break; |
| 1009 | + case PPC_FLAGS_MMU_32B: | ||
| 952 | error_code = 0x40000000; | 1010 | error_code = 0x40000000; |
| 1011 | + break; | ||
| 1012 | +#if defined(TARGET_PPC64) | ||
| 1013 | + case PPC_FLAGS_MMU_64B: | ||
| 1014 | + /* XXX: TODO */ | ||
| 1015 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 1016 | + return -1; | ||
| 1017 | + case PPC_FLAGS_MMU_64BRIDGE: | ||
| 1018 | + /* XXX: TODO */ | ||
| 1019 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 1020 | + return -1; | ||
| 1021 | +#endif | ||
| 1022 | + case PPC_FLAGS_MMU_601: | ||
| 1023 | + /* XXX: TODO */ | ||
| 1024 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 1025 | + return -1; | ||
| 1026 | + case PPC_FLAGS_MMU_BOOKE: | ||
| 1027 | + /* XXX: TODO */ | ||
| 1028 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 1029 | + return -1; | ||
| 1030 | + case PPC_FLAGS_MMU_BOOKE_FSL: | ||
| 1031 | + /* XXX: TODO */ | ||
| 1032 | + cpu_abort(env, "MMU model not implemented\n"); | ||
| 1033 | + return -1; | ||
| 1034 | + default: | ||
| 1035 | + cpu_abort(env, "Unknown or invalid MMU model\n"); | ||
| 1036 | + return -1; | ||
| 953 | } | 1037 | } |
| 954 | break; | 1038 | break; |
| 955 | case -2: | 1039 | case -2: |
target-ppc/op_helper.c
| @@ -2537,39 +2537,72 @@ void do_4xx_tlbsx_ (void) | @@ -2537,39 +2537,72 @@ void do_4xx_tlbsx_ (void) | ||
| 2537 | env->crf[0] = tmp; | 2537 | env->crf[0] = tmp; |
| 2538 | } | 2538 | } |
| 2539 | 2539 | ||
| 2540 | -void do_4xx_tlbwe_lo (void) | 2540 | +void do_4xx_tlbwe_hi (void) |
| 2541 | { | 2541 | { |
| 2542 | ppcemb_tlb_t *tlb; | 2542 | ppcemb_tlb_t *tlb; |
| 2543 | target_ulong page, end; | 2543 | target_ulong page, end; |
| 2544 | 2544 | ||
| 2545 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
| 2546 | + if (loglevel) { | ||
| 2547 | + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); | ||
| 2548 | + } | ||
| 2549 | +#endif | ||
| 2545 | T0 &= 0x3F; | 2550 | T0 &= 0x3F; |
| 2546 | tlb = &env->tlb[T0].tlbe; | 2551 | tlb = &env->tlb[T0].tlbe; |
| 2547 | /* Invalidate previous TLB (if it's valid) */ | 2552 | /* Invalidate previous TLB (if it's valid) */ |
| 2548 | if (tlb->prot & PAGE_VALID) { | 2553 | if (tlb->prot & PAGE_VALID) { |
| 2549 | end = tlb->EPN + tlb->size; | 2554 | end = tlb->EPN + tlb->size; |
| 2555 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
| 2556 | + if (loglevel) { | ||
| 2557 | + fprintf(logfile, "%s: invalidate old TLB %d start " ADDRX | ||
| 2558 | + " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end); | ||
| 2559 | + } | ||
| 2560 | +#endif | ||
| 2550 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) | 2561 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) |
| 2551 | tlb_flush_page(env, page); | 2562 | tlb_flush_page(env, page); |
| 2552 | } | 2563 | } |
| 2553 | tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7); | 2564 | tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7); |
| 2554 | tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1); | 2565 | tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1); |
| 2555 | - if (T1 & 0x400) | 2566 | + if (T1 & 0x40) |
| 2556 | tlb->prot |= PAGE_VALID; | 2567 | tlb->prot |= PAGE_VALID; |
| 2557 | else | 2568 | else |
| 2558 | tlb->prot &= ~PAGE_VALID; | 2569 | tlb->prot &= ~PAGE_VALID; |
| 2559 | - tlb->PID = env->spr[SPR_BOOKE_PID]; /* PID */ | 2570 | + tlb->PID = env->spr[SPR_40x_PID]; /* PID */ |
| 2560 | tlb->attr = T1 & 0xFF; | 2571 | tlb->attr = T1 & 0xFF; |
| 2572 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
| 2573 | + if (loglevel) { | ||
| 2574 | + fprintf(logfile, "%s: set up TLB %d RPN " ADDRX " EPN " ADDRX | ||
| 2575 | + " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, | ||
| 2576 | + (int)T0, tlb->RPN, tlb->EPN, tlb->size, | ||
| 2577 | + tlb->prot & PAGE_READ ? 'r' : '-', | ||
| 2578 | + tlb->prot & PAGE_WRITE ? 'w' : '-', | ||
| 2579 | + tlb->prot & PAGE_EXEC ? 'x' : '-', | ||
| 2580 | + tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); | ||
| 2581 | + } | ||
| 2582 | +#endif | ||
| 2561 | /* Invalidate new TLB (if valid) */ | 2583 | /* Invalidate new TLB (if valid) */ |
| 2562 | if (tlb->prot & PAGE_VALID) { | 2584 | if (tlb->prot & PAGE_VALID) { |
| 2563 | end = tlb->EPN + tlb->size; | 2585 | end = tlb->EPN + tlb->size; |
| 2586 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
| 2587 | + if (loglevel) { | ||
| 2588 | + fprintf(logfile, "%s: invalidate TLB %d start " ADDRX | ||
| 2589 | + " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end); | ||
| 2590 | + } | ||
| 2591 | +#endif | ||
| 2564 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) | 2592 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) |
| 2565 | tlb_flush_page(env, page); | 2593 | tlb_flush_page(env, page); |
| 2566 | } | 2594 | } |
| 2567 | } | 2595 | } |
| 2568 | 2596 | ||
| 2569 | -void do_4xx_tlbwe_hi (void) | 2597 | +void do_4xx_tlbwe_lo (void) |
| 2570 | { | 2598 | { |
| 2571 | ppcemb_tlb_t *tlb; | 2599 | ppcemb_tlb_t *tlb; |
| 2572 | 2600 | ||
| 2601 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
| 2602 | + if (loglevel) { | ||
| 2603 | + fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1); | ||
| 2604 | + } | ||
| 2605 | +#endif | ||
| 2573 | T0 &= 0x3F; | 2606 | T0 &= 0x3F; |
| 2574 | tlb = &env->tlb[T0].tlbe; | 2607 | tlb = &env->tlb[T0].tlbe; |
| 2575 | tlb->RPN = T1 & 0xFFFFFC00; | 2608 | tlb->RPN = T1 & 0xFFFFFC00; |
| @@ -2578,5 +2611,16 @@ void do_4xx_tlbwe_hi (void) | @@ -2578,5 +2611,16 @@ void do_4xx_tlbwe_hi (void) | ||
| 2578 | tlb->prot |= PAGE_EXEC; | 2611 | tlb->prot |= PAGE_EXEC; |
| 2579 | if (T1 & 0x100) | 2612 | if (T1 & 0x100) |
| 2580 | tlb->prot |= PAGE_WRITE; | 2613 | tlb->prot |= PAGE_WRITE; |
| 2614 | +#if defined (DEBUG_SOFTWARE_TLB) | ||
| 2615 | + if (loglevel) { | ||
| 2616 | + fprintf(logfile, "%s: set up TLB %d RPN " ADDRX " EPN " ADDRX | ||
| 2617 | + " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, | ||
| 2618 | + (int)T0, tlb->RPN, tlb->EPN, tlb->size, | ||
| 2619 | + tlb->prot & PAGE_READ ? 'r' : '-', | ||
| 2620 | + tlb->prot & PAGE_WRITE ? 'w' : '-', | ||
| 2621 | + tlb->prot & PAGE_EXEC ? 'x' : '-', | ||
| 2622 | + tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); | ||
| 2623 | + } | ||
| 2624 | +#endif | ||
| 2581 | } | 2625 | } |
| 2582 | #endif /* !CONFIG_USER_ONLY */ | 2626 | #endif /* !CONFIG_USER_ONLY */ |