[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