TEE-502 imx: refactor optee bindings addition
authorSilvano di Ninno <silvano.dininno@nxp.com>
Wed, 29 Jan 2020 16:52:00 +0000 (17:52 +0100)
committerYe Li <ye.li@nxp.com>
Thu, 29 Apr 2021 07:56:39 +0000 (00:56 -0700)
- Remove code duplication betwee imx8 and imx8m support
- add reserved memory node to prevent Linux accessing optee reserved memory

Signed-off-by: Silvano di Ninno <silvano.dininno@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit 8beac7ef22c16b72ad337b44a0516436a4a0d00c)
(cherry picked from commit 07be6f855bdcbca200e4685ea557b2529187e29f)

arch/arm/include/asm/mach-imx/optee.h [new file with mode: 0644]
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/dt_optee.c [new file with mode: 0644]
arch/arm/mach-imx/imx8/fdt.c
arch/arm/mach-imx/imx8m/soc.c

diff --git a/arch/arm/include/asm/mach-imx/optee.h b/arch/arm/include/asm/mach-imx/optee.h
new file mode 100644 (file)
index 0000000..f13c5a3
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020 NXP
+ */
+#ifndef __IMX_OPTEE_H__
+#define __IMX_OPTEE_H__
+
+#include <common.h>
+
+#define OPTEE_SHM_SIZE 0x00400000
+int ft_add_optee_node(void *fdt, struct bd_info *bd);
+#endif
index d9115c6..12a06e2 100644 (file)
@@ -34,6 +34,9 @@ obj-y += misc.o
 obj-$(CONFIG_CMD_PRIBLOB) += priblob.o
 obj-$(CONFIG_SPL_BUILD)        += spl.o
 endif
+ifeq ($(SOC),$(filter $(SOC),imx8m imx8))
+obj-y  += dt_optee.o
+endif
 ifeq ($(SOC),$(filter $(SOC),mx7))
 obj-y  += cpu.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
diff --git a/arch/arm/mach-imx/dt_optee.c b/arch/arm/mach-imx/dt_optee.c
new file mode 100644 (file)
index 0000000..9e76d17
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ */
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/mach-imx/optee.h>
+#include <errno.h>
+#include <fdt_support.h>
+
+#ifdef CONFIG_OF_SYSTEM_SETUP
+static void set_dt_val(void *data, uint32_t cell_size, uint64_t val)
+{
+       if (cell_size == 1) {
+               fdt32_t v = cpu_to_fdt32((uint32_t)val);
+
+               memcpy(data, &v, sizeof(v));
+       } else {
+               fdt64_t v = cpu_to_fdt64(val);
+
+               memcpy(data, &v, sizeof(v));
+       }
+}
+
+static int add_dt_path_subnode(void *fdt, const char *path, const char *subnode)
+{
+       int offs;
+
+       offs = fdt_path_offset(fdt, path);
+       if (offs < 0)
+               return -1;
+
+       offs = fdt_add_subnode(fdt, offs, subnode);
+       if (offs < 0)
+               return -1;
+       return offs;
+}
+
+static int add_res_mem_dt_node(void *fdt, const char *name, phys_addr_t pa,
+                              size_t size)
+{
+       int offs = 0;
+       int ret = 0;
+       int addr_size = -1;
+       int len_size = -1;
+       bool found = true;
+       char subnode_name[80] = { 0 };
+
+       offs = fdt_path_offset(fdt, "/reserved-memory");
+
+       if (offs < 0) {
+               found = false;
+               offs = 0;
+       }
+
+       len_size = fdt_size_cells(fdt, offs);
+       if (len_size < 0)
+               return -1;
+       addr_size = fdt_address_cells(fdt, offs);
+       if (addr_size < 0)
+               return -1;
+
+       if (!found) {
+               offs = add_dt_path_subnode(fdt, "/", "reserved-memory");
+               if (offs < 0)
+                       return -1;
+
+               ret = fdt_setprop_cell(fdt, offs, "#address-cells", addr_size);
+               if (ret < 0)
+                       return -1;
+               ret = fdt_setprop_cell(fdt, offs, "#size-cells", len_size);
+               if (ret < 0)
+                       return -1;
+               ret = fdt_setprop(fdt, offs, "ranges", NULL, 0);
+               if (ret < 0)
+                       return -1;
+       }
+
+       snprintf(subnode_name, sizeof(subnode_name), "%s@0x%llx", name, pa);
+       offs = fdt_add_subnode(fdt, offs, subnode_name);
+       if (offs >= 0) {
+               u32 data[FDT_MAX_NCELLS * 2];
+
+               set_dt_val(data, addr_size, pa);
+               set_dt_val(data + addr_size, len_size, size);
+               ret = fdt_setprop(fdt, offs, "reg", data,
+                                 sizeof(uint32_t) * (addr_size + len_size));
+               if (ret < 0)
+                       return -1;
+               ret = fdt_setprop(fdt, offs, "no-map", NULL, 0);
+               if (ret < 0)
+                       return -1;
+       } else {
+               return -1;
+       }
+       return 0;
+}
+
+int ft_add_optee_node(void *fdt, struct bd_info *bd)
+{
+       const char *path, *subpath;
+       int ret = 0;
+       int offs;
+       phys_addr_t optee_start;
+       size_t optee_size;
+
+       /*
+        * No TEE space allocated indicating no TEE running, so no
+        * need to add optee node in dts
+        */
+       if (!rom_pointer[1])
+               return 0;
+
+       optee_start = (phys_addr_t)rom_pointer[0];
+       optee_size = rom_pointer[1] - OPTEE_SHM_SIZE;
+
+       offs = fdt_increase_size(fdt, 512);
+       if (offs) {
+               printf("No Space for dtb\n");
+               return -1;
+       }
+
+       path = "/firmware";
+       offs = fdt_path_offset(fdt, path);
+       if (offs < 0) {
+               offs = add_dt_path_subnode(fdt, "/", "firmware");
+               if (offs < 0)
+                       return -1;
+       }
+
+       subpath = "optee";
+       offs = fdt_add_subnode(fdt, offs, subpath);
+       if (offs < 0) {
+               printf("Could not create %s node.\n", subpath);
+               return -1;
+       }
+
+       fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz");
+       fdt_setprop_string(fdt, offs, "method", "smc");
+
+       ret = add_res_mem_dt_node(fdt, "optee_core", optee_start, optee_size);
+       if (ret < 0) {
+               printf("Could not create optee_core node.\n");
+               return -1;
+       }
+
+       ret = add_res_mem_dt_node(fdt, "optee_shm", optee_start + optee_size,
+                                 OPTEE_SHM_SIZE);
+       if (ret < 0) {
+               printf("Could not create optee_shm node.\n");
+               return -1;
+       }
+       return ret;
+}
+#endif
index a84d3fe..a05f3c0 100644 (file)
@@ -8,6 +8,7 @@
 #include <asm/arch/sci/sci.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/global_data.h>
+#include <asm/mach-imx/optee.h>
 #include <dm/ofnode.h>
 #include <fdt_support.h>
 #include <linux/libfdt.h>
@@ -574,56 +575,6 @@ static int config_smmu_fdt(void *blob)
        return 0;
 }
 
-static int ft_add_optee_node(void *fdt, struct bd_info *bd)
-{
-       const char *path, *subpath;
-       int offs;
-
-       /*
-        * No TEE space allocated indicating no TEE running, so no
-        * need to add optee node in dts
-        */
-       if (!boot_pointer[1])
-               return 0;
-
-       offs = fdt_increase_size(fdt, 512);
-       if (offs) {
-               printf("No Space for dtb\n");
-               return 1;
-       }
-
-       path = "/firmware";
-       offs = fdt_path_offset(fdt, path);
-       if (offs < 0) {
-               path = "/";
-               offs = fdt_path_offset(fdt, path);
-
-               if (offs < 0) {
-                       printf("Could not find root node.\n");
-                       return offs;
-               }
-
-               subpath = "firmware";
-               offs = fdt_add_subnode(fdt, offs, subpath);
-               if (offs < 0) {
-                       printf("Could not create %s node.\n", subpath);
-                       return offs;
-               }
-       }
-
-       subpath = "optee";
-       offs = fdt_add_subnode(fdt, offs, subpath);
-       if (offs < 0) {
-               printf("Could not create %s node.\n", subpath);
-               return offs;
-       }
-
-       fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz");
-       fdt_setprop_string(fdt, offs, "method", "smc");
-
-       return 0;
-}
-
 int ft_system_setup(void *blob, struct bd_info *bd)
 {
        int ret;
index a19f3f9..3f25326 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-imx/hab.h>
 #include <asm/mach-imx/boot_mode.h>
+#include <asm/mach-imx/optee.h>
 #include <asm/mach-imx/syscounter.h>
 #include <asm/ptrace.h>
 #include <asm/armv8/mmu.h>
@@ -893,54 +894,6 @@ static int disable_cpu_nodes(void *blob, u32 disabled_cores)
        return 0;
 }
 
-static int ft_add_optee_node(void *fdt, struct bd_info *bd)
-{
-       const char *path, *subpath;
-       int offs;
-
-       /*
-        * No TEE space allocated indicating no TEE running, so no
-        * need to add optee node in dts
-        */
-       if (!rom_pointer[1])
-               return 0;
-
-       offs = fdt_increase_size(fdt, 512);
-       if (offs) {
-               printf("No Space for dtb\n");
-               return 1;
-       }
-
-       path = "/firmware";
-       offs = fdt_path_offset(fdt, path);
-       if (offs < 0) {
-               path = "/";
-               offs = fdt_path_offset(fdt, path);
-
-               if (offs < 0) {
-                       printf("Could not find root node.\n");
-                       return 1;
-               }
-
-               subpath = "firmware";
-               offs = fdt_add_subnode(fdt, offs, subpath);
-               if (offs < 0) {
-                       printf("Could not create %s node.\n", subpath);
-               }
-       }
-
-       subpath = "optee";
-       offs = fdt_add_subnode(fdt, offs, subpath);
-       if (offs < 0) {
-               printf("Could not create %s node.\n", subpath);
-       }
-
-       fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz");
-       fdt_setprop_string(fdt, offs, "method", "smc");
-
-       return 0;
-}
-
 int ft_system_setup(void *blob, struct bd_info *bd)
 {
 #ifdef CONFIG_IMX8MQ