Software APIs
otbn_testutils.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_OTBN_TESTUTILS_H_
6#define OPENTITAN_SW_DEVICE_LIB_TESTING_OTBN_TESTUTILS_H_
7
9#include "sw/device/lib/base/status.h"
12
13/**
14 * @file
15 * @brief OpenTitan Big Number Accelerator (OTBN) driver
16 */
17
18/**
19 * Information about an embedded OTBN application image.
20 *
21 * All pointers reference data in the normal CPU address space.
22 *
23 * Use `OTBN_DECLARE_APP_SYMBOLS()` together with `OTBN_APP_T_INIT()` to
24 * initialize this structure.
25 */
26typedef struct otbn_app {
27 /**
28 * Start of OTBN instruction memory.
29 */
30 const uint8_t *imem_start;
31 /**
32 * End of OTBN instruction memory.
33 */
34 const uint8_t *imem_end;
35 /**
36 * Start of initialized OTBN data memory.
37 *
38 * Data in this section is copied into DMEM when the app is loaded.
39 */
40 const uint8_t *dmem_data_start;
41 /**
42 * End of initialized OTBN data memory.
43 */
44 const uint8_t *dmem_data_end;
46
47/**
48 * The address of an OTBN symbol as seen by OTBN
49 *
50 * Use `OTBN_DECLARE_SYMBOL_ADDR()` together with `OTBN_ADDR_T_INIT()` to
51 * initialize this type.
52 */
53typedef uint32_t otbn_addr_t;
54
55/**
56 * Generate the prefix to add to an OTBN symbol name used on the Ibex side
57 *
58 * The result is a pointer to Ibex's rodata that should be used to initialise
59 * memory for that symbol.
60 *
61 * This is needed by the OTBN driver to support DMEM/IMEM ranges but
62 * application code shouldn't need to use this. Use the `otbn_addr_t` type and
63 * supporting macros instead.
64 */
65#define OTBN_SYMBOL_PTR(app_name, sym) _otbn_local_app_##app_name##_##sym
66
67/**
68 * Generate the prefix to add to an OTBN symbol name used on the OTBN side
69 *
70 * The result is a pointer whose integer value is the address by which the
71 * symbol should be accessed in OTBN memory.
72 *
73 * This is an internal macro used in `OTBN_DECLARE_SYMBOL_ADDR` and
74 * `OTBN_ADDR_T_INIT` but application code shouldn't need to use it directly.
75 */
76#define OTBN_SYMBOL_ADDR(app_name, sym) _otbn_remote_app_##app_name##_##sym
77
78/**
79 * Makes a symbol in the OTBN application image available.
80 *
81 * This is needed by the OTBN driver to support DMEM/IMEM ranges but
82 * application code shouldn't need to use this. To get access to OTBN
83 * addresses, use `OTBN_DECLARE_SYMBOL_ADDR` instead.
84 */
85#define OTBN_DECLARE_SYMBOL_PTR(app_name, symbol_name) \
86 extern const uint8_t OTBN_SYMBOL_PTR(app_name, symbol_name)[]
87
88/**
89 * Makes the OTBN address of a symbol in the OTBN application available.
90 *
91 * Symbols are typically function or data pointers, i.e. labels in assembly
92 * code. Unlike OTBN_DECLARE_SYMBOL_PTR, this will work for symbols in the .bss
93 * section (which exist on the OTBN side, even though they don't have backing
94 * data on Ibex).
95 *
96 * Use this macro instead of manually declaring the symbols as symbol names
97 * might change.
98 *
99 * @param app_name Name of the application the function is contained in.
100 * @param symbol_name Name of the symbol (function, label).
101 */
102#define OTBN_DECLARE_SYMBOL_ADDR(app_name, symbol_name) \
103 extern const uint8_t OTBN_SYMBOL_ADDR(app_name, symbol_name)[]
104
105/**
106 * Makes an embedded OTBN application image available for use.
107 *
108 * Make symbols available that indicate the start and the end of instruction
109 * and data memory regions, as they are stored in the device memory.
110 *
111 * Use this macro instead of manually declaring the symbols as symbol names
112 * might change.
113 *
114 * @param app_name Name of the application to load, which is typically the
115 * name of the main (assembly) source file.
116 */
117#define OTBN_DECLARE_APP_SYMBOLS(app_name) \
118 OTBN_DECLARE_SYMBOL_PTR(app_name, _imem_start); \
119 OTBN_DECLARE_SYMBOL_PTR(app_name, _imem_end); \
120 OTBN_DECLARE_SYMBOL_PTR(app_name, _dmem_data_start); \
121 OTBN_DECLARE_SYMBOL_PTR(app_name, _dmem_data_end)
122
123/**
124 * Initializes the OTBN application information structure.
125 *
126 * After making all required symbols from the application image available
127 * through `OTBN_DECLARE_APP_SYMBOLS()`, use this macro to initialize an
128 * `otbn_app_t` struct with those symbols.
129 *
130 * @param app_name Name of the application to load.
131 * @see OTBN_DECLARE_APP_SYMBOLS()
132 */
133#define OTBN_APP_T_INIT(app_name) \
134 ((otbn_app_t){ \
135 .imem_start = OTBN_SYMBOL_PTR(app_name, _imem_start), \
136 .imem_end = OTBN_SYMBOL_PTR(app_name, _imem_end), \
137 .dmem_data_start = OTBN_SYMBOL_PTR(app_name, _dmem_data_start), \
138 .dmem_data_end = OTBN_SYMBOL_PTR(app_name, _dmem_data_end), \
139 })
140
141/**
142 * Initializes an `otbn_addr_t`.
143 */
144#define OTBN_ADDR_T_INIT(app_name, symbol_name) \
145 ((uint32_t)OTBN_SYMBOL_ADDR(app_name, symbol_name))
146
147/**
148 * (Re-)loads the application into OTBN.
149 *
150 * Load the application image with both instruction and data segments into OTBN.
151 *
152 * @param otbn The context object.
153 * @param app The application to load into OTBN.
154 * @return The result of the operation.
155 */
157status_t otbn_testutils_load_app(const dif_otbn_t *otbn, const otbn_app_t app);
158
159/**
160 * Starts the OTBN execute operation.
161 *
162 * Use `otbn_testutils_wait_for_done()` to wait for execution to complete.
163 *
164 * @param otbn The context object.
165 * @return The result of the operation.
166 */
168status_t otbn_testutils_execute(const dif_otbn_t *otbn);
169
170/**
171 * Waits for OTBN to be done with the current operation.
172 *
173 * Polls the status register until OTBN is idle. Produces a CHECK-fail if OTBN
174 * is or becomes locked. Checks that the final error bits match expectations.
175 *
176 * @param otbn The context object.
177 * @param expected_err_bits Expected error bits.
178 * @return The result of the operation.
179 */
181status_t otbn_testutils_wait_for_done(const dif_otbn_t *otbn,
182 dif_otbn_err_bits_t expected_err_bits);
183
184/**
185 * Copies data from the CPU memory to OTBN data memory.
186 *
187 * @param otbn The context object.
188 * @param len_bytes Number of bytes to copy.
189 * @param dest Address of the destination in OTBN's data memory.
190 * @param src Source of the data to copy.
191 * @return The result of the operation.
192 */
194status_t otbn_testutils_write_data(const dif_otbn_t *otbn, size_t len_bytes,
195 const void *src, otbn_addr_t dest);
196
197/**
198 * Copies data from OTBN's data memory to CPU memory.
199 *
200 * @param otbn The context object.
201 * @param len_bytes The number of bytes to copy.
202 * @param src The address in OTBN data memory to copy from.
203 * @param[out] dest The destination of the copied data in main memory
204 * (preallocated).
205 * @return The result of the operation.
206 */
208status_t otbn_testutils_read_data(const dif_otbn_t *otbn, size_t len_bytes,
209 otbn_addr_t src, void *dest);
210
211/**
212 * Writes a LOG_INFO message with the contents of each 256b DMEM word.
213 *
214 * @param otbn The context object.
215 * @param max_addr The highest address to dump. Set to 0 to output the whole
216 * DMEM. Must be a multiple of WLEN.
217 * @return The result of the operation.
218 */
220status_t otbn_testutils_dump_dmem(const dif_otbn_t *otbn, uint32_t max_addr);
221
222#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_OTBN_TESTUTILS_H_