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
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{
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 {
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
--- /dev/null
+/*
+ * 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);
--- /dev/null
+/*
+ * 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)
#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",
}
#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
#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);
{
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)
*/
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();
#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*/
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) {
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) {
#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
}
#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)
{
* 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
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;
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 */
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)
#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"
#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;
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,
MODULE_DESCRIPTION("Meson JTAG Driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Amlogic, Inc.");
-
--- /dev/null
+/*
+ * 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_ */