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