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