ARCv2: Accomodate NS48 MMUv5 by releaxing MMU ver checking

Message ID 1509996651-7174-1-git-send-email-vgupta@synopsys.com
State New
Headers show
Series
  • ARCv2: Accomodate NS48 MMUv5 by releaxing MMU ver checking
Related show

Commit Message

Vineet Gupta Nov. 6, 2017, 7:30 p.m.
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: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/mm/tlb.c | 57 ++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

Comments

Alexey Brodkin Nov. 7, 2017, 3:33 p.m. | #1
Hi Vineet,

Subject contains one typo: NS48 -> HS48.

On Mon, 2017-11-06 at 11:30 -0800, Vineet Gupta wrote:
> 
> 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.

I don't terribly like this approach with assuming all ARCv2 MMUs are
backward-compatible. This time v5 is indeed backward compatible with
v4 from our stand-point. But what if v6 becomes non-compatible to
both v4 and v6?

That said I'd prefer to add each particular MMU version explicitly like
we used to do previously.

Your intention to make built today binaries future-proof is understood but
again if following MMUs become non-compatible we'll need to rewrite this code
again.

One better option would be more precise encoding of MMU version in hardware
such that based on combination of features we may decide if we may handle it.

-Alexey
Vineet Gupta Nov. 7, 2017, 4:49 p.m. | #2
On 11/07/2017 07:33 AM, Alexey Brodkin wrote:
> Hi Vineet,
>
> Subject contains one typo: NS48 -> HS48.
>
> On Mon, 2017-11-06 at 11:30 -0800, Vineet Gupta wrote:
>> 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.
> I don't terribly like this approach with assuming all ARCv2 MMUs are
> backward-compatible. This time v5 is indeed backward compatible with
> v4 from our stand-point. But what if v6 becomes non-compatible to
> both v4 and v6?

The guiding principle for new cores is that we will try to keep things compatible. 
There's no MMUv6 spec'ed yet - so we can't speak for it already.

> That said I'd prefer to add each particular MMU version explicitly like
> we used to do previously.

But most of the v5 features don't apply to Linux - so what support in software 
will you actually add. There's no point bumbing kconfig to V5 and pretneding we 
support a v5 feature when there's none we are supporting.

> Your intention to make built today binaries future-proof is understood but
> again if following MMUs become non-compatible we'll need to rewrite this code
> again.

It is not so much about future proofing - but just supporting the new hardware 
with sufficient changes.
If MMUs become non compatible then we come up with a comaptibility matrix or some 
such - although I'm hoping we won't.

> One better option would be more precise encoding of MMU version in hardware
> such that based on combination of features we may decide if we may handle it.

That's already done today in the MMU Build config register. It's just that the new 
features don't really apply to Linux per se - not right away atleast.

-Vineet
Alexey Brodkin Nov. 8, 2017, 8:20 a.m. | #3
Hi Vineet,

Subject contains one typo: NS48 -> HS48.

On Mon, 2017-11-06 at 11:30 -0800, Vineet Gupta wrote:
> 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.

I don't terribly like this approach with assuming all ARCv2 MMUs are
backward-compatible. This time v5 is indeed backward compatible with
v4 from our stand-point. But what if v6 becomes non-compatible to
both v4 and v6?

That said I'd prefer to add each particular MMU version explicitly like
we used to do previously.

Your intention to make built today binaries future-proof is understood but
again if following MMUs become non-compatible we'll need to rewrite this code
again.

One better option would be more precise encoding of MMU version in hardware
such that based on combination of features we may decide if we may handle it.

-Alexey

Patch

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)
 	tmp = read_aux_reg(ARC_REG_MMU_BCR);
 	mmu->ver = (tmp >> 24);
 
-	if (mmu->ver <= 2) {
-		mmu2 = (struct bcr_mmu_1_2 *)&tmp;
-		mmu->pg_sz_k = TO_KB(0x2000);
-		mmu->sets = 1 << mmu2->sets;
-		mmu->ways = 1 << mmu2->ways;
-		mmu->u_dtlb = mmu2->u_dtlb;
-		mmu->u_itlb = mmu2->u_itlb;
-	} else if (mmu->ver == 3) {
-		mmu3 = (struct bcr_mmu_3 *)&tmp;
-		mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1);
-		mmu->sets = 1 << mmu3->sets;
-		mmu->ways = 1 << mmu3->ways;
-		mmu->u_dtlb = mmu3->u_dtlb;
-		mmu->u_itlb = mmu3->u_itlb;
-		mmu->sasid = mmu3->sasid;
+	if (is_isa_arcompact()) {
+		if (mmu->ver <= 2) {
+			mmu2 = (struct bcr_mmu_1_2 *)&tmp;
+			mmu->pg_sz_k = TO_KB(0x2000);
+			mmu->sets = 1 << mmu2->sets;
+			mmu->ways = 1 << mmu2->ways;
+			mmu->u_dtlb = mmu2->u_dtlb;
+			mmu->u_itlb = mmu2->u_itlb;
+		} else {
+			mmu3 = (struct bcr_mmu_3 *)&tmp;
+			mmu->pg_sz_k = 1 << (mmu3->pg_sz - 1);
+			mmu->sets = 1 << mmu3->sets;
+			mmu->ways = 1 << mmu3->ways;
+			mmu->u_dtlb = mmu3->u_dtlb;
+			mmu->u_itlb = mmu3->u_itlb;
+			mmu->sasid = mmu3->sasid;
+		}
 	} else {
 		mmu4 = (struct bcr_mmu_4 *)&tmp;
 		mmu->pg_sz_k = 1 << (mmu4->sz0 - 1);
@@ -818,8 +820,9 @@  int pae40_exist_but_not_enab(void)
 
 void arc_mmu_init(void)
 {
-	char str[256];
 	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)));
 
@@ -834,15 +837,21 @@  void arc_mmu_init(void)
 	 */
 	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.
-	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-	 *  hardware doesn't understand cmds such as WriteNI, or IVUTLB
-	 * On the other hand, Linux built for V1 if run on MMU V2 will do
-	 *   un-needed workarounds to prevent memcpy thrashing.
-	 * Similarly MMU V3 has new features which won't work on older MMU
+	/*
+	 * Ensure that MMU features assumed by kernel exist in hardware.
+	 * For older ARC700 cpus, it has to be exact match, since the MMU
+	 * revisions were not backwards compatible (MMUv3 TLB layout changed
+	 * so even if kernel for v2 didn't use any new cmds of v3, it would
+	 * still not work.
+	 * 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",
 		      mmu->ver, CONFIG_ARC_MMU_VER);
 	}