1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
5*61046927SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal
6*61046927SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights
7*61046927SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8*61046927SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is
9*61046927SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*61046927SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #ifndef PVR_DUMP_H
25*61046927SAndroid Build Coastguard Worker #define PVR_DUMP_H
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
28*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
29*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
30*61046927SAndroid Build Coastguard Worker #include <stdint.h>
31*61046927SAndroid Build Coastguard Worker #include <stdio.h>
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include "pvr_types.h"
34*61046927SAndroid Build Coastguard Worker #include "pvr_util.h"
35*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
36*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker /** BASIC PRINTING **/
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Worker #define PVR_DUMP_OFFSET_PREFIX "[%0*" PRIx64 "] "
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker /** CONTEXTS **/
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker #define PVR_DUMP_INDENT_SIZE 2U
45*61046927SAndroid Build Coastguard Worker #define PVR_DUMP_FIELD_COLUMN_WIDTH 36U
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Worker /* This is an invalid context used to permanently mark popped contexts as
48*61046927SAndroid Build Coastguard Worker * unusable. All operations on a context check that it's the "top" context
49*61046927SAndroid Build Coastguard Worker * by ensuring it has no active child. The only way to remove the active child
50*61046927SAndroid Build Coastguard Worker * of a context is by popping the active child directly. Assigning an invalid
51*61046927SAndroid Build Coastguard Worker * context as the active child of a context therefore makes it impossible to
52*61046927SAndroid Build Coastguard Worker * use.
53*61046927SAndroid Build Coastguard Worker */
54*61046927SAndroid Build Coastguard Worker extern const struct pvr_dump_ctx __pvr_dump_ctx_invalid;
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx {
57*61046927SAndroid Build Coastguard Worker /* This is const because only the "top" context should ever be modified. It's
58*61046927SAndroid Build Coastguard Worker * fine to extract information from the parent context, but not to modify it.
59*61046927SAndroid Build Coastguard Worker * There is *one* exception: pvr_dump_ctx_pop() must cast away the const to
60*61046927SAndroid Build Coastguard Worker * return the parent context as the new "top" context. This is considered
61*61046927SAndroid Build Coastguard Worker * sound because the parent context was not const when assigned here in
62*61046927SAndroid Build Coastguard Worker * pvr_dump_ctx_push().
63*61046927SAndroid Build Coastguard Worker */
64*61046927SAndroid Build Coastguard Worker const struct pvr_dump_ctx *parent;
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker /* This is const because it's not meant to be used for access - it's just a
67*61046927SAndroid Build Coastguard Worker * way of checking if this context is the "top" context (see the comment on
68*61046927SAndroid Build Coastguard Worker * __pvr_dump_ctx_invalid for more details). Unlike parent, the const
69*61046927SAndroid Build Coastguard Worker * qualifier here should never be cast away.
70*61046927SAndroid Build Coastguard Worker */
71*61046927SAndroid Build Coastguard Worker const struct pvr_dump_ctx *active_child;
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker FILE *file;
74*61046927SAndroid Build Coastguard Worker const char *name;
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker uint32_t allowed_child_depth;
77*61046927SAndroid Build Coastguard Worker uint32_t parent_indent;
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker /* User-modifiable values */
80*61046927SAndroid Build Coastguard Worker uint32_t indent;
81*61046927SAndroid Build Coastguard Worker bool ok;
82*61046927SAndroid Build Coastguard Worker };
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker static inline uint32_t
__pvr_dump_ctx_get_indent(const struct pvr_dump_ctx * const ctx)85*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_get_indent(const struct pvr_dump_ctx *const ctx)
86*61046927SAndroid Build Coastguard Worker {
87*61046927SAndroid Build Coastguard Worker return (ctx->parent_indent + ctx->indent) * PVR_DUMP_INDENT_SIZE;
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker struct pvr_dump_buffer_ctx {
91*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx base;
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker const void *initial_ptr;
94*61046927SAndroid Build Coastguard Worker uint64_t capacity;
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker /* User-modifiable values */
97*61046927SAndroid Build Coastguard Worker const void *ptr;
98*61046927SAndroid Build Coastguard Worker uint64_t remaining_size;
99*61046927SAndroid Build Coastguard Worker };
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker #define pvr_dump_printf(ctx, format, args...) \
102*61046927SAndroid Build Coastguard Worker pvr_dump_printf_cont(ctx, \
103*61046927SAndroid Build Coastguard Worker "%*s" format, \
104*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_get_indent(ctx), \
105*61046927SAndroid Build Coastguard Worker "", \
106*61046927SAndroid Build Coastguard Worker ##args)
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker /* Same as pvr_dump_printf(), but with no indent.
109*61046927SAndroid Build Coastguard Worker * Intended for continuation lines.
110*61046927SAndroid Build Coastguard Worker */
111*61046927SAndroid Build Coastguard Worker #define pvr_dump_printf_cont(ctx, format, args...) \
112*61046927SAndroid Build Coastguard Worker fprintf((ctx)->file, format, ##args)
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker #define pvr_dump_println(ctx, format, args...) \
115*61046927SAndroid Build Coastguard Worker pvr_dump_printf(ctx, format "\n", ##args)
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker #define pvr_dump_println_cont(ctx, format, args...) \
118*61046927SAndroid Build Coastguard Worker pvr_dump_printf_cont(ctx, format "\n", ##args)
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker #define pvr_dump_print_eol(ctx) fprintf((ctx)->file, "\n")
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker #define pvr_dump_mark_section(ctx, format, args...) \
123*61046927SAndroid Build Coastguard Worker do { \
124*61046927SAndroid Build Coastguard Worker pvr_dump_print_eol(ctx); \
125*61046927SAndroid Build Coastguard Worker pvr_dump_println(ctx, "------- " format " -------", ##args); \
126*61046927SAndroid Build Coastguard Worker } while (0)
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker #define pvr_dump_buffer_print_header_prefix(ctx) \
129*61046927SAndroid Build Coastguard Worker do { \
130*61046927SAndroid Build Coastguard Worker struct pvr_dump_buffer_ctx *_prefix_ctx = (ctx); \
131*61046927SAndroid Build Coastguard Worker pvr_dump_printf(&_prefix_ctx->base, \
132*61046927SAndroid Build Coastguard Worker PVR_DUMP_OFFSET_PREFIX, \
133*61046927SAndroid Build Coastguard Worker u64_dec_digits(_prefix_ctx->capacity), \
134*61046927SAndroid Build Coastguard Worker _prefix_ctx->capacity - _prefix_ctx->remaining_size); \
135*61046927SAndroid Build Coastguard Worker } while (0)
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker #define pvr_dump_buffer_print_header_line(ctx, format, args...) \
138*61046927SAndroid Build Coastguard Worker do { \
139*61046927SAndroid Build Coastguard Worker struct pvr_dump_buffer_ctx *_ctx = (ctx); \
140*61046927SAndroid Build Coastguard Worker pvr_dump_buffer_print_header_prefix(_ctx); \
141*61046927SAndroid Build Coastguard Worker pvr_dump_printf_cont(&_ctx->base, format "\n", ##args); \
142*61046927SAndroid Build Coastguard Worker } while (0)
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker #define pvr_dump_msg(ctx, prefix, ret, format, args...) \
145*61046927SAndroid Build Coastguard Worker ({ \
146*61046927SAndroid Build Coastguard Worker bool _ret = (ret); \
147*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx *_ctx = (ctx); \
148*61046927SAndroid Build Coastguard Worker pvr_dump_println(_ctx, "<!" prefix "! " format ">", ##args); \
149*61046927SAndroid Build Coastguard Worker if (!_ret) \
150*61046927SAndroid Build Coastguard Worker _ctx->ok = _ret; \
151*61046927SAndroid Build Coastguard Worker _ret; \
152*61046927SAndroid Build Coastguard Worker })
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker #define pvr_dump_error(ctx, format, args...) \
155*61046927SAndroid Build Coastguard Worker pvr_dump_msg(ctx, "ERROR", false, format, ##args)
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker #define pvr_dump_warn(ctx, format, args...) \
158*61046927SAndroid Build Coastguard Worker pvr_dump_msg(ctx, "WARN", true, format, ##args)
159*61046927SAndroid Build Coastguard Worker
pvr_dump_ctx_require_top(struct pvr_dump_ctx * const ctx)160*61046927SAndroid Build Coastguard Worker static inline bool pvr_dump_ctx_require_top(struct pvr_dump_ctx *const ctx)
161*61046927SAndroid Build Coastguard Worker {
162*61046927SAndroid Build Coastguard Worker if (ctx->active_child != NULL)
163*61046927SAndroid Build Coastguard Worker return pvr_dump_error(ctx, "use of non-top context");
164*61046927SAndroid Build Coastguard Worker
165*61046927SAndroid Build Coastguard Worker return true;
166*61046927SAndroid Build Coastguard Worker }
167*61046927SAndroid Build Coastguard Worker
pvr_dump_indent(struct pvr_dump_ctx * const ctx)168*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_indent(struct pvr_dump_ctx *const ctx)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker ctx->indent++;
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker
pvr_dump_dedent(struct pvr_dump_ctx * const ctx)173*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_dedent(struct pvr_dump_ctx *const ctx)
174*61046927SAndroid Build Coastguard Worker {
175*61046927SAndroid Build Coastguard Worker if (ctx->indent)
176*61046927SAndroid Build Coastguard Worker ctx->indent--;
177*61046927SAndroid Build Coastguard Worker }
178*61046927SAndroid Build Coastguard Worker
__pvr_dump_ctx_init(struct pvr_dump_ctx * const ctx,const struct pvr_dump_ctx * const parent,FILE * const file,const char * const name,const uint32_t allowed_child_depth,const uint32_t parent_indent)179*61046927SAndroid Build Coastguard Worker static inline void __pvr_dump_ctx_init(struct pvr_dump_ctx *const ctx,
180*61046927SAndroid Build Coastguard Worker const struct pvr_dump_ctx *const parent,
181*61046927SAndroid Build Coastguard Worker FILE *const file,
182*61046927SAndroid Build Coastguard Worker const char *const name,
183*61046927SAndroid Build Coastguard Worker const uint32_t allowed_child_depth,
184*61046927SAndroid Build Coastguard Worker const uint32_t parent_indent)
185*61046927SAndroid Build Coastguard Worker {
186*61046927SAndroid Build Coastguard Worker ctx->parent = parent;
187*61046927SAndroid Build Coastguard Worker ctx->active_child = NULL;
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker ctx->file = file;
190*61046927SAndroid Build Coastguard Worker ctx->name = name;
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker ctx->allowed_child_depth = allowed_child_depth;
193*61046927SAndroid Build Coastguard Worker ctx->parent_indent = parent_indent;
194*61046927SAndroid Build Coastguard Worker ctx->indent = 0;
195*61046927SAndroid Build Coastguard Worker ctx->ok = true;
196*61046927SAndroid Build Coastguard Worker }
197*61046927SAndroid Build Coastguard Worker
__pvr_dump_ctx_mark_popped(struct pvr_dump_ctx * const ctx)198*61046927SAndroid Build Coastguard Worker static inline void __pvr_dump_ctx_mark_popped(struct pvr_dump_ctx *const ctx)
199*61046927SAndroid Build Coastguard Worker {
200*61046927SAndroid Build Coastguard Worker ctx->active_child = &__pvr_dump_ctx_invalid;
201*61046927SAndroid Build Coastguard Worker }
202*61046927SAndroid Build Coastguard Worker
pvr_dump_begin(struct pvr_dump_ctx * const root_ctx,FILE * const file,const char * const name,const uint32_t max_depth)203*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_begin(struct pvr_dump_ctx *const root_ctx,
204*61046927SAndroid Build Coastguard Worker FILE *const file,
205*61046927SAndroid Build Coastguard Worker const char *const name,
206*61046927SAndroid Build Coastguard Worker const uint32_t max_depth)
207*61046927SAndroid Build Coastguard Worker {
208*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_init(root_ctx, NULL, file, name, max_depth, 0);
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker flockfile(file);
211*61046927SAndroid Build Coastguard Worker pvr_dump_println(root_ctx, "======= BEGIN %s =======", name);
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
pvr_dump_end(struct pvr_dump_ctx * const root_ctx)214*61046927SAndroid Build Coastguard Worker static inline bool pvr_dump_end(struct pvr_dump_ctx *const root_ctx)
215*61046927SAndroid Build Coastguard Worker {
216*61046927SAndroid Build Coastguard Worker /* In order to end a dump, we must be in a root context (no parent) and have
217*61046927SAndroid Build Coastguard Worker * no active child context.
218*61046927SAndroid Build Coastguard Worker */
219*61046927SAndroid Build Coastguard Worker if (!pvr_dump_ctx_require_top(root_ctx))
220*61046927SAndroid Build Coastguard Worker return false;
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker if (root_ctx->parent)
223*61046927SAndroid Build Coastguard Worker return pvr_dump_error(root_ctx, "ending non-root context");
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker pvr_dump_println(root_ctx, "======= END %s =======", root_ctx->name);
226*61046927SAndroid Build Coastguard Worker funlockfile(root_ctx->file);
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_mark_popped(root_ctx);
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker return true;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker
pvr_dump_ctx_push(struct pvr_dump_ctx * const ctx,struct pvr_dump_ctx * const parent_ctx)233*61046927SAndroid Build Coastguard Worker static inline bool pvr_dump_ctx_push(struct pvr_dump_ctx *const ctx,
234*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx *const parent_ctx)
235*61046927SAndroid Build Coastguard Worker {
236*61046927SAndroid Build Coastguard Worker if (!parent_ctx->ok)
237*61046927SAndroid Build Coastguard Worker return false;
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker if (!parent_ctx->allowed_child_depth)
240*61046927SAndroid Build Coastguard Worker return pvr_dump_error(parent_ctx, "context stack depth limit reached");
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_init(ctx,
243*61046927SAndroid Build Coastguard Worker parent_ctx,
244*61046927SAndroid Build Coastguard Worker parent_ctx->file,
245*61046927SAndroid Build Coastguard Worker parent_ctx->name,
246*61046927SAndroid Build Coastguard Worker parent_ctx->allowed_child_depth - 1,
247*61046927SAndroid Build Coastguard Worker parent_ctx->parent_indent + parent_ctx->indent);
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker parent_ctx->active_child = ctx;
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker return true;
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker static inline struct pvr_dump_ctx *
pvr_dump_ctx_pop(struct pvr_dump_ctx * const ctx)255*61046927SAndroid Build Coastguard Worker pvr_dump_ctx_pop(struct pvr_dump_ctx *const ctx)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx *const parent = (struct pvr_dump_ctx *)ctx->parent;
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker if (!pvr_dump_ctx_require_top(ctx))
260*61046927SAndroid Build Coastguard Worker return NULL;
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker if (!parent) {
263*61046927SAndroid Build Coastguard Worker pvr_dump_error(ctx, "popped root context");
264*61046927SAndroid Build Coastguard Worker return NULL;
265*61046927SAndroid Build Coastguard Worker }
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker parent->active_child = NULL;
268*61046927SAndroid Build Coastguard Worker
269*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_mark_popped(ctx);
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker return parent;
272*61046927SAndroid Build Coastguard Worker }
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker static inline bool
pvr_dump_buffer_ctx_push(struct pvr_dump_buffer_ctx * const ctx,struct pvr_dump_ctx * const parent_ctx,const void * const initial_ptr,const uint64_t size)275*61046927SAndroid Build Coastguard Worker pvr_dump_buffer_ctx_push(struct pvr_dump_buffer_ctx *const ctx,
276*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx *const parent_ctx,
277*61046927SAndroid Build Coastguard Worker const void *const initial_ptr,
278*61046927SAndroid Build Coastguard Worker const uint64_t size)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker if (!pvr_dump_ctx_push(&ctx->base, parent_ctx))
281*61046927SAndroid Build Coastguard Worker return false;
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker ctx->initial_ptr = initial_ptr;
284*61046927SAndroid Build Coastguard Worker ctx->capacity = size;
285*61046927SAndroid Build Coastguard Worker
286*61046927SAndroid Build Coastguard Worker ctx->ptr = initial_ptr;
287*61046927SAndroid Build Coastguard Worker ctx->remaining_size = size;
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker return true;
290*61046927SAndroid Build Coastguard Worker }
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker static inline struct pvr_dump_ctx *
pvr_dump_buffer_ctx_pop(struct pvr_dump_buffer_ctx * const ctx)293*61046927SAndroid Build Coastguard Worker pvr_dump_buffer_ctx_pop(struct pvr_dump_buffer_ctx *const ctx)
294*61046927SAndroid Build Coastguard Worker {
295*61046927SAndroid Build Coastguard Worker return pvr_dump_ctx_pop(&ctx->base);
296*61046927SAndroid Build Coastguard Worker }
297*61046927SAndroid Build Coastguard Worker
298*61046927SAndroid Build Coastguard Worker bool pvr_dump_buffer_hex(struct pvr_dump_buffer_ctx *ctx, uint64_t nr_bytes);
299*61046927SAndroid Build Coastguard Worker
__pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx * ctx,const uint64_t nr_bytes)300*61046927SAndroid Build Coastguard Worker static inline void __pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx *ctx,
301*61046927SAndroid Build Coastguard Worker const uint64_t nr_bytes)
302*61046927SAndroid Build Coastguard Worker {
303*61046927SAndroid Build Coastguard Worker ctx->ptr = (uint8_t *)ctx->ptr + nr_bytes;
304*61046927SAndroid Build Coastguard Worker ctx->remaining_size -= nr_bytes;
305*61046927SAndroid Build Coastguard Worker }
306*61046927SAndroid Build Coastguard Worker
pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx * ctx,const uint64_t nr_bytes)307*61046927SAndroid Build Coastguard Worker static inline bool pvr_dump_buffer_advance(struct pvr_dump_buffer_ctx *ctx,
308*61046927SAndroid Build Coastguard Worker const uint64_t nr_bytes)
309*61046927SAndroid Build Coastguard Worker {
310*61046927SAndroid Build Coastguard Worker if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
311*61046927SAndroid Build Coastguard Worker return false;
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker if (nr_bytes > ctx->remaining_size)
314*61046927SAndroid Build Coastguard Worker return pvr_dump_error(&ctx->base, "advanced past end of context buffer");
315*61046927SAndroid Build Coastguard Worker
316*61046927SAndroid Build Coastguard Worker __pvr_dump_buffer_advance(ctx, nr_bytes);
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker return true;
319*61046927SAndroid Build Coastguard Worker }
320*61046927SAndroid Build Coastguard Worker
__pvr_dump_buffer_rewind(struct pvr_dump_buffer_ctx * ctx,const uint32_t nr_bytes)321*61046927SAndroid Build Coastguard Worker static inline void __pvr_dump_buffer_rewind(struct pvr_dump_buffer_ctx *ctx,
322*61046927SAndroid Build Coastguard Worker const uint32_t nr_bytes)
323*61046927SAndroid Build Coastguard Worker {
324*61046927SAndroid Build Coastguard Worker ctx->ptr = (uint8_t *)ctx->ptr - nr_bytes;
325*61046927SAndroid Build Coastguard Worker ctx->remaining_size += nr_bytes;
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker
pvr_dump_buffer_rewind(struct pvr_dump_buffer_ctx * ctx,const uint32_t nr_bytes)328*61046927SAndroid Build Coastguard Worker static inline bool pvr_dump_buffer_rewind(struct pvr_dump_buffer_ctx *ctx,
329*61046927SAndroid Build Coastguard Worker const uint32_t nr_bytes)
330*61046927SAndroid Build Coastguard Worker {
331*61046927SAndroid Build Coastguard Worker if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
332*61046927SAndroid Build Coastguard Worker return false;
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker if (nr_bytes > ctx->capacity - ctx->remaining_size)
335*61046927SAndroid Build Coastguard Worker return pvr_dump_error(&ctx->base, "rewound past start of context buffer");
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker __pvr_dump_buffer_rewind(ctx, nr_bytes);
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker return true;
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker
pvr_dump_buffer_truncate(struct pvr_dump_buffer_ctx * ctx,const uint64_t remaining_size)342*61046927SAndroid Build Coastguard Worker static inline bool pvr_dump_buffer_truncate(struct pvr_dump_buffer_ctx *ctx,
343*61046927SAndroid Build Coastguard Worker const uint64_t remaining_size)
344*61046927SAndroid Build Coastguard Worker {
345*61046927SAndroid Build Coastguard Worker if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
346*61046927SAndroid Build Coastguard Worker return false;
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker if (remaining_size > ctx->remaining_size)
349*61046927SAndroid Build Coastguard Worker return pvr_dump_error(&ctx->base, "truncated to larger size");
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker ctx->remaining_size = remaining_size;
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker return true;
354*61046927SAndroid Build Coastguard Worker }
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker static inline const void *restrict
pvr_dump_buffer_peek(struct pvr_dump_buffer_ctx * const restrict ctx,const uint64_t nr_bytes)357*61046927SAndroid Build Coastguard Worker pvr_dump_buffer_peek(struct pvr_dump_buffer_ctx *const restrict ctx,
358*61046927SAndroid Build Coastguard Worker const uint64_t nr_bytes)
359*61046927SAndroid Build Coastguard Worker {
360*61046927SAndroid Build Coastguard Worker if (!ctx->base.ok || !pvr_dump_ctx_require_top(&ctx->base))
361*61046927SAndroid Build Coastguard Worker return NULL;
362*61046927SAndroid Build Coastguard Worker
363*61046927SAndroid Build Coastguard Worker if (nr_bytes > ctx->remaining_size) {
364*61046927SAndroid Build Coastguard Worker pvr_dump_error(&ctx->base, "peeked past end of context buffer");
365*61046927SAndroid Build Coastguard Worker return NULL;
366*61046927SAndroid Build Coastguard Worker }
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker return ctx->ptr;
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker static inline const void *restrict
pvr_dump_buffer_take(struct pvr_dump_buffer_ctx * const restrict ctx,const uint64_t nr_bytes)372*61046927SAndroid Build Coastguard Worker pvr_dump_buffer_take(struct pvr_dump_buffer_ctx *const restrict ctx,
373*61046927SAndroid Build Coastguard Worker const uint64_t nr_bytes)
374*61046927SAndroid Build Coastguard Worker {
375*61046927SAndroid Build Coastguard Worker const void *const ptr = pvr_dump_buffer_peek(ctx, nr_bytes);
376*61046927SAndroid Build Coastguard Worker
377*61046927SAndroid Build Coastguard Worker if (ptr)
378*61046927SAndroid Build Coastguard Worker __pvr_dump_buffer_advance(ctx, nr_bytes);
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker return ptr;
381*61046927SAndroid Build Coastguard Worker }
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker static inline void
pvr_dump_buffer_restart(struct pvr_dump_buffer_ctx * const ctx)384*61046927SAndroid Build Coastguard Worker pvr_dump_buffer_restart(struct pvr_dump_buffer_ctx *const ctx)
385*61046927SAndroid Build Coastguard Worker {
386*61046927SAndroid Build Coastguard Worker ctx->ptr = ctx->initial_ptr;
387*61046927SAndroid Build Coastguard Worker ctx->remaining_size = ctx->capacity;
388*61046927SAndroid Build Coastguard Worker }
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker /*****************************************************************************
391*61046927SAndroid Build Coastguard Worker Field printers
392*61046927SAndroid Build Coastguard Worker *****************************************************************************/
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker #define pvr_dump_field(ctx, name, format, args...) \
395*61046927SAndroid Build Coastguard Worker pvr_dump_println(ctx, \
396*61046927SAndroid Build Coastguard Worker "%-*s : " format, \
397*61046927SAndroid Build Coastguard Worker PVR_DUMP_FIELD_COLUMN_WIDTH - \
398*61046927SAndroid Build Coastguard Worker __pvr_dump_ctx_get_indent(ctx), \
399*61046927SAndroid Build Coastguard Worker name, \
400*61046927SAndroid Build Coastguard Worker ##args)
401*61046927SAndroid Build Coastguard Worker
402*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_computed(ctx, name, format, raw_format, args...) \
403*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, format " (" raw_format ")", ##args)
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_error(ctx, format, args...) \
406*61046927SAndroid Build Coastguard Worker ({ \
407*61046927SAndroid Build Coastguard Worker struct pvr_dump_ctx *_ctx = (ctx); \
408*61046927SAndroid Build Coastguard Worker pvr_dump_field(_ctx, "<!ERROR!>", "<" format ">", ##args); \
409*61046927SAndroid Build Coastguard Worker _ctx->ok = false; \
410*61046927SAndroid Build Coastguard Worker false; \
411*61046927SAndroid Build Coastguard Worker })
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker /*****************************************************************************
414*61046927SAndroid Build Coastguard Worker Field printers: integers
415*61046927SAndroid Build Coastguard Worker *****************************************************************************/
416*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u32(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value)417*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u32(struct pvr_dump_ctx *const ctx,
418*61046927SAndroid Build Coastguard Worker const char *const name,
419*61046927SAndroid Build Coastguard Worker const uint32_t value)
420*61046927SAndroid Build Coastguard Worker {
421*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "%" PRIu32, value);
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u32_units(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value,const char * const units)424*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u32_units(struct pvr_dump_ctx *const ctx,
425*61046927SAndroid Build Coastguard Worker const char *const name,
426*61046927SAndroid Build Coastguard Worker const uint32_t value,
427*61046927SAndroid Build Coastguard Worker const char *const units)
428*61046927SAndroid Build Coastguard Worker {
429*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "%" PRIu32 " %s", value, units);
430*61046927SAndroid Build Coastguard Worker }
431*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u32_offset(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value,const uint32_t offset)432*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u32_offset(struct pvr_dump_ctx *const ctx,
433*61046927SAndroid Build Coastguard Worker const char *const name,
434*61046927SAndroid Build Coastguard Worker const uint32_t value,
435*61046927SAndroid Build Coastguard Worker const uint32_t offset)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx,
438*61046927SAndroid Build Coastguard Worker name,
439*61046927SAndroid Build Coastguard Worker "%" PRIu32,
440*61046927SAndroid Build Coastguard Worker "%" PRIu32 " + %" PRIu32,
441*61046927SAndroid Build Coastguard Worker value + offset,
442*61046927SAndroid Build Coastguard Worker value,
443*61046927SAndroid Build Coastguard Worker offset);
444*61046927SAndroid Build Coastguard Worker }
445*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u32_scaled(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value,const uint32_t scale)446*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u32_scaled(struct pvr_dump_ctx *const ctx,
447*61046927SAndroid Build Coastguard Worker const char *const name,
448*61046927SAndroid Build Coastguard Worker const uint32_t value,
449*61046927SAndroid Build Coastguard Worker const uint32_t scale)
450*61046927SAndroid Build Coastguard Worker {
451*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx,
452*61046927SAndroid Build Coastguard Worker name,
453*61046927SAndroid Build Coastguard Worker "%" PRIu32,
454*61046927SAndroid Build Coastguard Worker "%" PRIu32 " x %" PRIu32,
455*61046927SAndroid Build Coastguard Worker value * scale,
456*61046927SAndroid Build Coastguard Worker value,
457*61046927SAndroid Build Coastguard Worker scale);
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker
460*61046927SAndroid Build Coastguard Worker static inline void
pvr_dump_field_u32_scaled_units(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value,const uint32_t scale,const char * const units)461*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32_scaled_units(struct pvr_dump_ctx *const ctx,
462*61046927SAndroid Build Coastguard Worker const char *const name,
463*61046927SAndroid Build Coastguard Worker const uint32_t value,
464*61046927SAndroid Build Coastguard Worker const uint32_t scale,
465*61046927SAndroid Build Coastguard Worker const char *const units)
466*61046927SAndroid Build Coastguard Worker {
467*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx,
468*61046927SAndroid Build Coastguard Worker name,
469*61046927SAndroid Build Coastguard Worker "%" PRIu32 " %s",
470*61046927SAndroid Build Coastguard Worker "%" PRIu32 " x %" PRIu32 " %s",
471*61046927SAndroid Build Coastguard Worker value * scale,
472*61046927SAndroid Build Coastguard Worker units,
473*61046927SAndroid Build Coastguard Worker value,
474*61046927SAndroid Build Coastguard Worker scale,
475*61046927SAndroid Build Coastguard Worker units);
476*61046927SAndroid Build Coastguard Worker }
477*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u32_zero(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value,const uint32_t zero_value)478*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u32_zero(struct pvr_dump_ctx *const ctx,
479*61046927SAndroid Build Coastguard Worker const char *const name,
480*61046927SAndroid Build Coastguard Worker const uint32_t value,
481*61046927SAndroid Build Coastguard Worker const uint32_t zero_value)
482*61046927SAndroid Build Coastguard Worker {
483*61046927SAndroid Build Coastguard Worker if (value)
484*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32(ctx, name, value);
485*61046927SAndroid Build Coastguard Worker else
486*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx, name, "%" PRIu32, "0", zero_value);
487*61046927SAndroid Build Coastguard Worker }
488*61046927SAndroid Build Coastguard Worker
pvr_dump_field_x32(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t value,const uint32_t chars)489*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_x32(struct pvr_dump_ctx *const ctx,
490*61046927SAndroid Build Coastguard Worker const char *const name,
491*61046927SAndroid Build Coastguard Worker const uint32_t value,
492*61046927SAndroid Build Coastguard Worker const uint32_t chars)
493*61046927SAndroid Build Coastguard Worker {
494*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx,
495*61046927SAndroid Build Coastguard Worker name,
496*61046927SAndroid Build Coastguard Worker "0x%0*" PRIx32,
497*61046927SAndroid Build Coastguard Worker chars,
498*61046927SAndroid Build Coastguard Worker value & BITFIELD_MASK(chars * 4));
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u64(struct pvr_dump_ctx * const ctx,const char * const name,const uint64_t value)501*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u64(struct pvr_dump_ctx *const ctx,
502*61046927SAndroid Build Coastguard Worker const char *const name,
503*61046927SAndroid Build Coastguard Worker const uint64_t value)
504*61046927SAndroid Build Coastguard Worker {
505*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "%" PRIu64, value);
506*61046927SAndroid Build Coastguard Worker }
507*61046927SAndroid Build Coastguard Worker
pvr_dump_field_u64_units(struct pvr_dump_ctx * const ctx,const char * const name,const uint64_t value,const char * const units)508*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_u64_units(struct pvr_dump_ctx *const ctx,
509*61046927SAndroid Build Coastguard Worker const char *const name,
510*61046927SAndroid Build Coastguard Worker const uint64_t value,
511*61046927SAndroid Build Coastguard Worker const char *const units)
512*61046927SAndroid Build Coastguard Worker {
513*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "%" PRIu64 " %s", value, units);
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker /*****************************************************************************
517*61046927SAndroid Build Coastguard Worker Field printers: floating point
518*61046927SAndroid Build Coastguard Worker *****************************************************************************/
519*61046927SAndroid Build Coastguard Worker
pvr_dump_field_f32(struct pvr_dump_ctx * const ctx,const char * const name,const float value)520*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_f32(struct pvr_dump_ctx *const ctx,
521*61046927SAndroid Build Coastguard Worker const char *const name,
522*61046927SAndroid Build Coastguard Worker const float value)
523*61046927SAndroid Build Coastguard Worker {
524*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx, name, "%f", "0x%08" PRIx32, value, fui(value));
525*61046927SAndroid Build Coastguard Worker }
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker /*****************************************************************************
528*61046927SAndroid Build Coastguard Worker Field printers: fixed point
529*61046927SAndroid Build Coastguard Worker *****************************************************************************/
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker /* clang-format off */
532*61046927SAndroid Build Coastguard Worker static const char *const __fixed_frac_str_table_4[1 << 4] = {
533*61046927SAndroid Build Coastguard Worker "0", "0625", "125", "1875", "25", "3125", "375", "4375",
534*61046927SAndroid Build Coastguard Worker "5", "5625", "625", "6875", "75", "8125", "875", "9375",
535*61046927SAndroid Build Coastguard Worker };
536*61046927SAndroid Build Coastguard Worker /* clang-format on */
537*61046927SAndroid Build Coastguard Worker
pvr_dump_field_uq4_4(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t raw_value)538*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_uq4_4(struct pvr_dump_ctx *const ctx,
539*61046927SAndroid Build Coastguard Worker const char *const name,
540*61046927SAndroid Build Coastguard Worker const uint32_t raw_value)
541*61046927SAndroid Build Coastguard Worker {
542*61046927SAndroid Build Coastguard Worker const uint32_t int_part = (raw_value & BITFIELD_RANGE(4, 4)) >> 4;
543*61046927SAndroid Build Coastguard Worker const uint32_t frac_part = raw_value & BITFIELD_MASK(4);
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx,
546*61046927SAndroid Build Coastguard Worker name,
547*61046927SAndroid Build Coastguard Worker "%" PRIu32 ".%s",
548*61046927SAndroid Build Coastguard Worker "0x%02" PRIx32, /* Or %0*x where *=(nr_bits+3)/4 */
549*61046927SAndroid Build Coastguard Worker int_part,
550*61046927SAndroid Build Coastguard Worker __fixed_frac_str_table_4[frac_part],
551*61046927SAndroid Build Coastguard Worker raw_value & BITFIELD_MASK(8));
552*61046927SAndroid Build Coastguard Worker }
553*61046927SAndroid Build Coastguard Worker
pvr_dump_field_uq4_4_offset(struct pvr_dump_ctx * const ctx,const char * const name,const uint32_t raw_value,const uint32_t raw_offset)554*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_uq4_4_offset(struct pvr_dump_ctx *const ctx,
555*61046927SAndroid Build Coastguard Worker const char *const name,
556*61046927SAndroid Build Coastguard Worker const uint32_t raw_value,
557*61046927SAndroid Build Coastguard Worker const uint32_t raw_offset)
558*61046927SAndroid Build Coastguard Worker {
559*61046927SAndroid Build Coastguard Worker const uint32_t raw_offset_value = raw_value + raw_offset;
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker const uint32_t int_part = (raw_offset_value & BITFIELD_RANGE(4, 4)) >> 4;
562*61046927SAndroid Build Coastguard Worker const uint32_t frac_part = raw_offset_value & BITFIELD_MASK(4);
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx,
565*61046927SAndroid Build Coastguard Worker name,
566*61046927SAndroid Build Coastguard Worker "%" PRIu32 ".%s",
567*61046927SAndroid Build Coastguard Worker "0x%02" PRIx32 " + 0x%02" PRIx32,
568*61046927SAndroid Build Coastguard Worker int_part,
569*61046927SAndroid Build Coastguard Worker __fixed_frac_str_table_4[frac_part],
570*61046927SAndroid Build Coastguard Worker raw_value & BITFIELD_MASK(8),
571*61046927SAndroid Build Coastguard Worker raw_offset);
572*61046927SAndroid Build Coastguard Worker }
573*61046927SAndroid Build Coastguard Worker
574*61046927SAndroid Build Coastguard Worker /*****************************************************************************
575*61046927SAndroid Build Coastguard Worker Field printers: device address
576*61046927SAndroid Build Coastguard Worker *****************************************************************************/
577*61046927SAndroid Build Coastguard Worker
pvr_dump_field_addr_non_null(struct pvr_dump_ctx * const ctx,const char * const name,const pvr_dev_addr_t value)578*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_addr_non_null(struct pvr_dump_ctx *const ctx,
579*61046927SAndroid Build Coastguard Worker const char *const name,
580*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t value)
581*61046927SAndroid Build Coastguard Worker {
582*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, PVR_DEV_ADDR_FMT, value.addr);
583*61046927SAndroid Build Coastguard Worker }
584*61046927SAndroid Build Coastguard Worker
pvr_dump_field_addr(struct pvr_dump_ctx * const ctx,const char * const name,const pvr_dev_addr_t value)585*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_addr(struct pvr_dump_ctx *const ctx,
586*61046927SAndroid Build Coastguard Worker const char *const name,
587*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t value)
588*61046927SAndroid Build Coastguard Worker {
589*61046927SAndroid Build Coastguard Worker if (value.addr)
590*61046927SAndroid Build Coastguard Worker pvr_dump_field_addr_non_null(ctx, name, value);
591*61046927SAndroid Build Coastguard Worker else
592*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "<null>");
593*61046927SAndroid Build Coastguard Worker }
594*61046927SAndroid Build Coastguard Worker
pvr_dump_field_addr_split(struct pvr_dump_ctx * const ctx,const char * const name,const pvr_dev_addr_t msb,const pvr_dev_addr_t lsb)595*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_addr_split(struct pvr_dump_ctx *const ctx,
596*61046927SAndroid Build Coastguard Worker const char *const name,
597*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t msb,
598*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t lsb)
599*61046927SAndroid Build Coastguard Worker {
600*61046927SAndroid Build Coastguard Worker pvr_dump_field_addr(ctx, name, PVR_DEV_ADDR(msb.addr | lsb.addr));
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker pvr_dump_indent(ctx);
603*61046927SAndroid Build Coastguard Worker pvr_dump_field_addr_non_null(ctx, "msb", msb);
604*61046927SAndroid Build Coastguard Worker pvr_dump_field_addr_non_null(ctx, "lsb", lsb);
605*61046927SAndroid Build Coastguard Worker pvr_dump_dedent(ctx);
606*61046927SAndroid Build Coastguard Worker }
607*61046927SAndroid Build Coastguard Worker
pvr_dump_field_addr_offset(struct pvr_dump_ctx * const ctx,const char * const name,const pvr_dev_addr_t value,const pvr_dev_addr_t base)608*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_addr_offset(struct pvr_dump_ctx *const ctx,
609*61046927SAndroid Build Coastguard Worker const char *const name,
610*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t value,
611*61046927SAndroid Build Coastguard Worker const pvr_dev_addr_t base)
612*61046927SAndroid Build Coastguard Worker {
613*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx,
614*61046927SAndroid Build Coastguard Worker name,
615*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_FMT,
616*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_FMT " + " PVR_DEV_ADDR_FMT,
617*61046927SAndroid Build Coastguard Worker PVR_DEV_ADDR_OFFSET(base, value.addr).addr,
618*61046927SAndroid Build Coastguard Worker base.addr,
619*61046927SAndroid Build Coastguard Worker value.addr);
620*61046927SAndroid Build Coastguard Worker }
621*61046927SAndroid Build Coastguard Worker
622*61046927SAndroid Build Coastguard Worker /*****************************************************************************
623*61046927SAndroid Build Coastguard Worker Field printers: enums
624*61046927SAndroid Build Coastguard Worker *****************************************************************************/
625*61046927SAndroid Build Coastguard Worker
626*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_enum(ctx, name, value, to_str) \
627*61046927SAndroid Build Coastguard Worker do { \
628*61046927SAndroid Build Coastguard Worker __typeof__(value) _value = (value); \
629*61046927SAndroid Build Coastguard Worker const char *_str = to_str(_value); \
630*61046927SAndroid Build Coastguard Worker if (!_str) \
631*61046927SAndroid Build Coastguard Worker _str = "<unknown>"; \
632*61046927SAndroid Build Coastguard Worker pvr_dump_field_computed(ctx, name, "%s", "%u", _str, _value); \
633*61046927SAndroid Build Coastguard Worker } while (0)
634*61046927SAndroid Build Coastguard Worker
__bool_to_str(const bool b)635*61046927SAndroid Build Coastguard Worker static inline const char *__bool_to_str(const bool b)
636*61046927SAndroid Build Coastguard Worker {
637*61046927SAndroid Build Coastguard Worker return b ? "yes" : "no";
638*61046927SAndroid Build Coastguard Worker }
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker /* A bool is just an enum with two values. */
pvr_dump_field_bool(struct pvr_dump_ctx * const ctx,const char * const name,const bool value)641*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_bool(struct pvr_dump_ctx *const ctx,
642*61046927SAndroid Build Coastguard Worker const char *const name,
643*61046927SAndroid Build Coastguard Worker const bool value)
644*61046927SAndroid Build Coastguard Worker {
645*61046927SAndroid Build Coastguard Worker pvr_dump_field_enum(ctx, name, value, __bool_to_str);
646*61046927SAndroid Build Coastguard Worker }
647*61046927SAndroid Build Coastguard Worker
648*61046927SAndroid Build Coastguard Worker /*****************************************************************************
649*61046927SAndroid Build Coastguard Worker Field printers: string
650*61046927SAndroid Build Coastguard Worker *****************************************************************************/
651*61046927SAndroid Build Coastguard Worker
pvr_dump_field_string(struct pvr_dump_ctx * const ctx,const char * const name,const char * const value)652*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_string(struct pvr_dump_ctx *const ctx,
653*61046927SAndroid Build Coastguard Worker const char *const name,
654*61046927SAndroid Build Coastguard Worker const char *const value)
655*61046927SAndroid Build Coastguard Worker {
656*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "%s", value);
657*61046927SAndroid Build Coastguard Worker }
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker /*****************************************************************************
660*61046927SAndroid Build Coastguard Worker Field printers: not present
661*61046927SAndroid Build Coastguard Worker *****************************************************************************/
662*61046927SAndroid Build Coastguard Worker
pvr_dump_field_no_fields(struct pvr_dump_ctx * const ctx)663*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_no_fields(struct pvr_dump_ctx *const ctx)
664*61046927SAndroid Build Coastguard Worker {
665*61046927SAndroid Build Coastguard Worker pvr_dump_println(ctx, "<no fields>");
666*61046927SAndroid Build Coastguard Worker }
667*61046927SAndroid Build Coastguard Worker
pvr_dump_field_not_present(struct pvr_dump_ctx * const ctx,const char * const name)668*61046927SAndroid Build Coastguard Worker static inline void pvr_dump_field_not_present(struct pvr_dump_ctx *const ctx,
669*61046927SAndroid Build Coastguard Worker const char *const name)
670*61046927SAndroid Build Coastguard Worker {
671*61046927SAndroid Build Coastguard Worker pvr_dump_field(ctx, name, "<not present>");
672*61046927SAndroid Build Coastguard Worker }
673*61046927SAndroid Build Coastguard Worker
674*61046927SAndroid Build Coastguard Worker /*****************************************************************************
675*61046927SAndroid Build Coastguard Worker Field printers: helpers for members
676*61046927SAndroid Build Coastguard Worker *****************************************************************************/
677*61046927SAndroid Build Coastguard Worker
678*61046927SAndroid Build Coastguard Worker /* clang-format off */
679*61046927SAndroid Build Coastguard Worker
680*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u32(ctx, compound, member) \
681*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32(ctx, #member, (compound)->member)
682*61046927SAndroid Build Coastguard Worker
683*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u32_units(ctx, compound, member, units) \
684*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32_units(ctx, #member, (compound)->member, units)
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u32_offset(ctx, compound, member, offset) \
687*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32_offset(ctx, #member, (compound)->member, offset)
688*61046927SAndroid Build Coastguard Worker
689*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u32_scaled(ctx, compound, member, scale) \
690*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32_scaled(ctx, #member, (compound)->member, scale)
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u32_scaled_units(ctx, compound, member, scale, units) \
693*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32_scaled_units(ctx, #member, (compound)->member, scale, units)
694*61046927SAndroid Build Coastguard Worker
695*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u32_zero(ctx, compound, member, zero_value) \
696*61046927SAndroid Build Coastguard Worker pvr_dump_field_u32_zero(ctx, #member, (compound)->member, zero_value)
697*61046927SAndroid Build Coastguard Worker
698*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_x32(ctx, compound, member, chars) \
699*61046927SAndroid Build Coastguard Worker pvr_dump_field_x32(ctx, #member, (compound)->member, chars)
700*61046927SAndroid Build Coastguard Worker
701*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u64(ctx, compound, member) \
702*61046927SAndroid Build Coastguard Worker pvr_dump_field_u64(ctx, #member, (compound)->member)
703*61046927SAndroid Build Coastguard Worker
704*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_u64_units(ctx, compound, member, units) \
705*61046927SAndroid Build Coastguard Worker pvr_dump_field_u64_units(ctx, #member, (compound)->member, units)
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_f32(ctx, compound, member) \
708*61046927SAndroid Build Coastguard Worker pvr_dump_field_f32(ctx, #member, (compound)->member)
709*61046927SAndroid Build Coastguard Worker
710*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_uq4_4(ctx, compound, member) \
711*61046927SAndroid Build Coastguard Worker pvr_dump_field_uq4_4(ctx, #member, (compound)->member)
712*61046927SAndroid Build Coastguard Worker
713*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_uq4_4_offset(ctx, compound, member, raw_offset) \
714*61046927SAndroid Build Coastguard Worker pvr_dump_field_uq4_4_offset(ctx, #member, (compound)->member, raw_offset)
715*61046927SAndroid Build Coastguard Worker
716*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_addr(ctx, compound, member) \
717*61046927SAndroid Build Coastguard Worker pvr_dump_field_addr(ctx, #member, (compound)->member)
718*61046927SAndroid Build Coastguard Worker
719*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_addr_offset(ctx, compound, member, base) \
720*61046927SAndroid Build Coastguard Worker pvr_dump_field_addr_offset(ctx, #member, (compound)->member, base)
721*61046927SAndroid Build Coastguard Worker
722*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_enum(ctx, compound, member, to_str) \
723*61046927SAndroid Build Coastguard Worker pvr_dump_field_enum(ctx, #member, (compound)->member, to_str)
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_bool(ctx, compound, member) \
726*61046927SAndroid Build Coastguard Worker pvr_dump_field_bool(ctx, #member, (compound)->member)
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_string(ctx, compound, member) \
729*61046927SAndroid Build Coastguard Worker pvr_dump_field_string(ctx, #member, (compound)->member)
730*61046927SAndroid Build Coastguard Worker
731*61046927SAndroid Build Coastguard Worker /* clang-format on */
732*61046927SAndroid Build Coastguard Worker
733*61046927SAndroid Build Coastguard Worker #define pvr_dump_field_member_not_present(ctx, compound, member) \
734*61046927SAndroid Build Coastguard Worker do { \
735*61046927SAndroid Build Coastguard Worker (void)&(compound)->member; \
736*61046927SAndroid Build Coastguard Worker pvr_dump_field_not_present(ctx, #member); \
737*61046927SAndroid Build Coastguard Worker } while (0)
738*61046927SAndroid Build Coastguard Worker
739*61046927SAndroid Build Coastguard Worker #endif /* PVR_DUMP_H */
740