Commit 92d44128 authored by Vineet Gupta's avatar Vineet Gupta

ARCv2: Accomodate HS48 MMUv5 by relaxing MMU ver checking

HS48 cpus will have a new MMUv5, although Linux is currently not
explicitly supporting the newer features (so remains at V4).
The existing software/hardware version check is very tight and causes
boot abort. Given that the MMUv5 hardware is backwards compatible,
relax the boot check to allow current kernel support level to work
with new hardware.

Also while at it, move the ancient MMU related code to under ARCompact
builds as baseline MMU for HS cpus is v4.
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 4fbaf649
...@@ -762,21 +762,23 @@ void read_decode_mmu_bcr(void) ...@@ -762,21 +762,23 @@ void read_decode_mmu_bcr(void)
tmp = read_aux_reg(ARC_REG_MMU_BCR); tmp = read_aux_reg(ARC_REG_MMU_BCR);
mmu->ver = (tmp >> 24); mmu->ver = (tmp >> 24);
if (mmu->ver <= 2) { if (is_isa_arcompact()) {
mmu2 = (struct bcr_mmu_1_2 *)&tmp; if (mmu->ver <= 2) {
mmu->pg_sz_k = TO_KB(0x2000); mmu2 = (struct bcr_mmu_1_2 *)&tmp;
mmu->sets = 1 << mmu2->sets; mmu->pg_sz_k = TO_KB(0x2000);
mmu->ways = 1 << mmu2->ways; mmu->sets = 1 << mmu2->sets;
mmu->u_dtlb = mmu2->u_dtlb; mmu->ways = 1 << mmu2->ways;
mmu->u_itlb = mmu2->u_itlb; mmu->u_dtlb = mmu2->u_dtlb;
} else if (mmu->ver == 3) { mmu->u_itlb = mmu2->u_itlb;
mmu3 = (struct bcr_mmu_3 *)&tmp; } else {
mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1); mmu3 = (struct bcr_mmu_3 *)&tmp;
mmu->sets = 1 << mmu3->sets; mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1);
mmu->ways = 1 << mmu3->ways; mmu->sets = 1 << mmu3->sets;
mmu->u_dtlb = mmu3->u_dtlb; mmu->ways = 1 << mmu3->ways;
mmu->u_itlb = mmu3->u_itlb; mmu->u_dtlb = mmu3->u_dtlb;
mmu->sasid = mmu3->sasid; mmu->u_itlb = mmu3->u_itlb;
mmu->sasid = mmu3->sasid;
}
} else { } else {
mmu4 = (struct bcr_mmu_4 *)&tmp; mmu4 = (struct bcr_mmu_4 *)&tmp;
mmu->pg_sz_k = 1 << (mmu4->sz0 - 1); mmu->pg_sz_k = 1 << (mmu4->sz0 - 1);
...@@ -818,8 +820,9 @@ int pae40_exist_but_not_enab(void) ...@@ -818,8 +820,9 @@ int pae40_exist_but_not_enab(void)
void arc_mmu_init(void) void arc_mmu_init(void)
{ {
char str[256];
struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu;
char str[256];
int compat = 0;
pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str)));
...@@ -834,15 +837,21 @@ void arc_mmu_init(void) ...@@ -834,15 +837,21 @@ void arc_mmu_init(void)
*/ */
BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE)); BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
/* For efficiency sake, kernel is compile time built for a MMU ver /*
* This must match the hardware it is running on. * Ensure that MMU features assumed by kernel exist in hardware.
* Linux built for MMU V2, if run on MMU V1 will break down because V1 * For older ARC700 cpus, it has to be exact match, since the MMU
* hardware doesn't understand cmds such as WriteNI, or IVUTLB * revisions were not backwards compatible (MMUv3 TLB layout changed
* On the other hand, Linux built for V1 if run on MMU V2 will do * so even if kernel for v2 didn't use any new cmds of v3, it would
* un-needed workarounds to prevent memcpy thrashing. * still not work.
* Similarly MMU V3 has new features which won't work on older MMU * For HS cpus, MMUv4 was baseline and v5 is backwards compatible
* (will run older software).
*/ */
if (mmu->ver != CONFIG_ARC_MMU_VER) { if (is_isa_arcompact() && mmu->ver == CONFIG_ARC_MMU_VER)
compat = 1;
else if (is_isa_arcv2() && mmu->ver >= CONFIG_ARC_MMU_VER)
compat = 1;
if (!compat) {
panic("MMU ver %d doesn't match kernel built for %d...\n", panic("MMU ver %d doesn't match kernel built for %d...\n",
mmu->ver, CONFIG_ARC_MMU_VER); mmu->ver, CONFIG_ARC_MMU_VER);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment