1 /*
2  * Copyright 2018 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #pragma once
10 
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <stdnoreturn.h>
15 
16 #include "hf/dlog.h"
17 #include "hf/fdt.h"
18 #include "hf/memiter.h"
19 
20 /*
21  * Define a set up function to be run before every test in a test suite.
22  */
23 #define SET_UP(suite) HFTEST_SET_UP(suite)
24 
25 /*
26  * Define a tear down function to be run after every test in a test suite.
27  */
28 #define TEAR_DOWN(suite) HFTEST_TEAR_DOWN(suite)
29 
30 /*
31  * Define a test as part of a test suite.
32  */
33 #define TEST(suite, test) HFTEST_TEST(suite, test, false)
34 
35 /*
36  * Define a test as part of a test suite and mark it long-running.
37  */
38 #define TEST_LONG_RUNNING(suite, test) HFTEST_TEST(suite, test, true)
39 
40 /*
41  * Define a test service.
42  */
43 #define TEST_SERVICE(service) HFTEST_TEST_SERVICE(service)
44 
45 /* Assertions. */
46 #define ASSERT_EQ(x, y) HFTEST_ASSERT_OP(x, y, ==, true)
47 #define ASSERT_NE(x, y) HFTEST_ASSERT_OP(x, y, !=, true)
48 #define ASSERT_LE(x, y) HFTEST_ASSERT_OP(x, y, <=, true)
49 #define ASSERT_LT(x, y) HFTEST_ASSERT_OP(x, y, <, true)
50 #define ASSERT_GE(x, y) HFTEST_ASSERT_OP(x, y, >=, true)
51 #define ASSERT_GT(x, y) HFTEST_ASSERT_OP(x, y, >, true)
52 
53 #define ASSERT_TRUE(x) ASSERT_EQ(x, true)
54 #define ASSERT_FALSE(x) ASSERT_EQ(x, false)
55 
56 #define EXPECT_EQ(x, y) HFTEST_ASSERT_OP(x, y, ==, false)
57 #define EXPECT_NE(x, y) HFTEST_ASSERT_OP(x, y, !=, false)
58 #define EXPECT_LE(x, y) HFTEST_ASSERT_OP(x, y, <=, false)
59 #define EXPECT_LT(x, y) HFTEST_ASSERT_OP(x, y, <, false)
60 #define EXPECT_GE(x, y) HFTEST_ASSERT_OP(x, y, >=, false)
61 #define EXPECT_GT(x, y) HFTEST_ASSERT_OP(x, y, >, false)
62 
63 #define EXPECT_TRUE(x) EXPECT_EQ(x, true)
64 #define EXPECT_FALSE(x) EXPECT_EQ(x, false)
65 
66 #define FAIL(...) HFTEST_FAIL(true, __VA_ARGS__)
67 
68 /* Service utilities. */
69 #define SERVICE_NAME_MAX_LENGTH 64
70 #define SERVICE_SELECT(vm_id, service, send_buffer) \
71 	HFTEST_SERVICE_SELECT(vm_id, service, send_buffer)
72 
73 #define SERVICE_SEND_BUFFER() HFTEST_SERVICE_SEND_BUFFER()
74 #define SERVICE_RECV_BUFFER() HFTEST_SERVICE_RECV_BUFFER()
75 #define SERVICE_MEMORY_SIZE() HFTEST_SERVICE_MEMORY_SIZE()
76 
77 /*
78  * This must be used exactly once in a test image to signal to the linker that
79  * the .hftest section is allowed to be included in the generated image.
80  */
81 #define HFTEST_ENABLE() __attribute__((used)) int hftest_enable
82 
83 /*
84  * Prefixed to log lines from tests for easy filtering in the console.
85  */
86 #define HFTEST_LOG_PREFIX "[hftest] "
87 
88 /*
89  * Indentation used e.g. to give the reason for an assertion failure.
90  */
91 #define HFTEST_LOG_INDENT "    "
92 
93 /** Initializes stage-1 MMU for tests running in a VM. */
94 bool hftest_mm_init(void);
95 
96 /** Adds stage-1 identity mapping for pages covering bytes [base, base+size). */
97 void hftest_mm_identity_map(const void *base, size_t size, uint32_t mode);
98 
99 void hftest_mm_vcpu_init(void);
100 
101 /**
102  * Returns a pointer to stage-1 mappings.
103  * Note: There is no locking as all existing users are on the same vCPU.
104  */
105 struct mm_stage1_locked hftest_mm_get_stage1(void);
106 
107 /** Returns a pointer to the page-table pool. */
108 struct mpool *hftest_mm_get_ppool(void);
109 
110 /**
111  * Inform a host that this is the start of a test run and obtain the command
112  * line arguments for it.
113  */
114 bool hftest_ctrl_start(const struct fdt *fdt, struct memiter *cmd);
115 
116 /** Inform a host that this test run has finished and clean up. */
117 void hftest_ctrl_finish(void);
118 void hftest_ctrl_reboot(void);
119 
120 /** Parses and run test command */
121 void hftest_command(struct fdt *fdt);
122 
123 /** Reboot the device. */
124 noreturn void hftest_device_reboot(void);
125 
126 /**
127  * Device-specific operation to escape from the test environment.
128  * For example, an Android device with UART test controller will reboot after
129  * every test run back into hftest. So as to flash the device with a different
130  * system image, the device must escape this loop and boot into the Android
131  * bootloader.
132  * If successful, this function will not return.
133  * It may not be supported on all devices.
134  */
135 void hftest_device_exit_test_environment(void);
136 
137 /**
138  * Starts the CPU with the given ID. It will start at the provided entry point
139  * with the provided argument. It is a wrapper around the generic cpu_start()
140  * and takes care of MMU initialization.
141  */
142 bool hftest_cpu_start(uintptr_t id, void *stack, size_t stack_size,
143 		      void (*entry)(uintptr_t arg), uintptr_t arg);
144 
145 uintptr_t hftest_get_cpu_id(size_t index);
146 
147 noreturn void hftest_service_main(const void *fdt_ptr);
148 /* Above this point is the public API. Now include the implementation. */
149 #include "hftest_impl.h"
150