From 47648bd7e0320979646894b866e039eb0941e812 Mon Sep 17 00:00:00 2001 From: Manoharan Vijaya Raghavan Date: Mon, 2 Apr 2018 21:49:42 +0530 Subject: [PATCH] ipq807x: Dcache: Fixing Dcache invalidate Using of Dcache invalidate all resulted in stack which was dirty being invalidated. Hence the return address stored in stack wasn't flushed and this caused issues. Reverting to invalidate_dcache_range. Change-Id: I382e07a3a81885ab02c9eae38196d3aa3ba8b086 Signed-off-by: Manoharan Vijaya Raghavan --- arch/arm/cpu/armv7/qca/common/scm.c | 39 +++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/arch/arm/cpu/armv7/qca/common/scm.c b/arch/arm/cpu/armv7/qca/common/scm.c index 26a451e233..8eb9e4183b 100644 --- a/arch/arm/cpu/armv7/qca/common/scm.c +++ b/arch/arm/cpu/armv7/qca/common/scm.c @@ -294,7 +294,6 @@ static int scm_call_64(u32 svc_id, u32 cmd_id, struct qca_scm_desc *desc) &desc->ret[0], &desc->ret[1], &desc->ret[2]); - invalidate_dcache_all(); return ret; } @@ -325,7 +324,6 @@ bool is_scm_armv8(void) flush_dcache_all(); ret = __qca_scm_call_armv8_32(x0, QCA_SCM_ARGS(1), x0, 0, 0, 0, &ret1, NULL, NULL); - invalidate_dcache_all(); if (ret || !ret1) scm_version = SCM_LEGACY; else @@ -385,6 +383,23 @@ void __attribute__ ((noreturn)) execute_tzt(void *entry_addr) } +/* We need to invalidate the buffer written by TZ before we use in u-boot + * In some calls TZ writes to desc.args[0]. + * This arg is passed with an address of local variable with size 1. + * This is not cache aligned and invalidate_dcache_range won't + * invalidate this cache line at all. To avoid this we are passing a + * buffer which is cache aligned and we will copy contents of this + * buffer back to buffer passed by callers. + */ +/* Just aliging the address of local variable with cache line is also + * not correct as the other stack contents will also be invalidated wrongly + * Hence creating a seperate cache aligned buffer + */ +#ifndef CONFIG_SYS_CACHELINE_SIZE +#define CONFIG_SYS_CACHELINE_SIZE 128 +#endif +static uint8_t tz_buf[CONFIG_SYS_CACHELINE_SIZE] __aligned(CONFIG_SYS_CACHELINE_SIZE); + int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len) { int ret = 0; @@ -393,10 +408,15 @@ int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len) { struct qca_scm_desc desc = {0}; + memcpy(tz_buf, buf, len); desc.arginfo = QCA_SCM_ARGS(2, SCM_READ_OP); - desc.args[0] = (u32)buf; + desc.args[0] = (u32)tz_buf; desc.args[1] = len; ret = scm_call_64(svc_id, cmd_id, &desc); + /* qca_scm_call is called with len 1, hence tz_buf is enough */ + invalidate_dcache_range(tz_buf, + tz_buf + CONFIG_SYS_CACHELINE_SIZE); + memcpy(buf, tz_buf, len); } else { @@ -452,19 +472,6 @@ int qca_scm_auth_kernel(void *cmd_buf, return ret; } -int qca_scm_call_read(u32 svc_id, u32 cmd_id, u32 *addr, u32 *rsp) -{ - int ret = 0; - - struct qca_scm_desc desc = {0}; - desc.arginfo = QCA_SCM_ARGS(1, SCM_READ_OP); - desc.args[0] = (u32)addr; - ret = scm_call_64(svc_id, cmd_id, &desc); - if (!ret) - *rsp = desc.ret[0]; - return ret; -} - int qca_scm_call_write(u32 svc_id, u32 cmd_id, u32 *addr, u32 val) { int ret = 0;