From f9ad5ac9d793d72279b622667ea5ade663a19016 Mon Sep 17 00:00:00 2001 From: Gokul Sriram Palanisamy Date: Tue, 10 Oct 2017 22:48:23 +0530 Subject: [PATCH] ipq807x: Modified scm calls to support both 32 bit and 64 bit Change-Id: Iee99423239f7de49a9fc7a4c2e6244df385f5f09 Signed-off-by: Gopinath Sekar Signed-off-by: Gokul Sriram Palanisamy --- arch/arm/cpu/armv7/qca/common/scm.c | 149 ++++++++++++++++----- arch/arm/include/asm/arch-qca-common/scm.h | 10 +- arch/arm/lib/bootm.c | 8 -- board/qca/arm/common/cmd_bootqca.c | 55 ++++---- board/qca/arm/ipq807x/ipq807x.c | 5 +- include/configs/ipq807x.h | 1 - include/image.h | 8 -- 7 files changed, 149 insertions(+), 87 deletions(-) diff --git a/arch/arm/cpu/armv7/qca/common/scm.c b/arch/arm/cpu/armv7/qca/common/scm.c index cdffb4933f..b394d21947 100644 --- a/arch/arm/cpu/armv7/qca/common/scm.c +++ b/arch/arm/cpu/armv7/qca/common/scm.c @@ -225,8 +225,6 @@ int scm_init(void) return 0; } -#ifdef CONFIG_SCM_TZ64 - int __qca_scm_call_armv8_32(u32 x0, u32 x1, u32 x2, u32 x3, u32 x4, u32 x5, u32 *ret1, u32 *ret2, u32 *ret3) { @@ -298,6 +296,42 @@ static int scm_call_64(u32 svc_id, u32 cmd_id, struct qca_scm_desc *desc) return ret; } +static enum scm_interface_version { + SCM_UNKNOWN, + SCM_LEGACY, + SCM_ARMV8_32, +} scm_version = SCM_UNKNOWN; + +/* This function is used to find whether TZ is in AARCH64 mode. + * If this function returns 1, then its in AARCH64 mode and + * calling conventions for AARCH64 TZ is different, we need to + * use them. + */ +bool is_scm_armv8(void) +{ + int ret; + u32 ret1, x0; + + if (likely(scm_version != SCM_UNKNOWN)) + return (scm_version == SCM_ARMV8_32); + + /* Try SMC32 call */ + ret1 = 0; + x0 = QCA_SCM_SIP_FNID(SCM_SVC_INFO, QCA_IS_CALL_AVAIL_CMD) | + QCA_SMC_ATOMIC_MASK; + + ret = __qca_scm_call_armv8_32(x0, QCA_SCM_ARGS(1), x0, 0, 0, 0, + &ret1, NULL, NULL); + if (ret || !ret1) + scm_version = SCM_LEGACY; + else + scm_version = SCM_ARMV8_32; + + pr_debug("scm_call: scm version is %x\n", scm_version); + + return (scm_version == SCM_ARMV8_32); +} + void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry, void *fdt_addr) { @@ -312,6 +346,11 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry, desc.args[0] = (u32) ¶m; desc.args[1] = sizeof(param); + if (!is_scm_armv8()) { + printf("Can't boot kernel: %d\n", ret); + hang(); + } + printf("Jumping to AARCH64 kernel via monitor\n"); ret = scm_call_64(SCM_ARCH64_SWITCH_ID, SCM_EL1SWITCH_CMD_ID, &desc); @@ -320,22 +359,24 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry, hang(); } -#endif int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len) { int ret = 0; -#ifdef CONFIG_SCM_TZ64 - struct qca_scm_desc desc = {0}; + if (is_scm_armv8()) + { + struct qca_scm_desc desc = {0}; - desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP); - desc.args[0] = (u32)buf; - desc.args[1] = len; - ret = scm_call_64(svc_id, cmd_id, &desc); -#else - ret = scm_call(svc_id, cmd_id, NULL, 0, buf, len); -#endif + desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP); + desc.args[0] = (u32)buf; + desc.args[1] = len; + ret = scm_call_64(svc_id, cmd_id, &desc); + } + else + { + ret = scm_call(svc_id, cmd_id, NULL, 0, buf, len); + } return ret; } @@ -343,19 +384,22 @@ int qca_scm_fuseipq(u32 svc_id, u32 cmd_id, void *buf, size_t len) { int ret = 0; uint32_t *status; -#ifdef CONFIG_SCM_TZ64 - struct qca_scm_desc desc = {0}; + if (is_scm_armv8()) + { + struct qca_scm_desc desc = {0}; - desc.arginfo = QCA_SCM_ARGS(1, SCM_READ_OP); - desc.args[0] = *((unsigned int *)buf); + desc.arginfo = QCA_SCM_ARGS(1, SCM_READ_OP); + desc.args[0] = *((unsigned int *)buf); - ret = scm_call_64(svc_id, cmd_id, &desc); + ret = scm_call_64(svc_id, cmd_id, &desc); - status = (uint32_t *)(*(((uint32_t *)buf) + 1)); - *status = desc.ret[0]; -#else - ret = scm_call(svc_id, cmd_id, buf, len, NULL, 0); -#endif + status = (uint32_t *)(*(((uint32_t *)buf) + 1)); + *status = desc.ret[0]; + } + else + { + ret = scm_call(svc_id, cmd_id, buf, len, NULL, 0); + } return ret; } @@ -364,23 +408,25 @@ int qca_scm_auth_kernel(void *cmd_buf, { int ret = 0; -#ifdef CONFIG_SCM_TZ64 - struct qca_scm_desc desc = {0}; - desc.arginfo = QCA_SCM_ARGS(1, SCM_VAL); - /* args[0] has the kernel load address */ - desc.args[0] = * ((unsigned int *)cmd_buf); - /* args[1] has the kernel image size */ - desc.args[1] = * (((unsigned int *)cmd_buf) + 1); - ret = scm_call_64(SCM_SVC_BOOT, KERNEL_AUTH_CMD, &desc); -#else - ret = scm_call(SCM_SVC_BOOT, KERNEL_AUTH_CMD, cmd_buf, cmd_len, - NULL, 0); -#endif + if (is_scm_armv8()) + { + struct qca_scm_desc desc = {0}; + desc.arginfo = QCA_SCM_ARGS(1, SCM_VAL); + /* args[0] has the kernel load address */ + desc.args[0] = * ((unsigned int *)cmd_buf); + /* args[1] has the kernel image size */ + desc.args[1] = * (((unsigned int *)cmd_buf) + 1); + ret = scm_call_64(SCM_SVC_BOOT, KERNEL_AUTH_CMD, &desc); + } + else + { + ret = scm_call(SCM_SVC_BOOT, KERNEL_AUTH_CMD, cmd_buf, cmd_len, + NULL, 0); + } return ret; } -#ifdef CONFIG_SCM_TZ64 int qca_scm_call_read(u32 svc_id, u32 cmd_id, u32 *addr, u32 *rsp) { int ret = 0; @@ -406,7 +452,7 @@ int qca_scm_call_write(u32 svc_id, u32 cmd_id, u32 *addr, u32 val) return ret; } -int qca_scm_sdi_v8(void) +static int qca_scm_sdi_v8(void) { struct qca_scm_desc desc = {0}; int ret; @@ -422,4 +468,33 @@ int qca_scm_sdi_v8(void) return le32_to_cpu(desc.ret[0]); } -#endif + +int qca_scm_sdi(void) +{ + int ret; + unsigned int clear_info[] = { + 1 /* Disable wdog debug */, 0 /* SDI enable*/, }; + + if (is_scm_armv8()) + return qca_scm_sdi_v8(); + + ret = scm_call(SCM_SVC_BOOT, SCM_CMD_TZ_CONFIG_HW_FOR_RAM_DUMP_ID, &clear_info, + sizeof(clear_info), NULL, 0); + + return ret; +} + +int qca_scm_dload(unsigned int magic_cookie) +{ + int ret; + if (is_scm_armv8()) + { + ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE, + 0x193D100, magic_cookie); + } + else + { + ret = scm_call(SCM_SVC_BOOT, SCM_CMD_TZ_FORCE_DLOAD_ID, &magic_cookie, + sizeof(magic_cookie), NULL, 0); + } +} diff --git a/arch/arm/include/asm/arch-qca-common/scm.h b/arch/arm/include/asm/arch-qca-common/scm.h index 15d7eb9ad2..e6813e44f2 100644 --- a/arch/arm/include/asm/arch-qca-common/scm.h +++ b/arch/arm/include/asm/arch-qca-common/scm.h @@ -98,8 +98,10 @@ extern int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len); int qca_scm_call_write(u32, u32, u32 *, u32); int qca_scm_call_read(u32, u32, u32 *, u32 *); -int qca_scm_sdi_v8(void); +int qca_scm_sdi(void); +int qca_scm_dload(u32); int qca_scm_fuseipq(u32, u32, void *, size_t); +bool is_scm_armv8(void); #define MAX_QCA_SCM_RETS 3 #define MAX_QCA_SCM_ARGS 10 @@ -141,11 +143,11 @@ struct qca_scm_desc { #define QCA_SCM_ARGS(...) QCA_SCM_ARGS_IMPL(__VA_ARGS__, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) -#ifdef CONFIG_SCM_TZ64 - #define QCA_SCM_SIP_FNID(s, c) (((((s) & 0xFF) << 8) | \ ((c) & 0xFF)) | 0x02000000) +#define QCA_SMC_ATOMIC_MASK 0x80000000 + #define QCA_MAX_ARG_LEN 5 typedef struct { @@ -162,6 +164,7 @@ typedef struct { } kernel_params; #define SCM_ARCH64_SWITCH_ID 0x1 +#define QCA_IS_CALL_AVAIL_CMD 0x1 #define SCM_EL1SWITCH_CMD_ID 0xf #define SCM_NULL_OP 0 @@ -172,4 +175,3 @@ void __attribute__ ((noreturn)) jump_kernel64(void *kernel_entry, void *fdt_addr); #endif -#endif diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index ff708610f0..2c4c75e360 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -29,9 +29,7 @@ #ifdef CONFIG_ARMV7_NONSEC #include #endif -#ifdef CONFIG_SCM_TZ64 #include -#endif DECLARE_GLOBAL_DATA_PTR; static struct tag *params; @@ -260,7 +258,6 @@ bool armv7_boot_nonsec(void) } #endif -#ifdef CONFIG_SCM_TZ64 struct aarch64_hdr { u32 code0; /* Executable code */ u32 code1; /* Executable code */ @@ -275,7 +272,6 @@ struct aarch64_hdr { }; #define AARCH64_LINUX_MAGIC 0x644d5241 #define TEST_AARCH64(ptr) (ptr->magic == AARCH64_LINUX_MAGIC) ? true : false -#endif /* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) @@ -326,11 +322,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) else r2 = gd->bd->bi_boot_params; -#ifdef CONFIG_SCM_TZ64 if (TEST_AARCH64(((struct aarch64_hdr *)kernel_entry))) { jump_kernel64(kernel_entry, images->ft_addr); } else { -#endif if (!fake) { #ifdef CONFIG_ARMV7_NONSEC if (armv7_boot_nonsec()) { @@ -341,10 +335,8 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) #endif kernel_entry(0, machid, r2); } -#ifdef CONFIG_SCM_TZ64 } #endif -#endif } /* Main Entry point for arm bootm implementation diff --git a/board/qca/arm/common/cmd_bootqca.c b/board/qca/arm/common/cmd_bootqca.c index 31688010ea..a2d1f0b9f6 100644 --- a/board/qca/arm/common/cmd_bootqca.c +++ b/board/qca/arm/common/cmd_bootqca.c @@ -258,39 +258,42 @@ void qca_appsbl_dload(void) { unsigned long * dmagic1 = (unsigned long *) 0x2A03F000; unsigned long * dmagic2 = (unsigned long *) 0x2A03F004; -#ifdef CONFIG_SCM_TZ64 - ret = qca_scm_call_read(SCM_SVC_IO, SCM_IO_READ, addr, &rsp); - if (rsp == DLOAD_MAGIC_COOKIE) { - val = 0x0; - - ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE, addr, val); - if (ret) - printf ("Error in reseting the Magic cookie\n"); - dump_func(); - } -#else - ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_RD, (void *)&val, sizeof(val)); - if (ret) { - if (*dmagic1 == 0xE47B337D && *dmagic2 == 0x0501CAB0) { - /* clear the magic and run the dump command */ - *dmagic1 = 0; - *dmagic2 = 0; - dump_func(); - } - } - else { - /* check if we are in download mode */ - if (val == DLOAD_MAGIC_COOKIE) { - /* clear the magic and run the dump command */ + if (is_scm_armv8()) + { + ret = qca_scm_call_read(SCM_SVC_IO, SCM_IO_READ, addr, &rsp); + if (rsp == DLOAD_MAGIC_COOKIE) { val = 0x0; - ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_WR, (void *)&val, sizeof(val)); + ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE, addr, val); if (ret) printf ("Error in reseting the Magic cookie\n"); dump_func(); } } -#endif + else + { + ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_RD, (void *)&val, sizeof(val)); + if (ret) { + if (*dmagic1 == 0xE47B337D && *dmagic2 == 0x0501CAB0) { + /* clear the magic and run the dump command */ + *dmagic1 = 0; + *dmagic2 = 0; + dump_func(); + } + } + else { + /* check if we are in download mode */ + if (val == DLOAD_MAGIC_COOKIE) { + /* clear the magic and run the dump command */ + val = 0x0; + + ret = qca_scm_call(SCM_SVC_BOOT, SCM_SVC_WR, (void *)&val, sizeof(val)); + if (ret) + printf ("Error in reseting the Magic cookie\n"); + dump_func(); + } + } + } } #endif diff --git a/board/qca/arm/ipq807x/ipq807x.c b/board/qca/arm/ipq807x/ipq807x.c index 08747a0743..40fa3a27fa 100644 --- a/board/qca/arm/ipq807x/ipq807x.c +++ b/board/qca/arm/ipq807x/ipq807x.c @@ -185,9 +185,8 @@ unsigned long timer_read_counter(void) void reset_crashdump(void) { unsigned int ret = 0; - qca_scm_sdi_v8(); - ret = qca_scm_call_write(SCM_SVC_IO, SCM_IO_WRITE, - 0x193D100, CLEAR_MAGIC); + qca_scm_sdi(); + ret = qca_scm_dload(CLEAR_MAGIC); if (ret) printf ("Error in reseting the Magic cookie\n"); return; diff --git a/include/configs/ipq807x.h b/include/configs/ipq807x.h index 801a5e800f..173fb4438b 100644 --- a/include/configs/ipq807x.h +++ b/include/configs/ipq807x.h @@ -197,7 +197,6 @@ extern loff_t board_env_size; #define QCA_SPI_NOR_DEVICE "spi0.0" #define CONFIG_QUP_SPI_USE_DMA 1 -#define CONFIG_SCM_TZ64 1 /* * U-Boot Env Configs */ diff --git a/include/image.h b/include/image.h index 61ad3a8762..11a46eea6f 100644 --- a/include/image.h +++ b/include/image.h @@ -713,12 +713,8 @@ static inline int image_check_target_arch(const image_header_t *hdr) #ifndef IH_ARCH_DEFAULT # error "please define IH_ARCH_DEFAULT in your arch asm/u-boot.h" #endif -#ifdef CONFIG_SCM_TZ64 return image_check_arch(hdr, IH_ARCH_DEFAULT) || image_check_arch(hdr, IH_ARCH_ARM64); -#else - return image_check_arch(hdr, IH_ARCH_DEFAULT); -#endif } #endif /* USE_HOSTCC */ @@ -1105,12 +1101,8 @@ struct image_region *fit_region_make_list(const void *fit, static inline int fit_image_check_target_arch(const void *fdt, int node) { #ifndef USE_HOSTCC -#ifdef CONFIG_SCM_TZ64 return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT) || fit_image_check_arch(fdt, node, IH_ARCH_ARM64); -#else - return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT); -#endif #else return 0; #endif