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  */
26 typedef 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  */
53 typedef 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  */
157 status_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  */
168 status_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  */
181 status_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  */
194 status_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  */
208 status_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  */
220 status_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_