Software APIs
print.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_RUNTIME_PRINT_H_
6
#define OPENTITAN_SW_DEVICE_LIB_RUNTIME_PRINT_H_
7
8
#include <stdarg.h>
9
#include <stddef.h>
10
11
#include "
sw/device/lib/dif/dif_gpio.h
"
12
#include "
sw/device/lib/dif/dif_spi_device.h
"
13
#include "
sw/device/lib/dif/dif_uart.h
"
14
15
/**
16
* @file
17
* @brief Libc-like printing facilities.
18
*
19
* This header provides libc-like printing facilities, which is agnostic of the
20
* underlying hardware printing mechanism.
21
*
22
* We avoid using libc names here, since we do not support the full suite of
23
* format specifier syntax, and use a different character sink type instead of
24
* the traditional `FILE *`.
25
*
26
* All functions in this file should be machine word size agnostic, that is, the
27
* same code should work correctly on both 32-bit and 64-bit machines, though
28
* formatting, where the exact format style is unspecified, is allowed to vary
29
* slightly on machine word size.
30
*/
31
32
/**
33
* Function pointer type for data sink.
34
* The function should return the number of bytes actually written.
35
*/
36
typedef
size_t (*
sink_func_ptr
)(
void
*data,
const
char
*buf,
size_t
len);
37
38
/**
39
* A buffer_sink_t represents a place to write bytes to, implemented as a
40
* C-style "closure".
41
*
42
* It consists of a generic data pointer, which can hold instance-specific
43
* information, and a sink function, which takes the data pointer, a buffer, and
44
* that buffer's length.
45
*
46
*/
47
typedef
struct
buffer_sink
{
48
void
*data;
49
sink_func_ptr
sink;
50
}
buffer_sink_t
;
51
52
/**
53
* Returns a function pointer to the spi device sink function.
54
*/
55
sink_func_ptr
get_spi_device_sink
(
void
);
56
57
/**
58
* Returns a function pointer to the uart sink function.
59
*/
60
sink_func_ptr
get_uart_sink
(
void
);
61
62
/**
63
* Prints out a message to stdout, formatted according to the format string
64
* `format`.
65
*
66
* The definition of "stdout" is not provided by this library; rather, it must
67
* be initialized using `base_set_stdout()`.
68
*
69
* This function supports a subset of the format specifiers provided by standard
70
* C `printf`. Those are, namely:
71
* - %%, which prints a percent sign.
72
* - %c, which prints the lowest byte of a uint32_t as a character.
73
* - %s, which prints a NUL-terminated string.
74
* - %d and %i, which print a signed decimal uint32_t.
75
* - %u, which prints an unsigned decimal uint32_t.
76
* - %o, which prints an unsigned octal uint32_t.
77
* - %x and %X, which print an unsigned hex uint32_t.
78
* - %p, which prints a pointer in a consistent but unspecified way.
79
*
80
* Additionally, three SystemVerilog format specifiers are supported:
81
* - %h and %H, which are aliases for %x and %X, respectively.
82
* - %b, which prints an unsigned binary uint32_t.
83
*
84
* Finally, additional nonstandard format specifiers is supported:
85
* - %C prints a 'FourCC' style uint32_t (ASCII bytes in little-endian order).
86
* - %!s, which takes a size_t followed by a pointer to a buffer, and prints
87
* out that many characters from the buffer.
88
* - %!x, %!X, %!y, and %!Y, which are like %!s but print out a hex dump
89
* instead; casing is as with %x, and %!x will print in big-endian order
90
* (i.e., last byte printed first) while %!y will print in little-endian
91
* order (i.e., first byte printed first). This makes sure %!x is consistent
92
* with %x.
93
* - %!b, which takes a bool and prints either true or false.
94
* - %r, which takes a status_t and prints the status, argument and module ID.
95
* - %!r, which takes a status_t and prints the status, argument and module ID
96
* as JSON.
97
*
98
* When compiled for a DV testbench, this function will not read any pointers,
99
* and as such the specifiers %s, %!s, %!x, %!X, %!y, and %!Y will behave as if
100
* they were printing garbage, and are, as such, unsupported.
101
*
102
* This function furthermore supports width modifiers for integer specifiers,
103
* such as `%010d`. It does not support dynamic widths like `%*d`. If the width
104
* specifier starts with a `0`, it is padded with zeroes; otherwise, it is
105
* padded with spaces, consistent with the standard C behavior.
106
*
107
* Of course, providing arguments for formatting which are incompatible with a
108
* given format specifier is Undefined Behavior.
109
*
110
* Note that for logging in DV, the following script updates the format
111
* specifiers supported in C above and changes them to match the SystemVerilog
112
* language semantics: util/device_sw_utils/extract_sw_logs.py
113
* It also makes fixes as needed for custom specifiers such as %!s.
114
*
115
* @param format the format spec.
116
* @param ... values to interpolate in the format spec.
117
*/
118
size_t
base_printf
(
const
char
*format, ...);
119
120
/**
121
* Prints out a message to stdout, formatted according to the format string
122
* `format`.
123
*
124
* This function is identical to `base_printf`, except in that it takes a
125
* `va_list` instead of having a vararg parameter. This function plays a role
126
* analogous to `base_vfprintf`, for functions that wish to use the currently
127
* set `stdout`.
128
*
129
* This function *does not* take ownership of `args`; callers are responsible
130
* for calling `va_end`.
131
*
132
* See `base_printf()` for the semantics of the format specification.
133
*
134
* @param format the format spec.
135
* @param args values to interpolate in the format spec.
136
*/
137
size_t
base_vprintf
(
const
char
*format, va_list args);
138
139
/*
140
* Prints a message to the buffer `buf`, capped at a given length.
141
*
142
* It goes without saying that the caller must ensure the given buffer is large
143
* enough; failure to do so is Undefined Behavior.
144
*
145
* See `base_printf()` for the semantics of the format specification.
146
*
147
* @param buf a buffer to print to.
148
* @param format the format spec.
149
* @param ... values to interpolate in the format spec.
150
*/
151
size_t
base_snprintf(
char
*buf,
size_t
len,
const
char
*format, ...);
152
153
/**
154
* Prints a message to the sink `out`.
155
*
156
* If `out.sink` is `NULL`, writes are treated as-if they were written to a
157
* UNIX-like /dev/null: writes succeed, but the actual bytes are not printed
158
* anywhere.
159
*
160
* See `base_printf()` for the semantics of the format specification.
161
*
162
* @param out a sink to print to.
163
* @param format the format spec.
164
* @param ... values to interpolate in the format spec.
165
*/
166
size_t
base_fprintf
(
buffer_sink_t
out,
const
char
*format, ...);
167
168
/**
169
* Prints a message to the sink `out`.
170
*
171
* This function is identical to `base_fprintf`, except in that it takes a
172
* `va_list` instead of having a vararg parameter. This function is provided
173
* not for calling directly, but rather for being called by functions that
174
* already take a variable number of arguments, and wish to make use of
175
* formatting facilities.
176
*
177
* This function *does not* take ownership of `args`; callers are responsible
178
* for calling `va_end`.
179
*
180
* If `out.sink` is `NULL`, writes are treated as-if they were written to a
181
* UNIX-like /dev/null: writes succeed, but the actual bytes are not printed
182
* anywhere.
183
*
184
* See `base_printf()` for the semantics of the format specification.
185
*
186
* @param out a sink to print to.
187
* @param format the format spec.
188
* @param args values to interpolate in the format spec.
189
*/
190
size_t
base_vfprintf
(
buffer_sink_t
out,
const
char
*format, va_list args);
191
192
/**
193
* Configuration options for `base_hexdump` and friends.
194
*/
195
typedef
struct
base_hexdump_fmt
{
196
/** How many bytes to print per word of output. */
197
size_t
bytes_per_word
;
198
/** How many words (as defined above) per line of output. */
199
size_t
words_per_line
;
200
/**
201
* The alphabet to use for char-ifying a byte.
202
*
203
* These characters will be written as-is to the sink.
204
*/
205
const
char (*
alphabet
)[256];
206
}
base_hexdump_fmt_t
;
207
208
/**
209
* The default alphabet used by `base_hexdump()` functions.
210
*/
211
extern
const
char
kBaseHexdumpDefaultFmtAlphabet[256];
212
213
/**
214
* Dumps `hex` in an xxd-style hexdump to stdout, using default formatting
215
* options.
216
*
217
* @param buf the buffer to dump.
218
* @param len the number of bytes to dump from hex.
219
*/
220
size_t
base_hexdump
(
const
char
*buf,
size_t
len);
221
222
/**
223
* Dumps `hex` in an xxd-style hexdump to the buffer `buf`, capped at the given
224
* length, using default formatting options.
225
*
226
* @param out a buffer to print to.
227
* @param out_len the length of the output buffer.
228
* @param buf the buffer to dump.
229
* @param len the number of bytes to dump from hex.
230
*/
231
size_t
base_snhexdump
(
char
*out,
size_t
out_len,
const
char
*buf,
size_t
len);
232
233
/**
234
* Dumps `hex` in an xxd-style hexdump to `out`, using default formatting
235
* options.
236
*
237
* If `out.sink` is `NULL`, writes are treated as-if they were written to a
238
* UNIX-like /dev/null: writes succeed, but the actual bytes are not printed
239
* anywhere.
240
*
241
* @param out a sink to print to.
242
* @param buf the buffer to dump.
243
* @param len the number of bytes to dump from hex.
244
*/
245
size_t
base_fhexdump
(
buffer_sink_t
out,
const
char
*buf,
size_t
len);
246
247
/**
248
* Dumps `hex` in an xxd-style hexdump to stdout.
249
*
250
* @param fmt the format for dumping.
251
* @param buf the buffer to dump.
252
* @param len the number of bytes to dump from hex.
253
*/
254
size_t
base_hexdump_with
(
base_hexdump_fmt_t
fmt,
const
char
*buf,
size_t
len);
255
256
/**
257
* Dumps `hex` in an xxd-style hexdump to the buffer `buf`, capped at the given
258
* length.
259
*
260
* @param out a buffer to print to.
261
* @param out_len the length of the output buffer.
262
* @param fmt the format for dumping.
263
* @param buf the buffer to dump.
264
* @param len the number of bytes to dump from hex.
265
*/
266
size_t
base_snhexdump_with
(
char
*out,
size_t
out_len,
base_hexdump_fmt_t
fmt,
267
const
char
*buf,
size_t
len);
268
269
/**
270
* Dumps `hex` in an xxd-style hexdump to `out`.
271
*
272
* If `out.sink` is `NULL`, writes are treated as-if they were written to a
273
* UNIX-like /dev/null: writes succeed, but the actual bytes are not printed
274
* anywhere.
275
*
276
* @param out a sink to print to.
277
* @param fmt the format for dumping.
278
* @param buf the buffer to dump.
279
* @param len the number of bytes to dump from hex.
280
*/
281
size_t
base_fhexdump_with
(
buffer_sink_t
out,
base_hexdump_fmt_t
fmt,
282
const
char
*buf,
size_t
len);
283
284
/**
285
* Sets what the "stdout" sink is, which is used by `base_printf()`.
286
*
287
* The default sink behaves like /dev/null on a standard UNIX system: writes
288
* are treated as successful, but the contents of buffers are ignored.
289
*
290
* As such, this function must be called for printed messages to wind up
291
* somewhere.
292
*
293
* Passing in `NULL` instead of a real function pointer will reset stdout to
294
* the default /dev/null behavior.
295
*
296
* @param out the sink to use for "default" printing.
297
*/
298
void
base_set_stdout
(
buffer_sink_t
out);
299
300
/**
301
* Configures SPI device GPIO TX indicator pin for `base_print.h` to use.
302
*
303
* Note that this function will save `gpio` in a global variable, so the
304
* pointer must have static storage duration.
305
*
306
* @param gpio The GPIO handle to use for the SPI console TX indicator pin.
307
* @param tx_indicator_pin The GPIO pin to use for the SPI console TX indicator.
308
*/
309
void
base_spi_device_set_gpio_tx_indicator
(
dif_gpio_t
*gpio,
310
dif_gpio_pin_t
tx_indicator_pin);
311
312
/**
313
* Configures SPI device stdout for `base_print.h` to use.
314
*
315
* Note that this function will save `spi_device` in a global variable, so the
316
* pointer must have static storage duration.
317
*
318
* @param spi_device The SPI device handle to use for stdout.
319
*/
320
void
base_spi_device_stdout
(
const
dif_spi_device_handle_t
*spi_device);
321
322
/**
323
* Configures UART stdout for `base_print.h` to use.
324
*
325
* Note that this function will save `uart` in a global variable, so the pointer
326
* must have static storage duration.
327
*
328
* @param uart The UART handle to use for stdout.
329
*/
330
void
base_uart_stdout
(
const
dif_uart_t
*uart);
331
332
#endif
// OPENTITAN_SW_DEVICE_LIB_RUNTIME_PRINT_H_
sw
device
lib
runtime
print.h
Return to
OpenTitan Documentation