1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
9 #include <fdt_support.h>
12 #include <tee/optee.h>
14 #include <linux/sizes.h>
17 #include <test/optee.h>
18 #include <test/suites.h>
20 /* 4k ought to be enough for anybody */
21 #define FDT_COPY_SIZE (4 * SZ_1K)
23 extern u32 __dtb_test_optee_base_begin;
24 extern u32 __dtb_test_optee_optee_begin;
25 extern u32 __dtb_test_optee_no_optee_begin;
28 static bool expect_success;
30 static int optee_fdt_firmware(struct unit_test_state *uts)
35 offs = fdt_path_offset(fdt, "/firmware/optee");
36 ut_assert(expect_success ? offs >= 0 : offs < 0);
38 /* only continue if we have an optee node */
40 return CMD_RET_SUCCESS;
42 prop = fdt_getprop(fdt, offs, "compatible", &len);
43 ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
45 prop = fdt_getprop(fdt, offs, "method", &len);
46 ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
48 return CMD_RET_SUCCESS;
50 OPTEE_TEST(optee_fdt_firmware, 0);
52 static int optee_fdt_protected_memory(struct unit_test_state *uts)
57 offs = fdt_path_offset(fdt, "/firmware/optee");
58 ut_assert(expect_success ? offs >= 0 : offs < 0);
60 /* only continue if we have an optee node */
62 return CMD_RET_SUCCESS;
64 /* optee inserts its memory regions as reserved-memory nodes */
65 offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
68 subnode = fdt_first_subnode(fdt, offs);
72 while (subnode >= 0) {
73 const char *name = fdt_get_name(fdt, subnode, NULL);
74 struct fdt_resource res;
78 /* only handle optee reservations */
79 if (strncmp(name, "optee", 5))
84 /* check if this subnode has a reg property */
85 ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
86 subnode = fdt_next_subnode(fdt, subnode);
91 return CMD_RET_SUCCESS;
93 OPTEE_TEST(optee_fdt_protected_memory, 0);
95 int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
97 struct unit_test *tests = ll_entry_start(struct unit_test,
99 const int n_ents = ll_entry_count(struct unit_test, optee_test);
100 struct unit_test_state *uts;
101 void *fdt_optee = &__dtb_test_optee_optee_begin;
102 void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
103 void *fdt_base = &__dtb_test_optee_base_begin;
106 uts = calloc(1, sizeof(*uts));
110 ut_assertok(fdt_check_header(fdt_base));
111 ut_assertok(fdt_check_header(fdt_optee));
112 ut_assertok(fdt_check_header(fdt_no_optee));
114 fdt = malloc(FDT_COPY_SIZE);
119 * Resize the FDT to 4k so that we have room to operate on
121 * (and relocate it since the memory might be mapped
124 ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
127 * (1) Try to copy optee nodes from empty dt.
128 * This should still run successfully.
130 ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
132 expect_success = false;
133 ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
135 /* (2) Try to copy optee nodes from prefilled dt */
136 ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
138 expect_success = true;
139 ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
141 /* (3) Try to copy OP-TEE nodes into a already filled DT */
142 ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
143 ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
145 expect_success = true;
146 ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);