[PATCH 1/2] mach-ux500: cache operations are atomic on PL310

Will Deacon will.deacon at arm.com
Tue Jan 17 05:30:23 EST 2012


Hi Srinidhi,

On Tue, Jan 17, 2012 at 06:22:26AM +0000, Srinidhi KASAGAR wrote:
> On Mon, Jan 16, 2012 at 15:50:08 +0100, Will Deacon wrote:
> > The lock needs to stay. Besides, the problem isn't with inv_all, the problem
> > is with not being able to disable the outer cache. So can't you just do
> > something nasty like:
> > 
> > 	outer_cache.disable = NULL;
> > 
> > after your call to l2x0_init?
> 
> hmm..patch below

Thanks. Comments inline.

> > 
> > Also, if you can't disable the L2 from non-secure, does that mean that you
> > boot Linux with the L2 enabled?
> 
> Yes, we boot with L2 enabled.

Interesting. I'm surprised you don't have problems with stale data on the
D-side after the decompressor. Maybe you're lucky with the mappings being no
write allocate.

> From 46fdbda7d2d9a9f4df0933341bcc467b3bdd03d6 Mon Sep 17 00:00:00 2001
> From: srinidhi kasagar <srinidhi.kasagar at stericsson.com>
> Date: Tue, 17 Jan 2012 11:29:39 +0530
> Subject: [PATCH] mach-ux500: Do not override outer.inv_all
> 
> outer.inv_all is currently being used only in kexec path.
> Invalidating outer cache without disabling it is a big
> nono, and so, remove the machine specific outer.inv_all
> assuming that kexec does not call inv_all in its path.

Please change this comment. Kexec doesn't do this anymore.

> And at the same time it does not prevent us overriding
> outer.disable as we do not have any such secure SMI to
> handle the same while kexec disables the outer cache.
> 
> Signed-off-by: srinidhi kasagar <srinidhi.kasagar at stericsson.com>
> ---
>  arch/arm/mach-ux500/cache-l2x0.c |   48 +++++--------------------------------
>  1 files changed, 7 insertions(+), 41 deletions(-)
> 
> diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
> index 122ddde..45111c8 100644
> --- a/arch/arm/mach-ux500/cache-l2x0.c
> +++ b/arch/arm/mach-ux500/cache-l2x0.c
> @@ -12,44 +12,6 @@
>  
>  static void __iomem *l2x0_base;
>  
> -static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
> -{
> -	/* wait for the operation to complete */
> -	while (readl_relaxed(reg) & mask)
> -		cpu_relax();
> -}
> -
> -static inline void ux500_cache_sync(void)
> -{
> -	writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC);
> -	ux500_cache_wait(l2x0_base + L2X0_CACHE_SYNC, 1);
> -}
> -
> -/*
> - * The L2 cache cannot be turned off in the non-secure world.
> - * Dummy until a secure service is in place.
> - */
> -static void ux500_l2x0_disable(void)
> -{
> -}
> -
> -/*
> - * This is only called when doing a kexec, just after turning off the L2
> - * and L1 cache, and it is surrounded by a spinlock in the generic version.
> - * However, we're not really turning off the L2 cache right now and the
> - * PL310 does not support exclusive accesses (used to implement the spinlock).
> - * So, the invalidation needs to be done without the spinlock.
> - */
> -static void ux500_l2x0_inv_all(void)
> -{
> -	uint32_t l2x0_way_mask = (1<<16) - 1;	/* Bitmask of active ways */
> -
> -	/* invalidate all ways */
> -	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
> -	ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
> -	ux500_cache_sync();
> -}
> -
>  static int __init ux500_l2x0_unlock(void)
>  {
>  	int i;
> @@ -85,9 +47,13 @@ static int __init ux500_l2x0_init(void)
>  	/* 64KB way size, 8 way associativity, force WA */
>  	l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
>  
> -	/* Override invalidate function */
> -	outer_cache.disable = ux500_l2x0_disable;
> -	outer_cache.inv_all = ux500_l2x0_inv_all;
> +	/*
> +	 * We can't disable l2 as we are in non secure mode, currently
> +	 * this seems being called only during kexec path. So let's
> +	 * override outer.disable with nasty assignment until we have
> +	 * some SMI service available.
> +	 */
> +	outer_cache.disable = NULL;

Much better!

Cheers,

Will



More information about the linux-arm-kernel mailing list