Skip to contentSkip to conversation

Miscellaneous patches for 3.1 and 3.2

PATCH New Will Deacon 6 participants 16 messages Aug 8, 2011 – Aug 9, 2011

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Miscellaneous patches for 3.1 and 3.2

Hello,

This is a bit of a strange mix of patches that I've got lying around on top of -rc1.

The following patches are fixes and I'd like to put them into Russell's patch system in the near future:

ARM: realview: ensure visibility of writes during reset
ARM: twd: register clockevents device before enabling PPI
ARM: cache: detect VIPT aliasing I-cache on ARMv6

The other patches can wait until closer to the next merge window and I'd welcome any feedback on those. The boot CPU number patch is probably the most controversial given that I doubt many platforms can support booting on anything other than CPU0 (although my Realview-PBX is happy enough).

Will

Will Deacon (6):
ARM: vexpress: determine active tile site before reading tile ID
ARM: realview: ensure visibility of writes during reset
ARM: twd: register clockevents device before enabling PPI
ARM: smp: set thread_info->cpu to hardware CPU number for boot thread
ARM: cache: detect VIPT aliasing I-cache on ARMv6
ARM: cache: detect PIPT I-cache using CTR

 arch/arm/include/asm/cachetype.h                  |    5 +++-
 arch/arm/kernel/setup.c                           |   30 ++++++++++++++------
 arch/arm/kernel/smp.c                             |   16 +++++++++++
 arch/arm/kernel/smp_twd.c                         |    4 +-
 arch/arm/mach-realview/include/mach/system.h      |    1 +
 arch/arm/mach-vexpress/include/mach/motherboard.h |    5 +++
 arch/arm/mach-vexpress/v2m.c                      |    6 +++-
 7 files changed, 53 insertions(+), 14 deletions(-)
#1 lore raw

PATCH 1/6 ARM: vexpress: determine active tile site before reading tile ID

The Versatile Express platform features two tile sites and communicates the active tile site via the SYS_MISC register on the motherboard.

This patch updates the tile detection code to read the ID for the currently active tile during boot.

---
 arch/arm/mach-vexpress/include/mach/motherboard.h |    5 +++++
 arch/arm/mach-vexpress/v2m.c                      |    6 ++++--
 2 files changed, 9 insertions(+), 2 deletions(-)
arch/arm/mach-vexpress/include/mach/motherboard.h +5 -0
index 0a3a375..163a22c 100644
@@ -119,6 +119,11 @@ int v2m_cfg_write(u32 devfn, u32 data);
 int v2m_cfg_read(u32 devfn, u32 *data);
 
 /*
+ * Miscellaneous
+ */
+#define SYS_MISC_MASTERSITE	(1 << 14)
+
+/*
  * Core tile IDs
  */
 #define V2M_CT_ID_CA9		0x0c000191
arch/arm/mach-vexpress/v2m.c +4 -2
index 9e6b93b..dbb182c 100644
@@ -389,10 +389,12 @@ static struct ct_desc *ct_descs[] __initdata = {
 static void __init v2m_populate_ct_desc(void)
 {
 	int i;
-	u32 current_tile_id;
+	u32 procid_reg, current_tile_id;
 
 	ct_desc = NULL;
-	current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
+	procid_reg = readl(MMIO_P2V(V2M_SYS_MISC)) & SYS_MISC_MASTERSITE ?
+			V2M_SYS_PROCID1 : V2M_SYS_PROCID0;
+	current_tile_id = readl(MMIO_P2V(procid_reg)) & V2M_CT_ID_MASK;
 
 	for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
 		if (ct_descs[i]->id == current_tile_id)
Signature · 1 line
1.7.0.4
#2 lore raw

PATCH 2/6 ARM: realview: ensure visibility of writes during reset

In reply to Will Deacon

The various reset routines in mach-realview rely on an FPGA to power-cycle the board after writing some magic runes to memory-mapped registers.

This patch adds a dsb() following the writes, so that they become visible before we mdelay(1000) in the arch_reset code. Without this patch, the timeout would expire sporadically, causing the reset to fail.

---
 arch/arm/mach-realview/include/mach/system.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
arch/arm/mach-realview/include/mach/system.h +1 -0
index a30f2e3..6657ff2 100644
@@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd)
 	 */
 	if (realview_reset)
 		realview_reset(mode);
+	dsb();
 }
 
 #endif
Signature · 1 line
1.7.0.4
#3 lore raw

PATCH 2/6 ARM: realview: ensure visibility of writes during reset

Quoted 18 lines · Will Deacon

The various reset routines in mach-realview rely on an FPGA to power-cycle the board after writing some magic runes to memory-mapped registers.

This patch adds a dsb() following the writes, so that they become visible before we mdelay(1000) in the arch_reset code. Without this patch, the timeout would expire sporadically, causing the reset to fail.

---
 arch/arm/mach-realview/include/mach/system.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
arch/arm/mach-realview/include/mach/system.h +0 -0
index a30f2e3..6657ff2 100644

arch/arm/mach-realview/include/mach/system.h static inline void arch_reset(char mode, const char *cmd) · line 47

Quoted 4 lines
arch/arm/mach-realview/include/mach/system.h +1 -0
@@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd)
 	 */
 	if (realview_reset)
 		realview_reset(mode);
+	dsb();

Wouldn't it be better to do this globally.

Rob

#4 lore raw

PATCH 2/6 ARM: realview: ensure visibility of writes during reset

Hi Rob,

Quoted 14 lines · Rob Herring
Quoted 13 lines · Will Deacon

The various reset routines in mach-realview rely on an FPGA to power-cycle the board after writing some magic runes to memory-mapped registers.

This patch adds a dsb() following the writes, so that they become visible before we mdelay(1000) in the arch_reset code. Without this patch, the timeout would expire sporadically, causing the reset to fail.

---
 arch/arm/mach-realview/include/mach/system.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
Quoted 11 lines

arch/arm/mach-realview/include/mach/system.h static inline void arch_reset(char mode, const char *cmd) · line 47

Quoted 9 lines
arch/arm/mach-realview/include/mach/system.h +1 -0
index a30f2e3..6657ff2 100644
@@ -44,6 +44,7 @@ static inline void arch_reset(char mode, const char *cmd)
 	 */
 	if (realview_reset)
 		realview_reset(mode);
+	dsb();

Wouldn't it be better to do this globally.

I'd rather leave it in the arch-specific code since otherwise it feels like we're leaking the actual reset implementation into the caller. Plus it's not entirely clear that there's a one-size-fits-all solution here.

Cheers,

Will

#5 lore raw

PATCH 3/6 ARM: twd: register clockevents device before enabling PPI

In reply to Will Deacon

The smp_twd clockevents driver currently enables the local timer PPI before the clockevents device is registered. This can lead to a kernel panic if a spurious timer interrupt is generated before registration has completed since the kernel will treat it as an IPI timer.

This patch moves the clockevents device registration before the IRQ unmasking so that we can always handle timer interrupts once they can occur.

---
 arch/arm/kernel/smp_twd.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
arch/arm/kernel/smp_twd.c +2 -2
index 2c277d4..01c1862 100644
@@ -137,8 +137,8 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 	clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
 	clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
 
+	clockevents_register_device(clk);
+
 	/* Make sure our local interrupt controller has this enabled */
 	gic_enable_ppi(clk->irq);
-
-	clockevents_register_device(clk);
 }
Signature · 1 line
1.7.0.4
#6 lore raw

PATCH 3/6 ARM: twd: register clockevents device before enabling PPI

Quoted 10 lines · Will Deacon

The smp_twd clockevents driver currently enables the local timer PPI before the clockevents device is registered. This can lead to a kernel panic if a spurious timer interrupt is generated before registration has completed since the kernel will treat it as an IPI timer.

This patch moves the clockevents device registration before the IRQ unmasking so that we can always handle timer interrupts once they can occur.

I'll rebase my timer patches on top of this one.

	M.
Signature · 1 line
Jazz is not dead. It just smells funny...
#7 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

In reply to Will Deacon

On ARM, Linux assumes that the boot CPU has ID 0. If this ends up being out of sync with the hardware CPU number, we will configure the GIC incorrectly and route interrupts to the CPU with hardware ID 0.

This patch implements smp_setup_processor_id for ARM, using the MPIDR to set the CPU of the boot thread.

---
 arch/arm/kernel/smp.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/kernel/smp.c +16 -0
index d88ff02..8e60a4f 100644
@@ -259,6 +259,22 @@ void __ref cpu_die(void)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
+void __init smp_setup_processor_id(void)
+{
+	u32 mpidr;
+
+	/* Read the MPIDR to find the hardware ID of the current CPU. */
+	asm("1:		mrc	p15, 0, %0, c0, c0, 5\n"
+	    "		.pushsection \".alt.smp.init\", \"a\"\n"
+	    "		.long	1b\n"
+	    "		mov	%0, #0\n"
+	    "		.popsection"
+	    : "=r" (mpidr));
+
+	current_thread_info()->cpu = mpidr & 0xff;
+	printk("Booting Linux on CPU %d\n", current_thread_info()->cpu);
+}
+
 /*
  * Called by both boot and secondaries to move global data into
  * per-processor storage.
Signature · 1 line
1.7.0.4
#8 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 272

Quoted 13 lines · Will Deacon
arch/arm/kernel/smp.c +11 -0
+void __init smp_setup_processor_id(void)
+{
+	u32 mpidr;
+
+	/* Read the MPIDR to find the hardware ID of the current CPU. */
+	asm("1:		mrc	p15, 0, %0, c0, c0, 5\n"
+	    "		.pushsection \".alt.smp.init\", \"a\"\n"
+	    "		.long	1b\n"
+	    "		mov	%0, #0\n"
+	    "		.popsection"
+	    : "=r" (mpidr));

Would it be a good idea to put this into asm/cputype.h? I suppose the smp alternatives part would need to be written in C.

    mpidr = is_smp() ? read_cpuid_mpidr() : 0;

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 277

Quoted 6 lines
arch/arm/kernel/smp.c +5 -0
+
+	current_thread_info()->cpu = mpidr & 0xff;
+	printk("Booting Linux on CPU %d\n", current_thread_info()->cpu);
+}
+

Should there be a KERN_INFO there?

Signature · 2 lines
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
#9 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

Quoted 18 lines · Stephen Boyd

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 272

Quoted 13 lines · Will Deacon
arch/arm/kernel/smp.c +11 -0
+void __init smp_setup_processor_id(void)
+{
+	u32 mpidr;
+
+	/* Read the MPIDR to find the hardware ID of the current CPU. */
+	asm("1:		mrc	p15, 0, %0, c0, c0, 5\n"
+	    "		.pushsection \".alt.smp.init\", \"a\"\n"
+	    "		.long	1b\n"
+	    "		mov	%0, #0\n"
+	    "		.popsection"
+	    : "=r" (mpidr));

Would it be a good idea to put this into asm/cputype.h? I suppose the smp alternatives part would need to be written in C.

Quoted 1 line
    mpidr = is_smp() ? read_cpuid_mpidr() : 0;

Yes, that's much better. We used to have asm/smp_mpidr.h which did this, so I lifted the code from there but doing it in C is easier to read.

Quoted 8 lines

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 277

Quoted 6 lines
arch/arm/kernel/smp.c +5 -0
+
+	current_thread_info()->cpu = mpidr & 0xff;
+	printk("Booting Linux on CPU %d\n", current_thread_info()->cpu);
+}
+

Should there be a KERN_INFO there?

Can be. I just followed suit with secondary_start_kernel, but smp.c doesn't seem to be consistent anyway so I'll add the specifier.

Thanks for the comments,

Will

#10 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

Quoted 33 lines · Will Deacon
Quoted 18 lines · Stephen Boyd

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 272

Quoted 13 lines · Will Deacon
arch/arm/kernel/smp.c +11 -0
+void __init smp_setup_processor_id(void)
+{
+	u32 mpidr;
+
+	/* Read the MPIDR to find the hardware ID of the current CPU. */
+	asm("1:		mrc	p15, 0, %0, c0, c0, 5\n"
+	    "		.pushsection \".alt.smp.init\", \"a\"\n"
+	    "		.long	1b\n"
+	    "		mov	%0, #0\n"
+	    "		.popsection"
+	    : "=r" (mpidr));

Would it be a good idea to put this into asm/cputype.h? I suppose the smp alternatives part would need to be written in C.

Quoted 1 line
    mpidr = is_smp() ? read_cpuid_mpidr() : 0;

Yes, that's much better. We used to have asm/smp_mpidr.h which did this, so I lifted the code from there but doing it in C is easier to read.

Quoted 8 lines

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 277

Quoted 6 lines
arch/arm/kernel/smp.c +5 -0
+
+	current_thread_info()->cpu = mpidr & 0xff;
+	printk("Booting Linux on CPU %d\n", current_thread_info()->cpu);
+}
+

Should there be a KERN_INFO there?

Quoted 2 lines

Can be. I just followed suit with secondary_start_kernel, but smp.c doesn't seem to be consistent anyway so I'll add the specifier.

Actually, it's probably much better to keep logical CPU0 as the boot CPU. The hotplug code makes the assumption that the lowest online CPU number is the boot CPU.

So unless we want even more pain, I suggest we just ensure logical CPU0 is the boot CPU.

We're already fairly clean on our interactions between CPU numbering and the hardware CPU numbering - there's only a limited number of places where the two interact. Those are the GIC, IPI, secondary CPU bringup, and hotplug code. I suggest that we preserve the independence, and introduce a mapping between logical CPU numbering and hardware CPU numbering.

#11 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

Hi Russell,

Quoted 7 lines · Russell King - ARM Linux
Quoted 2 lines · Will Deacon

Can be. I just followed suit with secondary_start_kernel, but smp.c doesn't seem to be consistent anyway so I'll add the specifier.

Actually, it's probably much better to keep logical CPU0 as the boot CPU. The hotplug code makes the assumption that the lowest online CPU number is the boot CPU.

Yes, you're right. I only tested this on a dual-core platform so I didn't get a chance to play with hotplug (except to see that it failed, like I expected). That assumption is also in the generic code so I guess it's easier to leave it be.

Quoted 2 lines

So unless we want even more pain, I suggest we just ensure logical CPU0 is the boot CPU.

Right. Ensuring the logical CPU number isn't too hard, but we should aim to support an arbitrary physical CPU number for the boot ID, even if most platforms can't cater for that at the moment.

Quoted 5 lines

We're already fairly clean on our interactions between CPU numbering and the hardware CPU numbering - there's only a limited number of places where the two interact. Those are the GIC, IPI, secondary CPU bringup, and hotplug code. I suggest that we preserve the independence, and introduce a mapping between logical CPU numbering and hardware CPU numbering.

This was my initial approach but then I thought I'd try and cheat my messing with the logical numbering. I'll look at implementing the mapping and then updating the GIC and friends to indirect their CPU number lookups through that instead. I'll post it as its own series since it will be more than just a simple hack now.

Stay tuned...

Cheers,

Will

#12 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

In reply to Will Deacon

Hello.

Quoted 24 lines · Will Deacon

On ARM, Linux assumes that the boot CPU has ID 0. If this ends up being out of sync with the hardware CPU number, we will configure the GIC incorrectly and route interrupts to the CPU with hardware ID 0.

This patch implements smp_setup_processor_id for ARM, using the MPIDR to set the CPU of the boot thread.

---
  arch/arm/kernel/smp.c |   16 ++++++++++++++++
  1 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/kernel/smp.c +4 -0
index d88ff02..8e60a4f 100644
@@ -259,6 +259,22 @@ void __ref cpu_die(void)
  }
  #endif /* CONFIG_HOTPLUG_CPU */
 
+void __init smp_setup_processor_id(void)
+{
+	u32 mpidr;
+

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 275

Quoted 10 lines
arch/arm/kernel/smp.c +10 -0
+	/* Read the MPIDR to find the hardware ID of the current CPU. */
+	asm("1:		mrc	p15, 0, %0, c0, c0, 5\n"
+	    "		.pushsection \".alt.smp.init\", \"a\"\n"
+	    "		.long	1b\n"
+	    "		mov	%0, #0\n"
+	    "		.popsection"
+	    : "=r" (mpidr));
+
+	current_thread_info()->cpu = mpidr&  0xff;
+	printk("Booting Linux on CPU %d\n", current_thread_info()->cpu);

printk() should have the KERN_* logging facility.

WBR, Sergei

#13 lore raw

PATCH 4/6 ARM: smp: set thread_info->cpu to hardware CPU number for boot thread

Quoted 24 lines · Sergei Shtylyov

Hello.

Quoted 20 lines · Will Deacon

On ARM, Linux assumes that the boot CPU has ID 0. If this ends up being out of sync with the hardware CPU number, we will configure the GIC incorrectly and route interrupts to the CPU with hardware ID 0.

This patch implements smp_setup_processor_id for ARM, using the MPIDR to set the CPU of the boot thread.

---
  arch/arm/kernel/smp.c |   16 ++++++++++++++++
  1 files changed, 16 insertions(+), 0 deletions(-)
arch/arm/kernel/smp.c +0 -0
index d88ff02..8e60a4f 100644
@@ -259,6 +259,22 @@ void __ref cpu_die(void)
  }
  #endif /* CONFIG_HOTPLUG_CPU */
 
Quoted 16 lines
Quoted 4 lines
arch/arm/kernel/smp.c +4 -0
+void __init smp_setup_processor_id(void)
+{
+	u32 mpidr;
+

arch/arm/kernel/smp.c void __ref cpu_die(void) · line 275

Quoted 10 lines
arch/arm/kernel/smp.c +10 -0
+	/* Read the MPIDR to find the hardware ID of the current CPU. */
+	asm("1:		mrc	p15, 0, %0, c0, c0, 5\n"
+	    "		.pushsection \".alt.smp.init\", \"a\"\n"
+	    "		.long	1b\n"
+	    "		mov	%0, #0\n"
+	    "		.popsection"
+	    : "=r" (mpidr));
+
+	current_thread_info()->cpu = mpidr&  0xff;
+	printk("Booting Linux on CPU %d\n", current_thread_info()->cpu);

printk() should have the KERN_* logging facility.

There's an echo around here :) This patch is pretty much dead anyway after the discussion with Russell. I'll post some other guys soon.

Will

#14 lore raw

PATCH 5/6 ARM: cache: detect VIPT aliasing I-cache on ARMv6

In reply to Will Deacon

The current cache detection code does not check for an aliasing I-cache if the D-cache is found to be VIPT aliasing.

This patch fixes the problem by always checking for an aliasing I-cache on v6 and later.

---
 arch/arm/kernel/setup.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)
arch/arm/kernel/setup.c +8 -7
index d95de69..2cdba13 100644
@@ -280,18 +280,19 @@ static void __init cacheid_init(void)
 	if (arch >= CPU_ARCH_ARMv6) {
 		if ((cachetype & (7 << 29)) == 4 << 29) {
 			/* ARMv7 register format */
+			arch = CPU_ARCH_ARMv7;
 			cacheid = CACHEID_VIPT_NONALIASING;
 			if ((cachetype & (3 << 14)) == 1 << 14)
 				cacheid |= CACHEID_ASID_TAGGED;
-			else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
-				cacheid |= CACHEID_VIPT_I_ALIASING;
-		} else if (cachetype & (1 << 23)) {
-			cacheid = CACHEID_VIPT_ALIASING;
 		} else {
-			cacheid = CACHEID_VIPT_NONALIASING;
-			if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
-				cacheid |= CACHEID_VIPT_I_ALIASING;
+			arch = CPU_ARCH_ARMv6;
+			if (cachetype & (1 << 23))
+				cacheid = CACHEID_VIPT_ALIASING;
+			else
+				cacheid = CACHEID_VIPT_NONALIASING;
 		}
+		if (cpu_has_aliasing_icache(arch))
+			cacheid |= CACHEID_VIPT_I_ALIASING;
 	} else {
 		cacheid = CACHEID_VIVT;
 	}
Signature · 1 line
1.7.0.4
#15 lore raw

PATCH 6/6 ARM: cache: detect PIPT I-cache using CTR

In reply to Will Deacon

The Cache Type Register L1Ip field identifies I-caches with a PIPT policy using the encoding 11b.

This patch extends the cache policy parsing to identify PIPT I-caches correctly and prevent them from being treated as VIPT aliasing in cases where they are sufficiently large.

---
 arch/arm/include/asm/cachetype.h |    5 ++++-
 arch/arm/kernel/setup.c          |   15 +++++++++++++--
 2 files changed, 17 insertions(+), 3 deletions(-)
arch/arm/include/asm/cachetype.h +4 -1
index c023db0..7ea7814 100644
@@ -7,6 +7,7 @@
 #define CACHEID_VIPT			(CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
 #define CACHEID_ASID_TAGGED		(1 << 3)
 #define CACHEID_VIPT_I_ALIASING		(1 << 4)
+#define CACHEID_PIPT			(1 << 5)
 
 extern unsigned int cacheid;
 
@@ -16,6 +17,7 @@ extern unsigned int cacheid;
 #define cache_is_vipt_aliasing()	cacheid_is(CACHEID_VIPT_ALIASING)
 #define icache_is_vivt_asid_tagged()	cacheid_is(CACHEID_ASID_TAGGED)
 #define icache_is_vipt_aliasing()	cacheid_is(CACHEID_VIPT_I_ALIASING)
+#define icache_is_pipt()		cacheid_is(CACHEID_PIPT)
 
 /*
  * __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
@@ -26,7 +28,8 @@ extern unsigned int cacheid;
 #if __LINUX_ARM_ARCH__ >= 7
 #define __CACHEID_ARCH_MIN	(CACHEID_VIPT_NONALIASING |\
 				 CACHEID_ASID_TAGGED |\
-				 CACHEID_VIPT_I_ALIASING)
+				 CACHEID_VIPT_I_ALIASING |\
+				 CACHEID_PIPT)
 #elif __LINUX_ARM_ARCH__ >= 6
 #define	__CACHEID_ARCH_MIN	(~CACHEID_VIVT)
 #else
arch/arm/kernel/setup.c +13 -2
index 2cdba13..6311da7 100644
@@ -248,6 +248,10 @@ static int cpu_has_aliasing_icache(unsigned int arch)
 	int aliasing_icache;
 	unsigned int id_reg, num_sets, line_size;
 
+	/* PIPT caches never alias. */
+	if (icache_is_pipt())
+		return 0;
+
 	/* arch specifies the register format */
 	switch (arch) {
 	case CPU_ARCH_ARMv7:
@@ -282,8 +286,14 @@ static void __init cacheid_init(void)
 			/* ARMv7 register format */
 			arch = CPU_ARCH_ARMv7;
 			cacheid = CACHEID_VIPT_NONALIASING;
-			if ((cachetype & (3 << 14)) == 1 << 14)
+			switch (cachetype & (3 << 14)) {
+			case (1 << 14):
 				cacheid |= CACHEID_ASID_TAGGED;
+				break;
+			case (3 << 14):
+				cacheid |= CACHEID_PIPT;
+				break;
+			}
 		} else {
 			arch = CPU_ARCH_ARMv6;
 			if (cachetype & (1 << 23))
@@ -300,10 +310,11 @@ static void __init cacheid_init(void)
 	printk("CPU: %s data cache, %s instruction cache\n",
 		cache_is_vivt() ? "VIVT" :
 		cache_is_vipt_aliasing() ? "VIPT aliasing" :
-		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
+		cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
 		cache_is_vivt() ? "VIVT" :
 		icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
 		icache_is_vipt_aliasing() ? "VIPT aliasing" :
+		icache_is_pipt() ? "PIPT" :
 		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
 }
 
Signature · 1 line
1.7.0.4