Russell/Catalin, Can this make way to patch system if you are ok with this version ? > -----Original Message----- > From: Shilimkar, Santosh > Sent: Monday, December 21, 2009 3:39 PM > To: linux@xxxxxxxxxxxxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-omap@xxxxxxxxxxxxxxx; tony@xxxxxxxxxxx; Shilimkar, > Santosh; Woodruff, Richard; Catalin Marinas > Subject: [PATCH v3] ARM: L2 : Errata 588369: Clean & Invalidate do not invalidate clean lines > > This patch implements the work-around for the errata 588369. The secure API > is used to alter L2 debug regsiter because of trust-zone. > > v3 is rebased on the latest 2.6.33-rc1 which has Russell's "pending-l2x0" > changes merged. The patch is tested on OMAP4430 SDP. > > Signed-off-by: Woodruff Richard <r-woodruff2@xxxxxx> > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@xxxxxx> > cc: Catalin Marinas <catalin.marinas@xxxxxxx> > --- > arch/arm/Kconfig | 13 ++++++++++++ > arch/arm/mm/cache-l2x0.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 63 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 233a222..3891b77 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -917,6 +917,19 @@ config ARM_ERRATA_460075 > ACTLR register. Note that setting specific bits in the ACTLR register > may not be available in non-secure mode. > > +config PL310_ERRATA_588369 > + bool "Clean & Invalidate maintenance operations do not invalidate clean lines" > + depends on CACHE_L2X0 && ARCH_OMAP4 > + help > + The PL310 L2 cache controller implements three types of Clean & > + Invalidate maintenance operations: by Physical Address > + (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC). > + They are architecturally defined to behave as the execution of a > + clean operation followed immediately by an invalidate operation, > + both performing to the same memory location. This functionality > + is not correctly implemented in PL310 as clean lines are not > + invalidated as a result of these operations. Note that this errata > + uses Texas Instrument's secure monitor api. > endmenu > > source "arch/arm/common/Kconfig" > diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c > index cb8fc65..5443c0d 100644 > --- a/arch/arm/mm/cache-l2x0.c > +++ b/arch/arm/mm/cache-l2x0.c > @@ -28,6 +28,24 @@ > static void __iomem *l2x0_base; > static DEFINE_SPINLOCK(l2x0_lock); > > +#ifdef CONFIG_PL310_ERRATA_588369 > +static void debug_writel(unsigned long val) > +{ > + register unsigned long r0 asm("r0") = val; > + /* > + * Texas Instrument secure monitor api to modify the PL310 > + * Debug Control Register. > + */ > + __asm__ __volatile__( > + __asmeq("%0", "r0") > + "ldr r12, =0x100\n" > + "dsb\n" > + "smc\n" > + : : "r" (r0) > + : "r4", "r5", "r6", "r7", "r8"); > +} > +#endif > + > static inline void cache_wait(void __iomem *reg, unsigned long mask) > { > /* wait for the operation to complete */ > @@ -62,15 +80,33 @@ static void l2x0_inv_range(unsigned long start, unsigned long end) > spin_lock_irqsave(&l2x0_lock, flags); > if (start & (CACHE_LINE_SIZE - 1)) { > start &= ~(CACHE_LINE_SIZE - 1); > +#ifdef CONFIG_PL310_ERRATA_588369 > + debug_writel(0x03); > + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); > + writel(start, base + L2X0_CLEAN_LINE_PA); > + cache_wait(base + L2X0_INV_LINE_PA, 1); > + writel(start, base + L2X0_INV_LINE_PA); > + debug_writel(0x00); > +#else > cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); > writel(start, base + L2X0_CLEAN_INV_LINE_PA); > +#endif > start += CACHE_LINE_SIZE; > } > > if (end & (CACHE_LINE_SIZE - 1)) { > end &= ~(CACHE_LINE_SIZE - 1); > +#ifdef CONFIG_PL310_ERRATA_588369 > + debug_writel(0x03); > + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); > + writel(end, base + L2X0_CLEAN_LINE_PA); > + cache_wait(base + L2X0_INV_LINE_PA, 1); > + writel(end, base + L2X0_INV_LINE_PA); > + debug_writel(0x00); > +#else > cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); > writel(end, base + L2X0_CLEAN_INV_LINE_PA); > +#endif > } > > while (start < end) { > @@ -129,8 +165,17 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) > unsigned long blk_end = start + min(end - start, 4096UL); > > while (start < blk_end) { > +#ifdef CONFIG_PL310_ERRATA_588369 > + debug_writel(0x03); > + /* Clean by PA followed by Invalidate by PA */ > + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); > + writel(start, base + L2X0_CLEAN_LINE_PA); > + cache_wait(base + L2X0_INV_LINE_PA, 1); > + writel(start, base + L2X0_INV_LINE_PA); > +#else > cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); > writel(start, base + L2X0_CLEAN_INV_LINE_PA); > +#endif > start += CACHE_LINE_SIZE; > } > > @@ -139,7 +184,12 @@ static void l2x0_flush_range(unsigned long start, unsigned long end) > spin_lock_irqsave(&l2x0_lock, flags); > } > } > +#ifdef CONFIG_PL310_ERRATA_588369 > + cache_wait(base + L2X0_CLEAN_LINE_PA, 1); > + cache_wait(base + L2X0_INV_LINE_PA, 1); > +#else > cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1); > +#endif > cache_sync(); > spin_unlock_irqrestore(&l2x0_lock, flags); > } > -- > 1.6.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html