Skip to contentSkip to conversation

ARM: cache-l2x0: add setup entry for l2 in non-secure mode

RFC PATCH In review Gioh Kim 2 participants 5 messages May 15, 2014 – May 19, 2014 Arm (32-bit)

lore
Share & tools
lore

Gioh Kim

author
#0 lore raw

RFC PATCH 1/1 ARM: cache-l2x0: add setup entry for l2 in non-secure mode

Hi,

My board is using Trustzone and running kernel is non-secure mode. But setup function of PL310 driver is only for secure mode kernel.

What about adding an entry for non-secure mode setup function?

I'm sorry for my poor code but I just wanna say what I need .

------------------------------ 8< -------------------------------

Quoted 1 line

From ee4b03fb2c12038c6bbb9f752558abae8d500c07 Mon Sep 17 00:00:00 2001

From: Gioh Kim <[email protected]>
Date: Thu, 15 May 2014 14:06:36 +0900
Subject: [PATCH] ARM: cache-l2x0: add setup entry for l2 in non-secure mode

For some platforms using Trustzone and running kernel in non-secure mode, another l2 setup function is necessary.

---
 arch/arm/include/asm/hardware/cache-l2x0.h |    9 +++++++++
 arch/arm/mm/cache-l2x0.c                   |   26 +++++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)
arch/arm/include/asm/hardware/cache-l2x0.h +9 -0
index 6dec6da..de31114 100644
@@ -21,6 +21,7 @@
 #define __ASM_ARM_HARDWARE_L2X0_H
 
 #include <linux/errno.h>
+#include <linux/of.h>
 
 #define L2X0_CACHE_ID                  0x000
 #define L2X0_CACHE_TYPE                        0x004
@@ -110,11 +111,19 @@
 extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
 #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
 extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
+extern int l2x0_of_set_setup_nonsecure(const char *compatible, size_t len,
+                       void (*fp)(const struct device_node *, u32 *, u32 *));
 #else
 static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
        return -ENODEV;
 }
+static inline int l2x0_of_set_setup_nonsecure(const char *compatible,
+                                             size_t len,
+                     void (*fp)(const struct device_node *, u32 *, u32 *))
+{
+       return -ENODEV;
+}
 #endif
 
 struct l2x0_regs {
arch/arm/mm/cache-l2x0.c +25 -1
index 728d644..582ea37 100644
@@ -45,6 +45,7 @@ struct l2x0_regs l2x0_saved_regs;
 struct l2x0_of_data {
        void (*setup)(const struct device_node *, u32 *, u32 *);
        void (*save)(void);
+       void (*setup_nonsecure)(const struct device_node *, u32 *, u32 *);
        struct outer_cache_fns outer_cache;
 };
 
@@ -968,6 +969,23 @@ static const struct of_device_id l2x0_ids[] __initconst = {
        {}
 };
 
+int l2x0_of_set_setup_nonsecure(const char *compatible, size_t len,
+                       void (*fp)(const struct device_node *, u32 *, u32 *))
+{
+       const struct of_device_id *id;
+
+       for (id = &l2x0_ids[0]; id->compatible != NULL; id++) {
+               if (strncmp(id->compatible, compatible, len) == 0) {
+                       struct l2x0_of_data *data = id->data;
+
+                       data->setup_nonsecure = fp;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
 int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
        struct device_node *np;
@@ -989,8 +1007,14 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
        /* L2 configuration can only be changed if the cache is disabled */
        if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-               if (data->setup)
+
+               if (data->setup_nonsecure)
+                       data->setup_nonsecure(np, &aux_val, &aux_mask);
+               else if (data->setup)
                        data->setup(np, &aux_val, &aux_mask);
+               else
+                       /* no function to enable cache */
+                       return -ENODEV;
 
                /* For aurora cache in no outer mode select the
                 * correct mode using the coprocessor*/

--
1.7.9.5

#1 lore raw

2014-05-15 13:39 GMT+08:00 Gioh Kim <[email protected]>:

Quoted 9 lines

Hi,

My board is using Trustzone and running kernel is non-secure mode. But setup function of PL310 driver is only for secure mode kernel.

What about adding an entry for non-secure mode setup function?

I'm sorry for my poor code but I just wanna say what I need .

Gioh,

i don't really understand what is the user scenarios for this, if you are running linux in non-secure mode, your security-mode codes have enabled L2, so this makes non-secure linux have no chance to execute setup at all:
992 /* L2 configuration can only be changed if the cache is disabled */
993 if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
994 if (data->setup)
995 data->setup(np, &aux_val, &aux_mask);

anyway, cache-l2x0.c supported non-secure linux as you can read:
387 /*

 388          * Check if l2x0 controller is already enabled.
 389          * If you are booting from non-secure mode
 390          * accessing the below registers will fault.
 391          */

392 if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
393 /* Make sure that I&D is not locked down when starting */
394 l2x0_unlock(cache_id);
395
396 /* l2x0 controller is disabled */
397 writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
398
399 l2x0_inv_all();
400
401 /* enable L2X0 */
402 writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
403 }

Quoted 101 lines

------------------------------ 8< ------------------------------- From ee4b03fb2c12038c6bbb9f752558abae8d500c07 Mon Sep 17 00:00:00 2001
From: Gioh Kim <[email protected]>
Date: Thu, 15 May 2014 14:06:36 +0900
Subject: [PATCH] ARM: cache-l2x0: add setup entry for l2 in non-secure mode

For some platforms using Trustzone and running kernel in non-secure mode, another l2 setup function is necessary.

---
 arch/arm/include/asm/hardware/cache-l2x0.h |    9 +++++++++
 arch/arm/mm/cache-l2x0.c                   |   26 +++++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)
arch/arm/include/asm/hardware/cache-l2x0.h +9 -0
index 6dec6da..de31114 100644
@@ -21,6 +21,7 @@
 #define __ASM_ARM_HARDWARE_L2X0_H
 
 #include <linux/errno.h>
+#include <linux/of.h>
 
 #define L2X0_CACHE_ID                  0x000
 #define L2X0_CACHE_TYPE                        0x004
@@ -110,11 +111,19 @@
 extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
 #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
 extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
+extern int l2x0_of_set_setup_nonsecure(const char *compatible, size_t len,
+                       void (*fp)(const struct device_node *, u32 *, u32 *));
 #else
 static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
        return -ENODEV;
 }
+static inline int l2x0_of_set_setup_nonsecure(const char *compatible,
+                                             size_t len,
+                     void (*fp)(const struct device_node *, u32 *, u32 *))
+{
+       return -ENODEV;
+}
 #endif
 
 struct l2x0_regs {
arch/arm/mm/cache-l2x0.c +25 -2
index 728d644..582ea37 100644
@@ -45,6 +45,7 @@ struct l2x0_regs l2x0_saved_regs;
 struct l2x0_of_data {
        void (*setup)(const struct device_node *, u32 *, u32 *);
        void (*save)(void);
+       void (*setup_nonsecure)(const struct device_node *, u32 *, u32 *);
        struct outer_cache_fns outer_cache;
 };
 
@@ -968,6 +969,23 @@ static const struct of_device_id l2x0_ids[] __initconst = {
        {}
 };
 
+int l2x0_of_set_setup_nonsecure(const char *compatible, size_t len,
+                       void (*fp)(const struct device_node *, u32 *, u32 *))
+{
+       const struct of_device_id *id;
+
+       for (id = &l2x0_ids[0]; id->compatible != NULL; id++) {
+               if (strncmp(id->compatible, compatible, len) == 0) {
+                       struct l2x0_of_data *data = id->data;
+
+                       data->setup_nonsecure = fp;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
 int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
        struct device_node *np;
@@ -989,8 +1007,14 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
        /* L2 configuration can only be changed if the cache is disabled */
        if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-               if (data->setup)
+
+               if (data->setup_nonsecure)
+                       data->setup_nonsecure(np, &aux_val, &aux_mask);
+               else if (data->setup)
                        data->setup(np, &aux_val, &aux_mask);
+               else
+                       /* no function to enable cache */
+                       return -ENODEV;
 
                /* For aurora cache in no outer mode select the
                 * correct mode using the coprocessor*/
--
Quoted 1 line

1.7.9.5

-barry

author
#2 lore raw

2014-05-18 ?? 10:13, Barry Song ? ?:

Quoted 9 lines

2014-05-15 13:39 GMT+08:00 Gioh Kim <[email protected]>:

Quoted 8 lines

Hi,

My board is using Trustzone and running kernel is non-secure mode. But setup function of PL310 driver is only for secure mode kernel.

What about adding an entry for non-secure mode setup function?

Quoted 8 lines
Quoted 1 line

I'm sorry for my poor code but I just wanna say what I need .

Gioh,

i don't really understand what is the user scenarios for this, if you are running linux in non-secure mode, your security-mode codes have enabled L2, so this makes non-secure linux have no chance to execute setup at all:

My platform runs linux kernel before L2 cache activation.
And the L2 cache is activated when the kernel sends command to Trustzone firmware.
At this moment L2 is not activated. Linux should send command for L2 activation to Trustzone at the moment.

Quoted 6 lines
  992         /* L2 configuration can only be changed if the cache is disabled */
  993         if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  994                 if (data->setup)
  995                         data->setup(np, &aux_val, &aux_mask);

anyway, cache-l2x0.c supported non-secure linux as you can read:

If non-secure linux try to access l2x0 register, it would generate fault. If L2 is not activated at l2x0_of_init, follow code can generate fault. So the L2 should be activated before the follow code.

Quoted 126 lines
  387         /*
  388          * Check if l2x0 controller is already enabled.
  389          * If you are booting from non-secure mode
  390          * accessing the below registers will fault.
  391          */
  392         if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
  393                 /* Make sure that I&D is not locked down when starting */
  394                 l2x0_unlock(cache_id);
  395
  396                 /* l2x0 controller is disabled */
  397                 writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
  398
  399                 l2x0_inv_all();
  400
  401                 /* enable L2X0 */
  402                 writel_relaxed(L2X0_CTRL_EN, l2x0_base + L2X0_CTRL);
  403         }
Quoted 101 lines

------------------------------ 8< -------------------------------
From ee4b03fb2c12038c6bbb9f752558abae8d500c07 Mon Sep 17 00:00:00 2001
From: Gioh Kim <[email protected]>
Date: Thu, 15 May 2014 14:06:36 +0900
Subject: [PATCH] ARM: cache-l2x0: add setup entry for l2 in non-secure mode

For some platforms using Trustzone and running kernel in non-secure mode, another l2 setup function is necessary.

---
  arch/arm/include/asm/hardware/cache-l2x0.h |    9 +++++++++
  arch/arm/mm/cache-l2x0.c                   |   26 +++++++++++++++++++++++++-
  2 files changed, 34 insertions(+), 1 deletion(-)
arch/arm/include/asm/hardware/cache-l2x0.h +9 -0
index 6dec6da..de31114 100644
@@ -21,6 +21,7 @@
  #define __ASM_ARM_HARDWARE_L2X0_H
 
  #include <linux/errno.h>
+#include <linux/of.h>
 
  #define L2X0_CACHE_ID                  0x000
  #define L2X0_CACHE_TYPE                        0x004
@@ -110,11 +111,19 @@
  extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
  #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
  extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
+extern int l2x0_of_set_setup_nonsecure(const char *compatible, size_t len,
+                       void (*fp)(const struct device_node *, u32 *, u32 *));
  #else
  static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
  {
         return -ENODEV;
  }
+static inline int l2x0_of_set_setup_nonsecure(const char *compatible,
+                                             size_t len,
+                     void (*fp)(const struct device_node *, u32 *, u32 *))
+{
+       return -ENODEV;
+}
  #endif
 
  struct l2x0_regs {
arch/arm/mm/cache-l2x0.c +25 -2
index 728d644..582ea37 100644
@@ -45,6 +45,7 @@ struct l2x0_regs l2x0_saved_regs;
  struct l2x0_of_data {
         void (*setup)(const struct device_node *, u32 *, u32 *);
         void (*save)(void);
+       void (*setup_nonsecure)(const struct device_node *, u32 *, u32 *);
         struct outer_cache_fns outer_cache;
  };
 
@@ -968,6 +969,23 @@ static const struct of_device_id l2x0_ids[] __initconst = {
         {}
  };
 
+int l2x0_of_set_setup_nonsecure(const char *compatible, size_t len,
+                       void (*fp)(const struct device_node *, u32 *, u32 *))
+{
+       const struct of_device_id *id;
+
+       for (id = &l2x0_ids[0]; id->compatible != NULL; id++) {
+               if (strncmp(id->compatible, compatible, len) == 0) {
+                       struct l2x0_of_data *data = id->data;
+
+                       data->setup_nonsecure = fp;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
  int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
  {
         struct device_node *np;
@@ -989,8 +1007,14 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 
         /* L2 configuration can only be changed if the cache is disabled */
         if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN)) {
-               if (data->setup)
+
+               if (data->setup_nonsecure)
+                       data->setup_nonsecure(np, &aux_val, &aux_mask);
+               else if (data->setup)
                         data->setup(np, &aux_val, &aux_mask);
+               else
+                       /* no function to enable cache */
+                       return -ENODEV;
 
                 /* For aurora cache in no outer mode select the
                  * correct mode using the coprocessor*/
--
Quoted 1 line

1.7.9.5

-barry

#3 lore raw

2014-05-19 8:29 GMT+08:00 Gioh Kim <[email protected]>:

Quoted 25 lines

2014-05-18 ?? 10:13, Barry Song ? ?:

Quoted 13 lines

2014-05-15 13:39 GMT+08:00 Gioh Kim <[email protected]>:

Quoted 10 lines

Hi,

My board is using Trustzone and running kernel is non-secure mode. But setup function of PL310 driver is only for secure mode kernel.

What about adding an entry for non-secure mode setup function?

I'm sorry for my poor code but I just wanna say what I need .

Quoted 6 lines

Gioh,

i don't really understand what is the user scenarios for this, if you are running linux in non-secure mode, your security-mode codes have enabled L2, so this makes non-secure linux have no chance to execute setup at all:

Quoted 5 lines

My platform runs linux kernel before L2 cache activation. And the L2 cache is activated when the kernel sends command to Trustzone firmware.
At this moment L2 is not activated. Linux should send command for L2 activation to Trustzone at the moment.

i think you can send command to trustzone firmware to enable L2 at first, then make your Linux l2 driver run.

-barry

author
#4 lore raw

2014-05-19 ?? 6:11, Barry Song ? ?:

Quoted 26 lines

2014-05-19 8:29 GMT+08:00 Gioh Kim <[email protected]>:

Quoted 25 lines

2014-05-18 ?? 10:13, Barry Song ? ?:

Quoted 19 lines

2014-05-15 13:39 GMT+08:00 Gioh Kim <[email protected]>:

Quoted 10 lines

Hi,

My board is using Trustzone and running kernel is non-secure mode. But setup function of PL310 driver is only for secure mode kernel.

What about adding an entry for non-secure mode setup function?

I'm sorry for my poor code but I just wanna say what I need .

Gioh,

i don't really understand what is the user scenarios for this, if you are running linux in non-secure mode, your security-mode codes have enabled L2, so this makes non-secure linux have no chance to execute setup at all:

Quoted 8 lines
Quoted 5 lines

My platform runs linux kernel before L2 cache activation. And the L2 cache is activated when the kernel sends command to Trustzone firmware.
At this moment L2 is not activated. Linux should send command for L2 activation to Trustzone at the moment.

i think you can send command to trustzone firmware to enable L2 at first, then make your Linux l2 driver run.

Right. My platform is working like that.
Activate L2 first and run l2x0 driver.

But I think many platforms have trustzone firmware and are working like my platform. They might need non-secure setup.

Quoted 9 lines

-barry
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/