security: arm: meson: add tee support [2/2]
authorPeifu Jiang <peifu.jiang@amlogic.com>
Wed, 24 May 2017 10:34:15 +0000 (18:34 +0800)
committerVictor Wan <victor.wan@amlogic.com>
Thu, 1 Jun 2017 11:59:35 +0000 (04:59 -0700)
PD#145094: security: arm: meson: add tee support

Change-Id: I8789ef2b6d774abb6252e60c0726e7384127339f
Signed-off-by: Peifu Jiang <peifu.jiang@amlogic.com>
12 files changed:
MAINTAINERS
arch/arm/boot/dts/amlogic/meson8b_m200.dts
arch/arm/boot/dts/amlogic/meson8b_m400.dts
arch/arm/mach-meson/Makefile
arch/arm/mach-meson/meson-secure.c [new file with mode: 0644]
arch/arm/mach-meson/meson-smc.S [new file with mode: 0644]
arch/arm/mach-meson/meson.c
arch/arm/mach-meson/platsmp.c
drivers/amlogic/cpu_version/meson32_cpu.c
drivers/amlogic/efuse/efuse_hw.c
drivers/amlogic/jtag/meson_jtag.c
include/linux/amlogic/meson-secure.h [new file with mode: 0644]

index aa6783e..46d24af 100644 (file)
@@ -13925,3 +13925,8 @@ F: sound/soc/amlogic/auge/*
 F: sound/soc/codecs/amlogic/*
 F: include/dt-bindings/clock/amlogic,axg-audio-clk.h
 
+AMLOGIC Security Support
+M: Peifu Jiang <peifu.jiang@amlogic.com>
+F: include/linux/amlogic/meson-secure.h
+F: arch/arm/mach-meson/meson-smc.S
+F: arch/arm/mach-meson/meson-secure.c
\ No newline at end of file
index e29004a..72b4f68 100644 (file)
                        compatible = "amlogic, pm-m8b-reserve";
                        reg = <0x04f00000 0x100000>;
                };
+
+               secos_reserved:linux,secos {
+                       status = "disabled";
+                       compatible = "amlogic, aml_secos_memory";
+                       reg = <0x06100000 0x3000000>;
+                       no-map;
+               };
        };
 
        bt-dev{
index f35b9b1..534d193 100644 (file)
                        compatible = "amlogic, pm-m8b-reserve";
                        reg = <0x04f00000 0x100000>;
                };
+
+               secos_reserved:linux,secos {
+                       status = "disabled";
+                       compatible = "amlogic, aml_secos_memory";
+                       reg = <0x06100000 0x3000000>;
+                       no-map;
+               };
        };
 
        sdio {
index fe8345d..99732ca 100644 (file)
@@ -1,3 +1,5 @@
 obj-$(CONFIG_ARCH_MESON) += meson.o
+obj-$(CONFIG_ARCH_MESON) += meson-smc.o
+obj-$(CONFIG_ARCH_MESON) += meson-secure.o
 
 obj-$(CONFIG_SMP)       += platsmp.o headsmp.o hotplug-asm.o
diff --git a/arch/arm/mach-meson/meson-secure.c b/arch/arm/mach-meson/meson-secure.c
new file mode 100644 (file)
index 0000000..d47b458
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2014-2017 Amlogic, Inc. All rights reserved.
+ *
+ * All information contained herein is Amlogic confidential.
+ *
+ * This software is provided to you pursuant to Software License Agreement
+ * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
+ * only in accordance with the terms of this agreement.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is strictly prohibited without prior written permission from
+ * Amlogic.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/string.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/sched.h>
+#include <linux/amlogic/meson-secure.h>
+
+#define MESON_SECURE_DEBUG 0
+#if MESON_SECURE_DEBUG
+#undef pr_fmt
+#define pr_fmt(fmt) "meson-secure: " fmt
+#define TZDBG(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
+#else
+#define TZDBG(fmt, ...)
+#endif
+
+#define MESON_SECURE_FLAG_REG                 0xC11081F0
+#define MESON_SECURE_FLAG_VALUE_DISABLED      0x0
+#define MESON_SECURE_FLAG_VALUE_ENABLED       0x1
+#define MESON_SECURE_FLAG_VALUE_INVALID       0xFFFFFFFF
+
+static uint32_t secure_flag = MESON_SECURE_FLAG_VALUE_INVALID;
+static void __iomem *secure_flag_base;
+
+/* check secure status
+ *
+ * return value:
+ *   true: secure enabled
+ *  false: secure disabled
+ */
+bool meson_secure_enabled(void)
+{
+       bool ret = false;
+
+       if (secure_flag == MESON_SECURE_FLAG_VALUE_INVALID) {
+               secure_flag_base = ioremap(MESON_SECURE_FLAG_REG, 4);
+               if (!secure_flag_base) {
+                       TZDBG("iomap(0x%x) error.", MESON_SECURE_FLAG_REG);
+                       return false;
+               }
+               secure_flag = readl_relaxed(secure_flag_base);
+       }
+
+       TZDBG("secure_flag: 0x%x\n", secure_flag);
+       switch (secure_flag) {
+       case MESON_SECURE_FLAG_VALUE_ENABLED:
+               ret = true;
+               break;
+       case MESON_SECURE_FLAG_VALUE_DISABLED:
+               ret = false;
+               break;
+       case MESON_SECURE_FLAG_VALUE_INVALID:
+               ret = false;
+               break;
+
+       default:
+               ret = false;
+               break;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(meson_secure_enabled);
+
+uint32_t meson_secure_reg_read(uint32_t addr)
+{
+       uint32_t ret;
+       uint32_t paddr;
+       int offset;
+
+       offset = 0;//IO_SECBUS_PHY_BASE - IO_SECBUS_BASE;
+       paddr = addr + offset;
+       ret = meson_smc2(paddr);
+       TZDBG("end call smc2, read [0x%x]=%x\n", paddr, ret);
+
+       return ret;
+}
+
+uint32_t meson_secure_reg_write(uint32_t addr, uint32_t val)
+{
+       uint32_t ret;
+       uint32_t paddr;
+       int offset;
+
+       offset = 0;//IO_SECBUS_PHY_BASE - IO_SECBUS_BASE;
+       paddr = addr + offset;
+       ret = meson_smc3(paddr, val);
+       TZDBG("end call smc3, write [0x%x 0x%x]=%x\n", paddr, val, ret);
+
+       return ret;
+}
+
+uint32_t meson_secure_mem_base_start(void)
+{
+       return meson_smc1(TRUSTZONE_MON_MEM_BASE, 0);
+}
+
+uint32_t meson_secure_mem_total_size(void)
+{
+       return meson_smc1(TRUSTZONE_MON_MEM_TOTAL_SIZE, 0);
+}
+
+uint32_t meson_secure_mem_flash_start(void)
+{
+       return meson_smc1(TRUSTZONE_MON_MEM_FLASH, 0);
+}
+
+uint32_t meson_secure_mem_flash_size(void)
+{
+       return meson_smc1(TRUSTZONE_MON_MEM_FLASH_SIZE, 0);
+}
+
+int32_t meson_secure_mem_ge2d_access(uint32_t msec)
+{
+       int ret = -1;
+
+       set_cpus_allowed_ptr(current, cpumask_of(0));
+       ret = meson_smc_hal_api(TRUSTZONE_HAL_API_MEMCONFIG_GE2D, msec);
+       set_cpus_allowed_ptr(current, cpu_all_mask);
+
+       return ret;
+}
+EXPORT_SYMBOL(meson_secure_jtag_disable);
+
+uint32_t meson_secure_jtag_disable(void)
+{
+       return meson_smc1(TRUSTZONE_MON_JTAG_DISABLE, 0);
+}
+
+uint32_t meson_secure_jtag_apao(void)
+{
+       return meson_smc1(TRUSTZONE_MON_JTAG_APAO, 0);
+}
+EXPORT_SYMBOL(meson_secure_jtag_apao);
+
+uint32_t meson_secure_jtag_apee(void)
+{
+       return meson_smc1(TRUSTZONE_MON_JTAG_APEE, 0);
+}
+EXPORT_SYMBOL(meson_secure_jtag_apee);
+
+int meson_trustzone_efuse(void *arg)
+{
+       int ret;
+
+       if (!arg)
+               return -1;
+
+       set_cpus_allowed_ptr(current, cpumask_of(0));
+
+       ret = meson_smc_hal_api(TRUSTZONE_HAL_API_EFUSE, __pa(arg));
+
+       set_cpus_allowed_ptr(current, cpu_all_mask);
+
+       return ret;
+}
+EXPORT_SYMBOL(meson_trustzone_efuse);
diff --git a/arch/arm/mach-meson/meson-smc.S b/arch/arm/mach-meson/meson-smc.S
new file mode 100644 (file)
index 0000000..bc5d54e
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014-2017 Amlogic, Inc. All rights reserved.
+ *
+ * All information contained herein is Amlogic confidential.
+ *
+ * This software is provided to you pursuant to Software License Agreement
+ * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
+ * only in accordance with the terms of this agreement.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is strictly prohibited without prior written permission from
+ * Amlogic.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/linkage.h>
+#include <linux/amlogic/meson-secure.h>
+
+.arch_extension sec
+
+ENTRY(meson_smc1)
+       stmfd sp!, {r2-r12, lr}
+       mov r2, r1
+       mov r1, r0
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_smc1)
+
+ENTRY(meson_smc_hal_api)
+       stmfd sp!, {r3-r12, lr}
+       mov r2, r1
+       mov r1, r0
+       ldr r0, =CALL_TRUSTZONE_HAL_API
+       dsb
+       smc #0
+       ldmfd sp!, {r3-r12, pc}
+ENDPROC(meson_smc_hal_api)
+
+ENTRY(meson_smc2)
+       stmfd sp!, {r2-r12, lr}
+       mov r1, r0
+       ldr r0, =0x2
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_smc2)
+
+ENTRY(meson_smc3)
+       stmfd sp!, {r2-r12, lr}
+       mov r2, r1
+       mov r1, r0
+       ldr r0, =0x3
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_smc3)
+
+ENTRY(meson_read_corectrl)
+       stmfd sp!, {r2-r12, lr}
+       ldr r1, =TRUSTZONE_MON_CORE_RD_CTRL_INDEX
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_read_corectrl)
+
+ENTRY(meson_modify_corectrl)
+       stmfd sp!, {r2-r12, lr}
+       mov r2, r0
+       ldr r1, =TRUSTZONE_MON_CORE_WR_CTRL_INDEX
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_modify_corectrl)
+
+ENTRY(meson_read_corestatus)
+       stmfd sp!, {r2-r12, lr}
+       ldr r1, =TRUSTZONE_MON_CORE_RD_STATUS0_INDEX
+       add r1, r1, r0, lsl #1
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_read_corestatus)
+
+ENTRY(meson_modify_corestatus)
+       stmfd sp!, {r2-r12, lr}
+       mov r2, r1
+       ldr r1, =TRUSTZONE_MON_CORE_WR_STATUS0_INDEX
+       add r1, r1, r0, lsl #1
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_modify_corestatus)
+
+ENTRY(meson_auxcoreboot_addr)
+       stmfd sp!, {r2-r12, lr}
+       mov r3, r1
+       mov r2, r0
+       ldr r1, =TRUSTZONE_MON_CORE_BOOTADDR_INDEX
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_auxcoreboot_addr)
+
+ENTRY(meson_suspend_firmware)
+       stmfd sp!, {r2-r12, lr}
+       mov r2, r0
+       ldr r1, =TRUSTZONE_MON_SUSPNED_FIRMWARE
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_suspend_firmware)
+
+ENTRY(meson_read_socrev1)
+       stmfd sp!, {r2-r12, lr}
+       ldr r1, =TRUSTZONE_MON_CORE_RD_SOC_REV1
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_read_socrev1)
+
+ENTRY(meson_read_socrev2)
+       stmfd sp!, {r2-r12, lr}
+       ldr r1, =TRUSTZONE_MON_CORE_RD_SOC_REV2
+       ldr r0, =CALL_TRUSTZONE_MON
+       dsb
+       smc #0
+       ldmfd sp!, {r2-r12, pc}
+ENDPROC(meson_read_socrev2)
index 1778a18..ab814ed 100644 (file)
@@ -19,6 +19,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <linux/amlogic/pm.h>
+#include <linux/amlogic/meson-secure.h>
+#include <asm/hardware/cache-l2x0.h>
 
 static const char * const meson_common_board_compat[] = {
        "amlogic,meson6",
@@ -46,10 +48,61 @@ static void __init meson_map_io(void)
 }
 #endif
 
+static void meson_l2c310_write_sec(unsigned long val, unsigned int reg)
+{
+#define MESON_L2C310_BASE_REG 0xc4200000
+       static void __iomem *l2x0_base;
+
+       if (!meson_secure_enabled()) {
+               if (!l2x0_base)
+                       l2x0_base = ioremap(MESON_L2C310_BASE_REG, 0x1000);
+
+               if (l2x0_base)
+                       writel_relaxed(val, (l2x0_base + reg));
+
+               return;
+       }
+
+       switch (reg) {
+       case L2X0_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_CTRL_INDEX, val);
+               break;
+       case L2X0_AUX_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_AUXCTRL_INDEX, val);
+               break;
+       case L2X0_DEBUG_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_DEBUG_INDEX, val);
+               break;
+       case L310_TAG_LATENCY_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_TAGLATENCY_INDEX, val);
+               break;
+       case L310_DATA_LATENCY_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_DATALATENCY_INDEX, val);
+               break;
+       case L310_ADDR_FILTER_START:
+               meson_smc1(TRUSTZONE_MON_L2X0_FILTERSTART_INDEX, val);
+               break;
+       case L310_ADDR_FILTER_END:
+               meson_smc1(TRUSTZONE_MON_L2X0_FILTEREND_INDEX, val);
+               break;
+       case L310_PREFETCH_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_PREFETCH_INDEX, val);
+               break;
+       case L310_POWER_CTRL:
+               meson_smc1(TRUSTZONE_MON_L2X0_POWER_INDEX, val);
+               break;
+
+       default:
+               WARN_ONCE(1, "Meson L2C310: ignoring write to reg 0x%x\n", reg);
+               break;
+       }
+}
+
 DT_MACHINE_START(MESON, "Amlogic Meson platform")
        .dt_compat      = meson_common_board_compat,
        .l2c_aux_val    = 0,
        .l2c_aux_mask   = ~0,
+       .l2c_write_sec  = meson_l2c310_write_sec,
 #ifdef CONFIG_AMLOGIC_M8B_SUSPEND
        .map_io         = meson_map_io,
 #endif
index ee6e112..554b295 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
 #include <asm/cp15.h>
+#include <linux/amlogic/meson-secure.h>
 
 static DEFINE_SPINLOCK(boot_lock);
 static DEFINE_SPINLOCK(clockfw_lock);
@@ -47,42 +48,39 @@ void meson_set_cpu_ctrl_addr(uint32_t cpu, const uint32_t addr)
 {
        spin_lock(&clockfw_lock);
 
-#ifdef CONFIG_MESON_TRUSTZONE
-       meson_auxcoreboot_addr(cpu, addr);
-#else
-       writel(addr, (void *)(CPU1_CONTROL_ADDR_REG + ((cpu-1) << 2)));
-#endif
+       if (meson_secure_enabled())
+               meson_auxcoreboot_addr(cpu, addr);
+       else
+               writel(addr, (void *)(CPU1_CONTROL_ADDR_REG + ((cpu-1) << 2)));
+
        spin_unlock(&clockfw_lock);
 }
 
 void meson_set_cpu_ctrl_reg(int cpu, int is_on)
 {
-#ifdef CONFIG_MESON_TRUSTZONE
        uint32_t value = 0;
-#endif
+
        spin_lock(&clockfw_lock);
 
-#ifdef CONFIG_MESON_TRUSTZONE
-       value = meson_read_corectrl();
-       value = (value & ~(1U << cpu)) | (is_on << cpu);
-       value |= 1;
-       meson_modify_corectrl(value);
-#else
-       aml_set_reg32_bits(CPU_CONTROL_REG, is_on, cpu, 1);
-       aml_set_reg32_bits(CPU_CONTROL_REG, 1, 0, 1);
-#endif
+       if (meson_secure_enabled()) {
+               value = meson_read_corectrl();
+               value = (value & ~(1U << cpu)) | (is_on << cpu);
+               value |= 1;
+               meson_modify_corectrl(value);
+       } else {
+               aml_set_reg32_bits(CPU_CONTROL_REG, is_on, cpu, 1);
+               aml_set_reg32_bits(CPU_CONTROL_REG, 1, 0, 1);
+       }
 
        spin_unlock(&clockfw_lock);
 }
 
 int meson_get_cpu_ctrl_addr(int cpu)
 {
-#ifdef CONFIG_MESON_TRUSTZONE
-       return 0;
-#else
-       return readl((void *)(CPU1_CONTROL_ADDR_REG + ((cpu-1) << 2)));
-#endif
-
+       if (meson_secure_enabled())
+               return 0;
+       else
+               return readl((void *)(CPU1_CONTROL_ADDR_REG + ((cpu-1) << 2)));
 }
 
 void meson_set_cpu_power_ctrl(uint32_t cpu, int is_power_on)
@@ -200,17 +198,17 @@ static int meson_boot_secondary(unsigned int cpu, struct task_struct *idle)
         */
        write_pen_release(cpu_logical_map(cpu));
 
-#ifndef CONFIG_MESON_TRUSTZONE
-       meson_set_cpu_ctrl_addr(cpu,
-               (const uint32_t)virt_to_phys(meson_secondary_startup));
-       meson_set_cpu_power_ctrl(cpu, 1);
-       timeout = jiffies + (10 * HZ);
+       if (!meson_secure_enabled()) {
+               meson_set_cpu_ctrl_addr(cpu,
+                       (const uint32_t)virt_to_phys(meson_secondary_startup));
+               meson_set_cpu_power_ctrl(cpu, 1);
+               timeout = jiffies + (10 * HZ);
 
-       while (meson_get_cpu_ctrl_addr(cpu))
-               ;
-       if (!time_before(jiffies, timeout))
-               return -EPERM;
-#endif
+               while (meson_get_cpu_ctrl_addr(cpu))
+                       ;
+               if (!time_before(jiffies, timeout))
+                       return -EPERM;
+       }
 
        meson_secondary_set(cpu);
        dsb_sev();
index ac567cc..6b4918b 100644 (file)
 #include <linux/of_address.h>
 #include <linux/io.h>
 #include <linux/amlogic/iomap.h>
-
-#ifdef CONFIG_MESON_TRUSTZONE
-#include <mach/meson-secure.h>
-#endif
+#include <linux/amlogic/meson-secure.h>
 
 #define IO_REGS_BASE           0xFE000000
 #define IO_BOOTROM_BASE        (IO_REGS_BASE + 0x010000) /*64K*/
@@ -40,9 +37,7 @@ int __init meson_cpu_version_init(void)
        void __iomem  *assist_hw_rev0;
        void __iomem  *assist_hw_rev1;
        void __iomem  *assist_hw_rev2;
-#ifndef CONFIG_MESON_TRUSTZONE
        unsigned int  *version_map;
-#endif
 
        cpu_version = of_find_node_by_name(NULL, "cpu_version");
        if (!cpu_version) {
@@ -62,12 +57,13 @@ int __init meson_cpu_version_init(void)
 
        meson_cpu_version[MESON_CPU_VERSION_LVL_MAJOR] = readl(assist_hw_rev0);
 
-#ifndef CONFIG_MESON_TRUSTZONE
-       version_map = (unsigned int *)assist_hw_rev2;
-       meson_cpu_version[MESON_CPU_VERSION_LVL_MISC] = version_map[1];
-#else
-       meson_cpu_version[MESON_CPU_VERSION_LVL_MISC] = meson_read_socrev1();
-#endif
+       if (meson_secure_enabled()) {
+               meson_cpu_version[MESON_CPU_VERSION_LVL_MISC] =
+                       meson_read_socrev1();
+       } else {
+               version_map = (unsigned int *)assist_hw_rev2;
+               meson_cpu_version[MESON_CPU_VERSION_LVL_MISC] = version_map[1];
+       }
 
        version = readl(assist_hw_rev1);
        switch (version) {
index 6e5884b..8d11fb0 100644 (file)
 #ifndef CONFIG_ARM64
 #include <asm/opcodes-sec.h>
 #endif
+#include <linux/amlogic/meson-secure.h>
 #include <linux/amlogic/efuse.h>
 #include "efuse_regs.h"
 #include "efuse.h"
+
+
 int efuse_active_version = -1;
 
 #ifdef EFUSE_DEBUG
@@ -51,22 +54,6 @@ static void __efuse_read_dword_debug(unsigned long addr, unsigned long *data)
 }
 #endif
 
-/* to do meson_efuse_fn_smc */
-
-int meson_trustzone_efuse(struct efuse_hal_api_arg *arg)
-{
-       int ret;
-
-       if (!arg)
-               return -1;
-
-       set_cpus_allowed_ptr(current, cpumask_of(0));
-       //ret = meson_efuse_fn_smc(arg);
-       set_cpus_allowed_ptr(current, cpu_all_mask);
-       return ret;
-}
-
-#ifndef CONFIG_MESON_TRUSTZONE
 #ifndef EFUSE_DEBUG
 static void __efuse_write_byte(unsigned long addr, unsigned long data)
 {
@@ -122,8 +109,10 @@ static void __efuse_write_byte(unsigned long addr, unsigned long data)
         * then disable it upon exit
         */
        if (auto_wr_is_enabled == 0) {
-               aml_set_reg32_bits(P_EFUSE_CNTL1, CNTL1_AUTO_WR_ENABLE_OFF,
-           CNTL1_AUTO_WR_ENABLE_BIT, CNTL1_AUTO_WR_ENABLE_SIZE);
+               aml_set_reg32_bits(P_EFUSE_CNTL1,
+                               CNTL1_AUTO_WR_ENABLE_OFF,
+                               CNTL1_AUTO_WR_ENABLE_BIT,
+                               CNTL1_AUTO_WR_ENABLE_SIZE);
        }
 
        //set efuse PD=1
@@ -188,22 +177,20 @@ static void __efuse_read_dword(unsigned long addr, unsigned long *data)
        pr_debug("__efuse_read_dword: addr=%ld, data=0x%lx\n", addr, *data);
 }
 #endif
-#endif
+
 static ssize_t __efuse_read(char *buf, size_t count, loff_t *ppos)
 {
        unsigned long *contents = kzalloc(sizeof(unsigned long)*EFUSE_DWORDS,
                GFP_KERNEL);
        unsigned int pos = *ppos;
-#ifndef CONFIG_MESON_TRUSTZONE
        unsigned long *pdw;
        char *tmp_p;
        /*pos may not align to 4*/
        unsigned int dwsize = (count + 3 +  pos%4) >> 2;
-#else
        struct efuse_hal_api_arg arg;
        unsigned long retcnt;
        int ret;
-#endif
+
        if (!contents) {
                pr_info("memory not enough\n");
                return -ENOMEM;
@@ -217,66 +204,65 @@ static ssize_t __efuse_read(char *buf, size_t count, loff_t *ppos)
        if (count > EFUSE_BYTES)
                return -EFAULT;
 
-#ifndef CONFIG_MESON_TRUSTZONE
-       clk_prepare_enable(efuse_clk);
-       aml_set_reg32_bits(P_EFUSE_CNTL1, CNTL1_AUTO_RD_ENABLE_ON,
-               CNTL1_AUTO_RD_ENABLE_BIT, CNTL1_AUTO_RD_ENABLE_SIZE);
+       if (!meson_secure_enabled()) {
+               clk_prepare_enable(efuse_clk);
+               aml_set_reg32_bits(P_EFUSE_CNTL1, CNTL1_AUTO_RD_ENABLE_ON,
+                       CNTL1_AUTO_RD_ENABLE_BIT, CNTL1_AUTO_RD_ENABLE_SIZE);
 
-       for (pdw = contents + pos/4;
-               dwsize-- > 0 && pos < EFUSE_BYTES;
-               pos += 4, ++pdw) {
-               #ifdef EFUSE_DEBUG
-               __efuse_read_dword_debug(pos, pdw);
-               #else
-               /* if pos does not align to 4,  __efuse_read_dword
-                * read from next dword, so, discount this un-aligned
-                * partition
-                */
-               __efuse_read_dword((pos - pos%4), pdw);
-               #endif
-       }
+               for (pdw = contents + pos/4;
+                       dwsize-- > 0 && pos < EFUSE_BYTES;
+                       pos += 4, ++pdw) {
+                       #ifdef EFUSE_DEBUG
+                       __efuse_read_dword_debug(pos, pdw);
+                       #else
+                       /* if pos does not align to 4,  __efuse_read_dword
+                        * read from next dword, so, discount this un-aligned
+                        * partition
+                        */
+                       __efuse_read_dword((pos - pos%4), pdw);
+                       #endif
+               }
 
-       aml_set_reg32_bits(P_EFUSE_CNTL1, CNTL1_AUTO_RD_ENABLE_OFF,
-                       CNTL1_AUTO_RD_ENABLE_BIT, CNTL1_AUTO_RD_ENABLE_SIZE);
+               aml_set_reg32_bits(P_EFUSE_CNTL1,
+                               CNTL1_AUTO_RD_ENABLE_OFF,
+                               CNTL1_AUTO_RD_ENABLE_BIT,
+                               CNTL1_AUTO_RD_ENABLE_SIZE);
 
-       clk_disable_unprepare(efuse_clk);
-       tmp_p = (char *)contents;
-       tmp_p += *ppos;
-
-       memcpy(buf, tmp_p, count);
-
-       *ppos += count;
-#else
-       arg.cmd = EFUSE_HAL_API_READ;
-       arg.offset = pos;
-       arg.size = count;
-       arg.buffer = (unsigned long)contents;
-       arg.retcnt = (unsigned long)(&retcnt);
-       ret = meson_trustzone_efuse(&arg);
-
-       if (ret == 0) {
-               count = retcnt;
-               *ppos += retcnt;
-               memcpy(buf, contents, retcnt);
-       } else
-               count = 0;
-#endif /* CONFIG_MESON_TRUSTZONE */
+               clk_disable_unprepare(efuse_clk);
+               tmp_p = (char *)contents;
+               tmp_p += *ppos;
+
+               memcpy(buf, tmp_p, count);
+
+               *ppos += count;
+       } else {
+               arg.cmd = EFUSE_HAL_API_READ;
+               arg.offset = pos;
+               arg.size = count;
+               arg.buffer = virt_to_phys(contents);
+               arg.retcnt = virt_to_phys(&retcnt);
+               ret = meson_trustzone_efuse((void *)&arg);
+               if (ret == 0) {
+                       count = retcnt;
+                       *ppos += retcnt;
+                       memcpy(buf, contents, retcnt);
+               } else
+                       count = 0;
+       }
 
        /*if (contents)*/
                kfree(contents);
+
        return count;
 }
 
 static ssize_t __efuse_write(const char *buf, size_t count, loff_t *ppos)
 {
        unsigned int pos = *ppos;
-#ifndef CONFIG_MESON_TRUSTZONE
        unsigned char *pc;
-#else
        struct efuse_hal_api_arg arg;
        unsigned int retcnt;
        int ret;
-#endif
 
        if (pos >= EFUSE_BYTES)
                return 0;       /* Past EOF */
@@ -285,29 +271,31 @@ static ssize_t __efuse_write(const char *buf, size_t count, loff_t *ppos)
        if (count > EFUSE_BYTES)
                return -EFAULT;
 
-#ifndef CONFIG_MESON_TRUSTZONE
-       for (pc = (char *)buf; count--; ++pos, ++pc)
-       #ifdef EFUSE_DEBUG
-               __efuse_write_byte_debug(pos, *pc);
-       #else
-               __efuse_write_byte(pos, *pc);
-       #endif
-
-       *ppos = pos;
-       return (const char *)pc - buf;
-#else
-       arg.cmd = EFUSE_HAL_API_WRITE;
-       arg.offset = pos;
-       arg.size = count;
-       arg.buffer = (unsigned long)buf;
-       arg.retcnt = (unsigned long)(&retcnt);
-       ret = meson_trustzone_efuse(&arg);
-       if (ret == 0) {
-               *ppos = pos+retcnt;
-               return retcnt;
-       } else
-               return 0;
-#endif
+       if (!meson_secure_enabled()) {
+               for (pc = (char *)buf; count--; ++pos, ++pc)
+               #ifdef EFUSE_DEBUG
+                       __efuse_write_byte_debug(pos, *pc);
+               #else
+                       __efuse_write_byte(pos, *pc);
+               #endif
+
+               *ppos = pos;
+               ret = (const char *)pc - buf;
+       } else {
+               arg.cmd = EFUSE_HAL_API_WRITE;
+               arg.offset = pos;
+               arg.size = count;
+               arg.buffer = virt_to_phys(buf);
+               arg.retcnt = virt_to_phys(&retcnt);
+               ret = meson_trustzone_efuse((void *)&arg);
+               if (ret == 0) {
+                       *ppos = pos+retcnt;
+                       ret = retcnt;
+               } else
+                       ret = 0;
+       }
+
+       return ret;
 }
 
 ssize_t aml__efuse_read(char *buf, size_t count, loff_t *ppos)
index 8817fc4..4e8b4cb 100644 (file)
@@ -41,6 +41,9 @@
 
 #include <linux/amlogic/cpu_version.h>
 #include <linux/amlogic/jtag.h>
+#ifdef CONFIG_MACH_MESON8B
+#include <linux/amlogic/meson-secure.h>
+#endif
 
 #include "meson_jtag.h"
 
@@ -266,7 +269,34 @@ static int aml_jtag_apee_free_gpios(struct platform_device *pdev)
 
 #ifdef CONFIG_MACH_MESON8B
 
-static int aml_jtag_select(struct platform_device *pdev)
+static int aml_jtag_select_tee(struct platform_device *pdev)
+{
+       struct aml_jtag_dev *jdev = platform_get_drvdata(pdev);
+       uint32_t select = jdev->select;
+
+       pr_info("set state %u\n", select);
+       set_cpus_allowed_ptr(current, cpumask_of(0));
+       switch (select) {
+       case AMLOGIC_JTAG_DISABLE:
+               meson_secure_jtag_disable();
+               break;
+       case AMLOGIC_JTAG_APAO:
+               meson_secure_jtag_apao();
+               break;
+       case AMLOGIC_JTAG_APEE:
+               meson_secure_jtag_apao();
+               break;
+
+       default:
+               writel_relaxed(0x0, jdev->base);
+               break;
+       }
+       set_cpus_allowed_ptr(current, cpu_all_mask);
+
+       return 0;
+}
+
+static int aml_jtag_select_ree(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
@@ -304,6 +334,16 @@ static int aml_jtag_select(struct platform_device *pdev)
        return 0;
 }
 
+static int aml_jtag_select(struct platform_device *pdev)
+{
+       if (meson_secure_enabled())
+               aml_jtag_select_tee(pdev);
+       else
+               aml_jtag_select_ree(pdev);
+
+       return 0;
+}
+
 #else
 
 static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
@@ -616,4 +656,3 @@ module_exit(aml_jtag_exit);
 MODULE_DESCRIPTION("Meson JTAG Driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Amlogic, Inc.");
-
diff --git a/include/linux/amlogic/meson-secure.h b/include/linux/amlogic/meson-secure.h
new file mode 100644 (file)
index 0000000..1b38da0
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * include/linux/amlogic/meson-secure.h
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _MESON_SECURE_H_
+#define _MESON_SECURE_H_
+
+/* Meson Secure Monitor/HAL APIs */
+#define CALL_TRUSTZONE_API                      0x1
+#define CALL_TRUSTZONE_MON                      0x4
+#define CALL_TRUSTZONE_HAL_API                  0x5
+
+/* Secure Monitor mode APIs */
+#define TRUSTZONE_MON_TYPE_MASK                 0xF00
+#define TRUSTZONE_MON_FUNC_MASK                 0x0FF
+#define TRUSTZONE_MON_L2X0                      0x100
+#define TRUSTZONE_MON_L2X0_CTRL_INDEX           0x101
+#define TRUSTZONE_MON_L2X0_AUXCTRL_INDEX        0x102
+#define TRUSTZONE_MON_L2X0_PREFETCH_INDEX       0x103
+#define TRUSTZONE_MON_L2X0_TAGLATENCY_INDEX     0x104
+#define TRUSTZONE_MON_L2X0_DATALATENCY_INDEX    0x105
+#define TRUSTZONE_MON_L2X0_FILTERSTART_INDEX    0x106
+#define TRUSTZONE_MON_L2X0_FILTEREND_INDEX      0x107
+#define TRUSTZONE_MON_L2X0_DEBUG_INDEX          0x108
+#define TRUSTZONE_MON_L2X0_POWER_INDEX          0x109
+
+#define TRUSTZONE_MON_CORE                      0x200
+#define TRUSTZONE_MON_CORE_RD_CTRL_INDEX        0x201
+#define TRUSTZONE_MON_CORE_WR_CTRL_INDEX        0x202
+#define TRUSTZONE_MON_CORE_RD_STATUS0_INDEX     0x203
+#define TRUSTZONE_MON_CORE_WR_STATUS0_INDEX     0x204
+#define TRUSTZONE_MON_CORE_RD_STATUS1_INDEX     0x205
+#define TRUSTZONE_MON_CORE_WR_STATUS1_INDEX     0x206
+#define TRUSTZONE_MON_CORE_BOOTADDR_INDEX       0x207
+#define TRUSTZONE_MON_CORE_DDR_INDEX            0x208
+#define TRUSTZONE_MON_CORE_RD_SOC_REV1          0x209
+#define TRUSTZONE_MON_CORE_RD_SOC_REV2          0x20A
+#define TRUSTZONE_MON_CORE_OFF                  0x20B
+
+#define TRUSTZONE_MON_SUSPNED_FIRMWARE          0x300
+#define TRUSTZONE_MON_SAVE_CPU_GIC              0x400
+
+#define TRUSTZONE_MON_RTC                       0x500
+#define TRUSTZONE_MON_RTC_RD_REG_INDEX          0x501
+#define TRUSTZONE_MON_RTC_WR_REG_INDEX          0x502
+
+#define TRUSTZONE_MON_REG                       0x600
+#define TRUSTZONE_MON_REG_RD_INDEX              0x601
+#define TRUSTZONE_MON_REG_WR_INDEX              0x602
+
+#define TRUSTZONE_MON_MEM                       0x700
+#define TRUSTZONE_MON_MEM_BASE                  0x701
+#define TRUSTZONE_MON_MEM_TOTAL_SIZE            0x702
+#define TRUSTZONE_MON_MEM_FLASH                 0x703
+#define TRUSTZONE_MON_MEM_FLASH_SIZE            0x704
+#define TRUSTZONE_MON_MEM_GE2D                  0x705
+
+#define TRUSTZONE_MON_JTAG                      0x800
+#define TRUSTZONE_MON_JTAG_DISABLE              0x801
+#define TRUSTZONE_MON_JTAG_APAO                 0x802
+#define TRUSTZONE_MON_JTAG_APEE                 0x803
+
+/* Secure HAL APIs*/
+#define TRUSTZONE_HAL_API_EFUSE                 0x100
+#define TRUSTZONE_HAL_API_STORAGE               0x200
+#define TRUSTZONE_HAL_API_MEMCONFIG             0x300
+#define TRUSTZONE_HAL_API_MEMCONFIG_GE2D        0x301
+
+#ifndef __ASSEMBLER__
+extern int meson_smc1(uint32_t fn, uint32_t arg);
+extern int meson_smc_hal_api(uint32_t cmdidx, uint32_t arg);
+extern int meson_smc2(uint32_t arg);
+extern int meson_smc3(uint32_t arg1, uint32_t arg2);
+extern bool meson_secure_enabled(void);
+extern uint32_t meson_read_corectrl(void);
+extern uint32_t meson_modify_corectrl(uint32_t arg);
+extern uint32_t meson_read_corestatus(uint32_t cpu);
+extern uint32_t meson_modify_corestatus(uint32_t cpu, uint32_t arg);
+extern void meson_auxcoreboot_addr(uint32_t cpu, uint32_t arg);
+extern void meson_suspend_firmware(void);
+extern uint32_t meson_secure_reg_read(uint32_t addr);
+extern uint32_t meson_secure_reg_write(uint32_t addr, uint32_t val);
+extern uint32_t meson_read_socrev1(void);
+extern uint32_t meson_read_socrev2(void);
+extern uint32_t meson_secure_mem_base_start(void);
+extern uint32_t meson_secure_mem_total_size(void);
+extern uint32_t meson_secure_mem_flash_start(void);
+extern uint32_t meson_secure_mem_flash_size(void);
+extern int32_t meson_secure_mem_ge2d_access(uint32_t msec);
+
+extern uint32_t meson_secure_jtag_disable(void);
+extern uint32_t meson_secure_jtag_apao(void);
+extern uint32_t meson_secure_jtag_apee(void);
+
+extern int meson_trustzone_efuse(void *arg);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MESON_SECURE_H_ */