1// 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 <log.h>
11#include <malloc.h>
12#include <tee/optee.h>
13
14#include <linux/sizes.h>
15
16#include <test/ut.h>
17#include <test/optee.h>
18#include <test/suites.h>
19
20/* 4k ought to be enough for anybody */
21#define FDT_COPY_SIZE	(4 * SZ_1K)
22
23extern u32 __dtb_test_optee_base_begin;
24extern u32 __dtb_test_optee_optee_begin;
25extern u32 __dtb_test_optee_no_optee_begin;
26
27static void *fdt;
28static bool expect_success;
29
30static int optee_fdt_firmware(struct unit_test_state *uts)
31{
32	const void *prop;
33	int offs, len;
34
35	offs = fdt_path_offset(fdt, "/firmware/optee");
36	ut_assert(expect_success ? offs >= 0 : offs < 0);
37
38	/* only continue if we have an optee node */
39	if (offs < 0)
40		return CMD_RET_SUCCESS;
41
42	prop = fdt_getprop(fdt, offs, "compatible", &len);
43	ut_assertok(strncmp((const char *)prop, "linaro,optee-tz", len));
44
45	prop = fdt_getprop(fdt, offs, "method", &len);
46	ut_assert(strncmp(prop, "hvc", 3) == 0 || strncmp(prop, "smc", 3) == 0);
47
48	return CMD_RET_SUCCESS;
49}
50OPTEE_TEST(optee_fdt_firmware, 0);
51
52static int optee_fdt_protected_memory(struct unit_test_state *uts)
53{
54	int offs, subnode;
55	bool found;
56
57	offs = fdt_path_offset(fdt, "/firmware/optee");
58	ut_assert(expect_success ? offs >= 0 : offs < 0);
59
60	/* only continue if we have an optee node */
61	if (offs < 0)
62		return CMD_RET_SUCCESS;
63
64	/* optee inserts its memory regions as reserved-memory nodes */
65	offs = fdt_subnode_offset(fdt, 0, "reserved-memory");
66	ut_assert(offs >= 0);
67
68	subnode = fdt_first_subnode(fdt, offs);
69	ut_assert(subnode);
70
71	found = 0;
72	while (subnode >= 0) {
73		const char *name = fdt_get_name(fdt, subnode, NULL);
74		struct fdt_resource res;
75
76		ut_assert(name);
77
78		/* only handle optee reservations */
79		if (strncmp(name, "optee", 5))
80			continue;
81
82		found = true;
83
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);
87	}
88
89	ut_assert(found);
90
91	return CMD_RET_SUCCESS;
92}
93OPTEE_TEST(optee_fdt_protected_memory, 0);
94
95int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
96{
97	struct unit_test *tests = UNIT_TEST_SUITE_START(optee_test);
98	const int n_ents = UNIT_TEST_SUITE_COUNT(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}
150