blob: 670682f3d41eddf32216d9012b1db4dda7808363 [file] [log] [blame]
Heiko Stuebner1c9bb9b2019-10-23 16:46:41 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
4 */
5
6#include <common.h>
7#include <command.h>
8#include <errno.h>
9#include <fdt_support.h>
10#include <malloc.h>
11#include <tee/optee.h>
12
13#include <linux/sizes.h>
14
15#include <test/ut.h>
16#include <test/optee.h>
17#include <test/suites.h>
18
19/* 4k ought to be enough for anybody */
20#define FDT_COPY_SIZE (4 * SZ_1K)
21
22extern u32 __dtb_test_optee_base_begin;
23extern u32 __dtb_test_optee_optee_begin;
24extern u32 __dtb_test_optee_no_optee_begin;
25
26static void *fdt;
27static bool expect_success;
28
29static int optee_fdt_firmware(struct unit_test_state *uts)
30{
31 const void *prop;
32 int offs, len;
33
34 offs = fdt_path_offset(fdt, "/firmware/optee");
35 ut_assert(expect_success ? offs >= 0 : offs < 0);
36
37 /* only continue if we have an optee node */
38 if (offs < 0)
39 return CMD_RET_SUCCESS;
40
41 prop = fdt_getprop(fdt, offs, "compatible", &len);
42 ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
43
44 prop = fdt_getprop(fdt, offs, "method", &len);
45 ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
46
47 return CMD_RET_SUCCESS;
48}
49OPTEE_TEST(optee_fdt_firmware, 0);
50
51static int optee_fdt_protected_memory(struct unit_test_state *uts)
52{
53 int offs, subnode;
54 bool found;
55
56 offs = fdt_path_offset(fdt, "/firmware/optee");
57 ut_assert(expect_success ? offs >= 0 : offs < 0);
58
59 /* only continue if we have an optee node */
60 if (offs < 0)
61 return CMD_RET_SUCCESS;
62
63 /* optee inserts its memory regions as reserved-memory nodes */
64 offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
65 ut_assert(offs >= 0);
66
67 subnode = fdt_first_subnode(fdt, offs);
68 ut_assert(subnode);
69
70 found = 0;
71 while (subnode >= 0) {
72 const char *name = fdt_get_name(fdt, subnode, NULL);
73 struct fdt_resource res;
74
75 ut_assert(name);
76
77 /* only handle optee reservations */
78 if (strncmp(name, "optee", 5))
79 continue;
80
81 found = true;
82
83 /* check if this subnode has a reg property */
84 ut_assertok(fdt_get_resource(fdt, subnode, "reg", 0, &res));
85 subnode = fdt_next_subnode(fdt, subnode);
86 }
87
88 ut_assert(found);
89
90 return CMD_RET_SUCCESS;
91}
92OPTEE_TEST(optee_fdt_protected_memory, 0);
93
94int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
95{
96 struct unit_test *tests = ll_entry_start(struct unit_test,
97 optee_test);
98 const int n_ents = ll_entry_count(struct unit_test, optee_test);
99 struct unit_test_state *uts;
100 void *fdt_optee = &__dtb_test_optee_optee_begin;
101 void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
102 void *fdt_base = &__dtb_test_optee_base_begin;
103 int ret = -ENOMEM;
104
105 uts = calloc(1, sizeof(*uts));
106 if (!uts)
107 return -ENOMEM;
108
109 ut_assertok(fdt_check_header(fdt_base));
110 ut_assertok(fdt_check_header(fdt_optee));
111 ut_assertok(fdt_check_header(fdt_no_optee));
112
113 fdt = malloc(FDT_COPY_SIZE);
114 if (!fdt)
115 return ret;
116
117 /*
118 * Resize the FDT to 4k so that we have room to operate on
119 *
120 * (and relocate it since the memory might be mapped
121 * read-only)
122 */
123 ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
124
125 /*
126 * (1) Try to copy optee nodes from empty dt.
127 * This should still run successfully.
128 */
129 ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
130
131 expect_success = false;
132 ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
133
134 /* (2) Try to copy optee nodes from prefilled dt */
135 ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
136
137 expect_success = true;
138 ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
139
140 /* (3) Try to copy OP-TEE nodes into a already filled DT */
141 ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
142 ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
143
144 expect_success = true;
145 ret = cmd_ut_category("optee", tests, n_ents, argc, argv);
146
147 free(fdt);
148 return ret;
149}