diff options
| -rw-r--r-- | arch/arc/mm/tlb.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index 8ceefbf72fb0..4097764fea23 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c | |||
| @@ -762,21 +762,23 @@ void read_decode_mmu_bcr(void) | |||
| 762 | tmp = read_aux_reg(ARC_REG_MMU_BCR); | 762 | tmp = read_aux_reg(ARC_REG_MMU_BCR); |
| 763 | mmu->ver = (tmp >> 24); | 763 | mmu->ver = (tmp >> 24); |
| 764 | 764 | ||
| 765 | if (mmu->ver <= 2) { | 765 | if (is_isa_arcompact()) { |
| 766 | mmu2 = (struct bcr_mmu_1_2 *)&tmp; | 766 | if (mmu->ver <= 2) { |
| 767 | mmu->pg_sz_k = TO_KB(0x2000); | 767 | mmu2 = (struct bcr_mmu_1_2 *)&tmp; |
| 768 | mmu->sets = 1 << mmu2->sets; | 768 | mmu->pg_sz_k = TO_KB(0x2000); |
| 769 | mmu->ways = 1 << mmu2->ways; | 769 | mmu->sets = 1 << mmu2->sets; |
| 770 | mmu->u_dtlb = mmu2->u_dtlb; | 770 | mmu->ways = 1 << mmu2->ways; |
| 771 | mmu->u_itlb = mmu2->u_itlb; | 771 | mmu->u_dtlb = mmu2->u_dtlb; |
| 772 | } else if (mmu->ver == 3) { | 772 | mmu->u_itlb = mmu2->u_itlb; |
| 773 | mmu3 = (struct bcr_mmu_3 *)&tmp; | 773 | } else { |
| 774 | mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1); | 774 | mmu3 = (struct bcr_mmu_3 *)&tmp; |
| 775 | mmu->sets = 1 << mmu3->sets; | 775 | mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1); |
| 776 | mmu->ways = 1 << mmu3->ways; | 776 | mmu->sets = 1 << mmu3->sets; |
| 777 | mmu->u_dtlb = mmu3->u_dtlb; | 777 | mmu->ways = 1 << mmu3->ways; |
| 778 | mmu->u_itlb = mmu3->u_itlb; | 778 | mmu->u_dtlb = mmu3->u_dtlb; |
| 779 | mmu->sasid = mmu3->sasid; | 779 | mmu->u_itlb = mmu3->u_itlb; |
| 780 | mmu->sasid = mmu3->sasid; | ||
| 781 | } | ||
| 780 | } else { | 782 | } else { |
| 781 | mmu4 = (struct bcr_mmu_4 *)&tmp; | 783 | mmu4 = (struct bcr_mmu_4 *)&tmp; |
| 782 | mmu->pg_sz_k = 1 << (mmu4->sz0 - 1); | 784 | mmu->pg_sz_k = 1 << (mmu4->sz0 - 1); |
| @@ -818,8 +820,9 @@ int pae40_exist_but_not_enab(void) | |||
| 818 | 820 | ||
| 819 | void arc_mmu_init(void) | 821 | void arc_mmu_init(void) |
| 820 | { | 822 | { |
| 821 | char str[256]; | ||
| 822 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; | 823 | struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; |
| 824 | char str[256]; | ||
| 825 | int compat = 0; | ||
| 823 | 826 | ||
| 824 | pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); | 827 | pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); |
| 825 | 828 | ||
| @@ -834,15 +837,21 @@ void arc_mmu_init(void) | |||
| 834 | */ | 837 | */ |
| 835 | BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE)); | 838 | BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE)); |
| 836 | 839 | ||
| 837 | /* For efficiency sake, kernel is compile time built for a MMU ver | 840 | /* |
| 838 | * This must match the hardware it is running on. | 841 | * Ensure that MMU features assumed by kernel exist in hardware. |
| 839 | * Linux built for MMU V2, if run on MMU V1 will break down because V1 | 842 | * For older ARC700 cpus, it has to be exact match, since the MMU |
| 840 | * hardware doesn't understand cmds such as WriteNI, or IVUTLB | 843 | * revisions were not backwards compatible (MMUv3 TLB layout changed |
| 841 | * On the other hand, Linux built for V1 if run on MMU V2 will do | 844 | * so even if kernel for v2 didn't use any new cmds of v3, it would |
| 842 | * un-needed workarounds to prevent memcpy thrashing. | 845 | * still not work. |
| 843 | * Similarly MMU V3 has new features which won't work on older MMU | 846 | * For HS cpus, MMUv4 was baseline and v5 is backwards compatible |
| 847 | * (will run older software). | ||
| 844 | */ | 848 | */ |
| 845 | if (mmu->ver != CONFIG_ARC_MMU_VER) { | 849 | if (is_isa_arcompact() && mmu->ver == CONFIG_ARC_MMU_VER) |
| 850 | compat = 1; | ||
| 851 | else if (is_isa_arcv2() && mmu->ver >= CONFIG_ARC_MMU_VER) | ||
| 852 | compat = 1; | ||
| 853 | |||
| 854 | if (!compat) { | ||
| 846 | panic("MMU ver %d doesn't match kernel built for %d...\n", | 855 | panic("MMU ver %d doesn't match kernel built for %d...\n", |
| 847 | mmu->ver, CONFIG_ARC_MMU_VER); | 856 | mmu->ver, CONFIG_ARC_MMU_VER); |
| 848 | } | 857 | } |
