mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-20 08:58:52 +09:00
![Heiko Stuebner](/assets/img/avatar_default.png)
OP-TEE can get supplied with a devicetree and will then insert its firmware node and reserved-memory sections into it. As this devicetree often is not the one supplied to a later loaded kernel, a previous commit added functionality to transfer these nodes onto that new devicetree. To make sure this functionality stays intact, also add a test for the transfer functionality. Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com> Reviewed-by: Simon Glass <sjg@chromium.org>
150 lines
3.7 KiB
C
150 lines
3.7 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <errno.h>
|
|
#include <fdt_support.h>
|
|
#include <malloc.h>
|
|
#include <tee/optee.h>
|
|
|
|
#include <linux/sizes.h>
|
|
|
|
#include <test/ut.h>
|
|
#include <test/optee.h>
|
|
#include <test/suites.h>
|
|
|
|
/* 4k ought to be enough for anybody */
|
|
#define FDT_COPY_SIZE (4 * SZ_1K)
|
|
|
|
extern u32 __dtb_test_optee_base_begin;
|
|
extern u32 __dtb_test_optee_optee_begin;
|
|
extern u32 __dtb_test_optee_no_optee_begin;
|
|
|
|
static void *fdt;
|
|
static bool expect_success;
|
|
|
|
static int optee_fdt_firmware(struct unit_test_state *uts)
|
|
{
|
|
const void *prop;
|
|
int offs, len;
|
|
|
|
offs = fdt_path_offset(fdt, "/firmware/optee");
|
|
ut_assert(expect_success ? offs >= 0 : offs < 0);
|
|
|
|
/* only continue if we have an optee node */
|
|
if (offs < 0)
|
|
return CMD_RET_SUCCESS;
|
|
|
|
prop = fdt_getprop(fdt, offs, "compatible", &len);
|
|
ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
|
|
|
|
prop = fdt_getprop(fdt, offs, "method", &len);
|
|
ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
|
|
|
|
return CMD_RET_SUCCESS;
|
|
}
|
|
OPTEE_TEST(optee_fdt_firmware, 0);
|
|
|
|
static int optee_fdt_protected_memory(struct unit_test_state *uts)
|
|
{
|
|
int offs, subnode;
|
|
bool found;
|
|
|
|
offs = fdt_path_offset(fdt, "/firmware/optee");
|
|
ut_assert(expect_success ? offs >= 0 : offs < 0);
|
|
|
|
/* only continue if we have an optee node */
|
|
if (offs < 0)
|
|
return CMD_RET_SUCCESS;
|
|
|
|
/* optee inserts its memory regions as reserved-memory nodes */
|
|
offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
|
|
ut_assert(offs >= 0);
|
|
|
|
subnode = fdt_first_subnode(fdt, offs);
|
|
ut_assert(subnode);
|
|
|
|
found = 0;
|
|
while (subnode >= 0) {
|
|
const char *name = fdt_get_name(fdt, subnode, NULL);
|
|
struct fdt_resource res;
|
|
|
|
ut_assert(name);
|
|
|
|
/* only handle optee reservations */
|
|
if (strncmp(name, "optee", 5))
|
|
continue;
|
|
|
|
found = true;
|
|
|
|
/* check if this subnode has a reg property */
|
|
ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
|
|
subnode = fdt_next_subnode(fdt, subnode);
|
|
}
|
|
|
|
ut_assert(found);
|
|
|
|
return CMD_RET_SUCCESS;
|
|
}
|
|
OPTEE_TEST(optee_fdt_protected_memory, 0);
|
|
|
|
int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
{
|
|
struct unit_test *tests = ll_entry_start(struct unit_test,
|
|
optee_test);
|
|
const int n_ents = ll_entry_count(struct unit_test, optee_test);
|
|
struct unit_test_state *uts;
|
|
void *fdt_optee = &__dtb_test_optee_optee_begin;
|
|
void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
|
|
void *fdt_base = &__dtb_test_optee_base_begin;
|
|
int ret = -ENOMEM;
|
|
|
|
uts = calloc(1, sizeof(*uts));
|
|
if (!uts)
|
|
return -ENOMEM;
|
|
|
|
ut_assertok(fdt_check_header(fdt_base));
|
|
ut_assertok(fdt_check_header(fdt_optee));
|
|
ut_assertok(fdt_check_header(fdt_no_optee));
|
|
|
|
fdt = malloc(FDT_COPY_SIZE);
|
|
if (!fdt)
|
|
return ret;
|
|
|
|
/*
|
|
* Resize the FDT to 4k so that we have room to operate on
|
|
*
|
|
* (and relocate it since the memory might be mapped
|
|
* read-only)
|
|
*/
|
|
ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
|
|
|
|
/*
|
|
* (1) Try to copy optee nodes from empty dt.
|
|
* This should still run successfully.
|
|
*/
|
|
ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
|
|
|
|
expect_success = false;
|
|
ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
|
|
|
|
/* (2) Try to copy optee nodes from prefilled dt */
|
|
ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
|
|
|
|
expect_success = true;
|
|
ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
|
|
|
|
/* (3) Try to copy OP-TEE nodes into a already filled DT */
|
|
ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
|
|
ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
|
|
|
|
expect_success = true;
|
|
ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
|
|
|
|
free(fdt);
|
|
return ret;
|
|
}
|