Software APIs
ottf_main.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_TEST_FRAMEWORK_OTTF_MAIN_H_
6 #define OPENTITAN_SW_DEVICE_LIB_TESTING_TEST_FRAMEWORK_OTTF_MAIN_H_
7 
8 #include <stdbool.h>
9 
10 #include "sw/device/lib/base/status.h"
14 #include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
15 #include "sw/device/lib/testing/test_framework/check.h"
16 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
17 
18 /**
19  * @file
20  * @brief Entrypoint definitions for on-device tests
21  */
22 
23 /**
24  * Entry point for a SW on-device (or chip-level) test.
25  *
26  * This function should be defined externally in a standalone SW test, linked
27  * together with this library. This library provides a `main()` function that
28  * does test harness setup, initializes FreeRTOS, and starts a FreeRTOS task
29  * that executes `test_main()`.
30  *
31  * @return success or failure of the test as boolean.
32  */
33 extern bool test_main(void);
34 
35 /**
36  * OTTF Constants.
37  */
38 enum {
39  kOttfFreeRtosMinStackSize = configMINIMAL_STACK_SIZE,
40 };
41 
42 /**
43  * TODO: add description
44  */
45 extern bool manufacturer_pre_test_hook(void);
46 
47 /**
48  * TODO: add description
49  */
50 extern bool manufacturer_post_test_hook(void);
51 
52 /**
53  * Forward declaration of the function pointer prototype to which FreeRTOS (and
54  * transitively OTTF) task functions must conform. We use a forward declaration
55  * here to hide FreeRTOS internals from OTTF users.
56  *
57  * This declaration should match the `TaskFunction_t` type declaration in
58  * `<freertos kernel>/include/projdefs.h`.
59  */
60 typedef void (*ottf_task_t)(void *);
61 
62 /**
63  * Create a FreeRTOS task.
64  *
65  * Tasks should be implemented as functions that never return. However, they may
66  * delete themselves using the `ottf_task_delete_self()` function defined below.
67  *
68  * Additionally, tasks are always run at a priority level higher than that of
69  * the FreeRTOS idle task's (which is a priority of 0).
70  *
71  * See the FreeRTOS `xTaskCreate` documentation for more details:
72  * https://www.freertos.org/a00125.html.
73  *
74  * @param task_function The name of the function that implements the task.
75  * @param task_name A task identification string used to help debugging.
76  * @param task_stack_depth The amount of memory to reserve for the task's stack.
77  * @param task_priority The numerical priority of the task.
78  * @return A boolean encoding the success of the operation.
79  */
80 bool ottf_task_create(ottf_task_t task_function, const char *task_name,
81  configSTACK_DEPTH_TYPE task_stack_depth,
82  uint32_t task_priority);
83 /**
84  * Yield control flow to another FreeRTOS task of equal or higher priority.
85  *
86  * Note, if there are no other tasks of equal or higher priority, then the
87  * calling task will continue executing. See the FreeRTOS `taskYIELD`
88  * documentation for more details:
89  * https://www.freertos.org/a00020.html#taskYIELD.
90  */
91 void ottf_task_yield(void);
92 
93 /**
94  * Delete the calling FreeRTOS task.
95  *
96  * See the FreeRTOS `vTaskDelete` documentation for more details:
97  * https://www.freertos.org/a00126.html.
98  */
99 void ottf_task_delete_self(void);
100 
101 /**
102  * Returns the name of the currently executing FreeRTOS task.
103  *
104  * See the FreeRTOS `pcTaskGetName` documentation for more details:
105  * https://www.freertos.org/a00021.html#pcTaskGetName.
106  */
107 char *ottf_task_get_self_name(void);
108 
109 /**
110  * Execute a test function, profile the execution and log the test result.
111  * Update the result value if there is a failure code.
112  */
113 #define EXECUTE_TEST(result_, test_function_, ...) \
114  do { \
115  LOG_INFO("Starting test " #test_function_ "..."); \
116  uint64_t t_start_ = ibex_mcycle_read(); \
117  status_t local_status = INTO_STATUS(test_function_(__VA_ARGS__)); \
118  uint64_t cycles_ = ibex_mcycle_read() - t_start_; \
119  CHECK(kClockFreqCpuHz <= UINT32_MAX, ""); \
120  uint32_t clock_mhz = (uint32_t)kClockFreqCpuHz / 1000000; \
121  if (status_ok(local_status)) { \
122  if (cycles_ <= UINT32_MAX) { \
123  uint32_t micros = (uint32_t)cycles_ / clock_mhz; \
124  LOG_INFO("Successfully finished test " #test_function_ \
125  " in %u cycles or %u us @ %u MHz.", \
126  (uint32_t)cycles_, micros, clock_mhz); \
127  } else { \
128  uint32_t cycles_lower_ = (uint32_t)(cycles_ & UINT32_MAX); \
129  uint32_t cycles_upper_ = (uint32_t)(cycles_ >> 32); \
130  LOG_INFO("Successfully finished test " #test_function_ \
131  " in 0x%08x%08x cycles.", \
132  cycles_upper_, cycles_lower_); \
133  } \
134  } else { \
135  result_ = local_status; \
136  LOG_ERROR("Finished test " #test_function_ ": %r.", local_status); \
137  } \
138  } while (0)
139 
140 /**
141  * Override the default status report list size. This list is used to store
142  * error statuses in case of failed TRY() and are reported when the test
143  * fails. This must be used at the global scope.
144  */
145 #define OTTF_OVERRIDE_STATUS_REPORT_LIST(list_size) \
146  const size_t kStatusReportListSize = list_size; \
147  status_t status_report_list[list_size];
148 
149 #endif // OPENTITAN_SW_DEVICE_LIB_TESTING_TEST_FRAMEWORK_OTTF_MAIN_H_