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 */
32typedef 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 */
43typedef struct buffer_sink {
44 void *data;
45 sink_func_ptr sink;
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 */
104size_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 */
123size_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 */
137size_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 */
152size_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 */
176size_t base_vfprintf(buffer_sink_t out, const char *format, va_list args);
177
178/**
179 * Configuration options for `base_hexdump` and friends.
180 */
181typedef struct base_hexdump_fmt {
182 /** How many bytes to print per word of output. */
184 /** How many words (as defined above) per line of output. */
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];
193
194/**
195 * The default alphabet used by `base_hexdump()` functions.
196 */
197extern 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 */
206size_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 */
217size_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 */
231size_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 */
240size_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 */
252size_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 */
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 */
285
286#endif // OPENTITAN_SW_DEVICE_LIB_RUNTIME_PRINT_H_