mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
tee: optee: sync cache on pre-reloc OP-TEE invocation
This change ensures both U-Boot and OP-TEE see the same content from shared memory when OP-TEE is invoked prior U-Boot relocation. This change is required since U-Boot may execute with data cache off while OP-TEE always enables cache on memory shared with U-Boot. Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
parent
674afa6b35
commit
9e6da34c72
3 changed files with 44 additions and 2 deletions
|
@ -1,9 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0+
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Linaro Limited
|
* Copyright (c) 2018-2020 Linaro Limited
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <cpu_func.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <dm/device_compat.h>
|
#include <dm/device_compat.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
@ -295,6 +296,16 @@ static u32 call_err_to_res(u32 call_err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flush_shm_dcache(struct udevice *dev, struct optee_msg_arg *arg)
|
||||||
|
{
|
||||||
|
size_t sz = OPTEE_MSG_GET_ARG_SIZE(arg->num_params);
|
||||||
|
|
||||||
|
flush_dcache_range(rounddown((ulong)arg, CONFIG_SYS_CACHELINE_SIZE),
|
||||||
|
roundup((ulong)arg + sz, CONFIG_SYS_CACHELINE_SIZE));
|
||||||
|
|
||||||
|
tee_flush_all_shm_dcache(dev);
|
||||||
|
}
|
||||||
|
|
||||||
static u32 do_call_with_arg(struct udevice *dev, struct optee_msg_arg *arg)
|
static u32 do_call_with_arg(struct udevice *dev, struct optee_msg_arg *arg)
|
||||||
{
|
{
|
||||||
struct optee_pdata *pdata = dev_get_plat(dev);
|
struct optee_pdata *pdata = dev_get_plat(dev);
|
||||||
|
@ -305,9 +316,17 @@ static u32 do_call_with_arg(struct udevice *dev, struct optee_msg_arg *arg)
|
||||||
while (true) {
|
while (true) {
|
||||||
struct arm_smccc_res res;
|
struct arm_smccc_res res;
|
||||||
|
|
||||||
|
/* If cache are off from U-Boot, sync the cache shared with OP-TEE */
|
||||||
|
if (!dcache_status())
|
||||||
|
flush_shm_dcache(dev, arg);
|
||||||
|
|
||||||
pdata->invoke_fn(param.a0, param.a1, param.a2, param.a3,
|
pdata->invoke_fn(param.a0, param.a1, param.a2, param.a3,
|
||||||
param.a4, param.a5, param.a6, param.a7, &res);
|
param.a4, param.a5, param.a6, param.a7, &res);
|
||||||
|
|
||||||
|
/* If cache are off from U-Boot, sync the cache shared with OP-TEE */
|
||||||
|
if (!dcache_status())
|
||||||
|
flush_shm_dcache(dev, arg);
|
||||||
|
|
||||||
free(page_list);
|
free(page_list);
|
||||||
page_list = NULL;
|
page_list = NULL;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0+
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Linaro Limited
|
* Copyright (c) 2018-2020 Linaro Limited
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LOG_CATEGORY UCLASS_TEE
|
#define LOG_CATEGORY UCLASS_TEE
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <cpu_func.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <tee.h>
|
#include <tee.h>
|
||||||
|
#include <asm/cache.h>
|
||||||
#include <dm/device-internal.h>
|
#include <dm/device-internal.h>
|
||||||
#include <dm/uclass-internal.h>
|
#include <dm/uclass-internal.h>
|
||||||
|
|
||||||
|
@ -235,3 +237,18 @@ void tee_optee_ta_uuid_to_octets(u8 d[TEE_UUID_LEN],
|
||||||
d[7] = s->time_hi_and_version;
|
d[7] = s->time_hi_and_version;
|
||||||
memcpy(d + 8, s->clock_seq_and_node, sizeof(s->clock_seq_and_node));
|
memcpy(d + 8, s->clock_seq_and_node, sizeof(s->clock_seq_and_node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tee_flush_all_shm_dcache(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct tee_uclass_priv *priv = dev_get_uclass_priv(dev);
|
||||||
|
struct tee_shm *s;
|
||||||
|
|
||||||
|
list_for_each_entry(s, &priv->list_shm, link) {
|
||||||
|
ulong start = rounddown((ulong)s->addr,
|
||||||
|
CONFIG_SYS_CACHELINE_SIZE);
|
||||||
|
ulong end = roundup((ulong)s->addr + s->size,
|
||||||
|
CONFIG_SYS_CACHELINE_SIZE);
|
||||||
|
|
||||||
|
flush_dcache_range(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -377,4 +377,10 @@ void tee_optee_ta_uuid_from_octets(struct tee_optee_ta_uuid *d,
|
||||||
void tee_optee_ta_uuid_to_octets(u8 d[TEE_UUID_LEN],
|
void tee_optee_ta_uuid_to_octets(u8 d[TEE_UUID_LEN],
|
||||||
const struct tee_optee_ta_uuid *s);
|
const struct tee_optee_ta_uuid *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tee_flush_all_shm_dcache() - Flush data cache for all shared memories
|
||||||
|
* @dev: The TEE device
|
||||||
|
*/
|
||||||
|
void tee_flush_all_shm_dcache(struct udevice *dev);
|
||||||
|
|
||||||
#endif /* __TEE_H */
|
#endif /* __TEE_H */
|
||||||
|
|
Loading…
Reference in a new issue