1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#pragma once 14 15/* Include Kconfig variables. */ 16#include <autoconf.h> 17#include <sel4test/gen_config.h> 18 19#include <sel4/sel4.h> 20 21#include <utils/attribute.h> 22#include <sel4test/testutil.h> 23#include <vka/vka.h> 24#include <vspace/vspace.h> 25#include <sel4platsupport/timer.h> 26#include <sync/mutex.h> 27#include <sel4utils/elf.h> 28#include <sel4rpc/client.h> 29 30#include <inttypes.h> 31#include <stdbool.h> 32#include <stddef.h> 33#include <stdint.h> 34#include <stdio.h> 35#include <string.h> 36 37/* max test name size */ 38#define TEST_NAME_MAX (64 - 4 * sizeof(seL4_Word)) 39 40#define MAX_REGIONS 4 41 42/* Contains information about the test environment for regular tests, bootstrap tests do 43 * not use this environment */ 44struct env { 45 /* An initialised vka that may be used by the test. */ 46 vka_t vka; 47 /* virtual memory management interface */ 48 vspace_t vspace; 49 /* abstract interface over application init */ 50 simple_t simple; 51 /* notification for timer */ 52 vka_object_t timer_notification; 53 /* RPC client for serial server resource allocation */ 54 sel4rpc_client_t rpc_client; 55 56 /* caps for the current process */ 57 seL4_CPtr cspace_root; 58 seL4_CPtr page_directory; 59 seL4_CPtr endpoint; 60 seL4_CPtr tcb; 61 seL4_CPtr timer_untyped; 62 seL4_CPtr asid_pool; 63 seL4_CPtr asid_ctrl; 64 seL4_CPtr sched_ctrl; 65#ifdef CONFIG_IOMMU 66 seL4_CPtr io_space; 67#endif /* CONFIG_IOMMU */ 68#ifdef CONFIG_TK1_SMMU 69 seL4_SlotRegion io_space_caps; 70#endif 71 seL4_Word cores; 72 seL4_CPtr domain; 73 seL4_CPtr device_frame; 74 75 int priority; 76 int cspace_size_bits; 77 int num_regions; 78 sel4utils_elf_region_t regions[MAX_REGIONS]; 79}; 80typedef struct env *env_t; 81 82/* Prototype of a test function. Returns false on failure. */ 83typedef int (*test_fn)(uintptr_t environment); 84 85/* Test type definitions. */ 86typedef enum test_type_name {BOOTSTRAP = 0, BASIC} test_type_name_t; 87typedef struct testcase testcase_t; // Forward type declaration. 88typedef struct test_type { 89 /* Represents a single test type. See comment for `struct testcase` for info about ALIGN(32). */ 90 const char *name; 91 test_type_name_t id; 92 // Function called before and after all the tests for this test type have been run. 93 void (*set_up_test_type)(uintptr_t e); 94 void (*tear_down_test_type)(uintptr_t e); 95 // Function called before and after each test for this test type. 96 void (*set_up)(uintptr_t e); 97 void (*tear_down)(uintptr_t e); 98 // Run the test. Different tests take different environments 99 test_result_t (*run_test)(struct testcase *test, uintptr_t e); 100} ALIGN(32) test_type_t; 101 102/* Declare a test type. 103 * For now, we put the test types in a separate elf section. */ 104#define DEFINE_TEST_TYPE(_name, _id, _set_up_test_type, _tear_down_test_type, _set_up, _tear_down, _run_test) \ 105 __attribute__((used)) __attribute__((section("_test_type"))) struct test_type TEST_TYPE_ ##_name = { \ 106 .name = #_name, \ 107 .id = _id, \ 108 .set_up_test_type = _set_up_test_type, \ 109 .tear_down_test_type = _tear_down_test_type, \ 110 .set_up = _set_up, \ 111 .tear_down = _tear_down, \ 112 .run_test = _run_test, \ 113}; 114 115/* Represents a single testcase. 116 * Because this struct is used to declare variables that get 117 * placed into custom sections, that we later treat as an array, 118 * we need to make sure the struct is aligned and filled to the 119 * nearest power of two to avoid gcc placing arbitrary padding between them. 120 * 121 * The declaration below ensures that the actual size of 122 * the objects in the section is the same as the size reported 123 * by sizeof(struct testcase), allowing as to treat the items 124 * in the section as an array */ 125struct testcase { 126 char name[TEST_NAME_MAX]; 127 const char *description; 128 test_fn function; 129 seL4_Word test_type; 130 seL4_Word enabled; 131} PACKED; 132typedef struct testcase ALIGN(sizeof(struct testcase)) testcase_t; 133 134/* Declare a testcase. 135 * Must be declared using C89 style (#_name, _desc, _func...) instead of 136 * C99 style (name = _name, desc = _desc, func = _func...) to make sure 137 * that it is accepted by C++ compilers. 138 */ 139#define DEFINE_TEST_WITH_TYPE(_name, _description, _function, _test_type, _enabled) \ 140 __attribute__((used)) __attribute__((section("_test_case"))) struct testcase TEST_ ## _name = { \ 141 #_name, \ 142 _description, \ 143 (test_fn)_function, \ 144 _test_type, \ 145 _enabled, \ 146}; 147 148#define DEFINE_TEST(_name, _description, _function, _enabled) DEFINE_TEST_WITH_TYPE(_name, _description, _function, BASIC, _enabled) 149 150#define DEFINE_TEST_BOOTSTRAP(_name, _description, _function, _enabled) DEFINE_TEST_WITH_TYPE(_name, _description, _function, BOOTSTRAP, _enabled) 151/**/ 152 153/* Definitions so that we can find the test types */ 154extern struct test_type __start__test_type[]; 155extern struct test_type __stop__test_type[]; 156 157/* Definitions so that we can find the test cases */ 158extern testcase_t __start__test_case[]; 159extern testcase_t __stop__test_case[]; 160 161static inline int test_type_comparator(const void *a, const void *b) 162{ 163 const struct test_type **ta = (const struct test_type **) a; 164 const struct test_type **tb = (const struct test_type **) b; 165 if ((*ta)->id > (*tb)->id) { 166 return 1; 167 } else if ((*ta)->id < (*tb)->id) { 168 return -1; 169 } 170 171 return 0; 172} 173 174static inline int test_comparator(const void *a, const void *b) 175{ 176 const struct testcase **ta = (const struct testcase **)a; 177 const struct testcase **tb = (const struct testcase **)b; 178 return strcmp((*ta)->name, (*tb)->name); 179} 180 181/* Fails a test case, stop running the rest of the test, but keep running other tests. */ 182static inline test_result_t _test_fail(const char *condition, const char *file, int line) 183{ 184 _sel4test_failure(condition, file, line); 185 return FAILURE; 186} 187 188/* Fails a test case, keep running the rest of the test, then keep running other tests. */ 189static inline void _test_error(const char *condition, const char *file, int line) 190{ 191 192 _sel4test_report_error(condition, file, line); 193} 194 195/* Fails a test case, stop everything. */ 196static inline test_result_t _test_abort(const char *condition, const char *file, int line) 197{ 198 _sel4test_failure(condition, file, line); 199 return ABORT; 200} 201 202static inline void print_error_in_ipc(seL4_Error e) 203{ 204#ifdef CONFIG_KERNEL_INVOCATION_REPORT_ERROR_IPC 205 // If it hasnt been printed already 206 if (!seL4_CanPrintError() && e != seL4_NoError) { 207 printf("%s", seL4_GetDebugError()); 208 } 209#endif 210} 211 212#define test_error_eq(e, c) \ 213 if (!((e) == (c))) { \ 214 print_error_in_ipc(e); \ 215 return _test_fail(#e, __FILE__, __LINE__); \ 216 } 217#define test_assert(e) if (!(e)) return _test_fail(#e, __FILE__, __LINE__) 218#define test_check(e) if (!(e)) _test_error(#e, __FILE__, __LINE__) 219#define test_assert_fatal(e) if (!(e)) return _test_abort(#e, __FILE__, __LINE__) 220 221#define __TEST_BUFFER_SIZE 200 222#define test_op_type(a, b, op, t, name_a, name_b, cast) \ 223 do {\ 224 if (!(a op b)) { \ 225 int len = snprintf(NULL, 0, "Check %s(" t ") %s %s(" t ") failed.",\ 226 #name_a, (cast) a, #op, #name_b, (cast) b) + 1; \ 227 char buffer[len]; \ 228 snprintf(buffer, len, "Check %s(" t ") %s %s(" t ") failed.",\ 229 #name_a, (cast) a, #op, #name_b, (cast) b); \ 230 _test_error(buffer, __FILE__, __LINE__); \ 231 }\ 232 } while (0) 233 234#define test_op(a, b, op) \ 235 do { \ 236 typeof (a) _a = (a); \ 237 typeof (b) _b = (b); \ 238 if (sizeof(_a) != sizeof(_b)) { \ 239 int len = snprintf(NULL, 0, "%s (size %zu) != %s (size %zu), use of test_eq incorrect", #a,\ 240 sizeof(_a), #b, sizeof(_b)) + 1;\ 241 char buffer[len];\ 242 snprintf(buffer, len, "%s (size %zu) != %s (size %zu), use of test_eq incorrect", #a, sizeof(_a),\ 243 #b, sizeof(_b));\ 244 _test_error(buffer, __FILE__, __LINE__);\ 245 } else if (TYPES_COMPATIBLE(typeof(_a), int)) {\ 246 test_op_type(_a, _b, op, "%d", a, b, int); \ 247 } else if (TYPES_COMPATIBLE(typeof(_a), long)) {\ 248 test_op_type(_a, _b, op, "%ld", a, b, long); \ 249 } else if (TYPES_COMPATIBLE(typeof(_a), long long)) {\ 250 test_op_type(_a, _b, op, "%lld", a, b, long long); \ 251 } else if (TYPES_COMPATIBLE(typeof(_a), unsigned int)) {\ 252 test_op_type(_a, _b, op, "%u", a, b, unsigned int); \ 253 } else if (TYPES_COMPATIBLE(typeof(_a), unsigned long)) {\ 254 test_op_type(_a, _b, op, "%lu", a, b, unsigned long); \ 255 } else if (TYPES_COMPATIBLE(typeof(_a), unsigned long long)) {\ 256 test_op_type(_a, _b, op, "%llu", a, b, unsigned long long); \ 257 } else if (TYPES_COMPATIBLE(typeof(_a), char)) {\ 258 test_op_type(_a, _b, op, "%c", a, b, char); \ 259 } else if (TYPES_COMPATIBLE(typeof(_a), uintptr_t)) {\ 260 test_op_type(_a, _b, op, "0x%" PRIxPTR, a, b, uintptr_t);\ 261 } else { \ 262 _test_error("Cannot use test_op on this type", __FILE__, __LINE__);\ 263 }\ 264 } while (0) 265 266/* Pretty printed test_check wrapper macros for basic comparisons on base types, 267 * which output the values and variable names to aid debugging */ 268#define test_eq(a, b) test_op(a, b, ==) 269#define test_neq(a, b) test_op(a, b, !=) 270#define test_gt(a, b) test_op(a, b, >) 271#define test_geq(a, b) test_op(a, b, >=) 272#define test_lt(a, b) test_op(a, b, <) 273#define test_leq(a, b) test_op(a, b, <=) 274 275#define __TEST_MAX_STRING 50 276#define test_strop(a, b, op) \ 277 do {\ 278 if (strnlen(a, __TEST_MAX_STRING) == __TEST_MAX_STRING) {\ 279 _test_error("String " #a " too long for test_str* macros", __FILE__, __LINE__);\ 280 } else if (strnlen(b, __TEST_MAX_STRING) == __TEST_MAX_STRING) {\ 281 _test_error("String " #b " too long for test_str* macros", __FILE__, __LINE__);\ 282 } else if (!(strncmp(a, b, __TEST_MAX_STRING)) op 0) {\ 283 char buffer[__TEST_BUFFER_SIZE + 2 * __TEST_MAX_STRING];\ 284 snprintf(buffer, sizeof(buffer),\ 285 "Check %s(%s) %s %s(%s) failed.", #a, a, #op, #b, b);\ 286 _test_error(buffer, __FILE__, __LINE__); \ 287 }\ 288 } while (0) 289 290/* Pretty printed test_check wrapper macros for basic comparisons on c strings, 291 * which output the values and variable names to aid debugging */ 292#define test_streq(a, b) test_strop(a, b, ==) 293#define test_strneq(a, b) test_strop(a, b, !=) 294#define test_strge(a, b) test_strop(a, b, >) 295#define test_strgeq(a, b) test_strop(a, b, >=) 296#define test_strle(a, b) test_strop(a, b, <) 297#define test_strleq(a, b) test_strop(a, b, <=) 298 299env_t sel4test_get_env(void); 300 301