xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/crashdec-mempool.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2020 Valve Corporation
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker 
7*61046927SAndroid Build Coastguard Worker #include "crashdec.h"
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker 
10*61046927SAndroid Build Coastguard Worker static void
dump_mem_pool_reg_write(unsigned reg,uint32_t data,unsigned context,bool pipe)11*61046927SAndroid Build Coastguard Worker dump_mem_pool_reg_write(unsigned reg, uint32_t data, unsigned context,
12*61046927SAndroid Build Coastguard Worker                         bool pipe)
13*61046927SAndroid Build Coastguard Worker {
14*61046927SAndroid Build Coastguard Worker    /* TODO deal better somehow w/ 64b regs: */
15*61046927SAndroid Build Coastguard Worker    struct regacc r = {
16*61046927SAndroid Build Coastguard Worker          .rnn = pipe ? rnn_pipe : NULL,
17*61046927SAndroid Build Coastguard Worker          .regbase = reg,
18*61046927SAndroid Build Coastguard Worker          .value = data,
19*61046927SAndroid Build Coastguard Worker    };
20*61046927SAndroid Build Coastguard Worker    if (pipe) {
21*61046927SAndroid Build Coastguard Worker       struct rnndecaddrinfo *info = rnn_reginfo(rnn_pipe, reg);
22*61046927SAndroid Build Coastguard Worker       printf("\t\twrite %s (%02x) pipe\n", info->name, reg);
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker       if (!strcmp(info->typeinfo->name, "void")) {
25*61046927SAndroid Build Coastguard Worker          /* registers that ignore their payload */
26*61046927SAndroid Build Coastguard Worker       } else {
27*61046927SAndroid Build Coastguard Worker          printf("\t\t\t");
28*61046927SAndroid Build Coastguard Worker          dump_register(&r);
29*61046927SAndroid Build Coastguard Worker       }
30*61046927SAndroid Build Coastguard Worker       rnn_reginfo_free(info);
31*61046927SAndroid Build Coastguard Worker    } else {
32*61046927SAndroid Build Coastguard Worker       printf("\t\twrite %s (%05x)", regname(reg, 1), reg);
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker       if (is_a6xx()) {
35*61046927SAndroid Build Coastguard Worker          printf(" context %d", context);
36*61046927SAndroid Build Coastguard Worker       }
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker       printf("\n");
39*61046927SAndroid Build Coastguard Worker       dump_register_val(&r, 2);
40*61046927SAndroid Build Coastguard Worker    }
41*61046927SAndroid Build Coastguard Worker }
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker static void
dump_mem_pool_chunk(const uint32_t * chunk)44*61046927SAndroid Build Coastguard Worker dump_mem_pool_chunk(const uint32_t *chunk)
45*61046927SAndroid Build Coastguard Worker {
46*61046927SAndroid Build Coastguard Worker    struct __attribute__((packed)) {
47*61046927SAndroid Build Coastguard Worker       bool reg0_enabled : 1;
48*61046927SAndroid Build Coastguard Worker       bool reg1_enabled : 1;
49*61046927SAndroid Build Coastguard Worker       uint32_t data0 : 32;
50*61046927SAndroid Build Coastguard Worker       uint32_t data1 : 32;
51*61046927SAndroid Build Coastguard Worker       uint32_t reg0 : 18;
52*61046927SAndroid Build Coastguard Worker       uint32_t reg1 : 18;
53*61046927SAndroid Build Coastguard Worker       bool reg0_pipe : 1;
54*61046927SAndroid Build Coastguard Worker       bool reg1_pipe : 1;
55*61046927SAndroid Build Coastguard Worker       uint32_t reg0_context : 1;
56*61046927SAndroid Build Coastguard Worker       uint32_t reg1_context : 1;
57*61046927SAndroid Build Coastguard Worker       uint32_t padding : 22;
58*61046927SAndroid Build Coastguard Worker    } fields;
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker    memcpy(&fields, chunk, 4 * sizeof(uint32_t));
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    if (fields.reg0_enabled) {
63*61046927SAndroid Build Coastguard Worker       dump_mem_pool_reg_write(fields.reg0, fields.data0, fields.reg0_context,
64*61046927SAndroid Build Coastguard Worker                               fields.reg0_pipe);
65*61046927SAndroid Build Coastguard Worker    }
66*61046927SAndroid Build Coastguard Worker 
67*61046927SAndroid Build Coastguard Worker    if (fields.reg1_enabled) {
68*61046927SAndroid Build Coastguard Worker       dump_mem_pool_reg_write(fields.reg1, fields.data1, fields.reg1_context,
69*61046927SAndroid Build Coastguard Worker                               fields.reg1_pipe);
70*61046927SAndroid Build Coastguard Worker    }
71*61046927SAndroid Build Coastguard Worker }
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker void
dump_cp_mem_pool(uint32_t * mempool)74*61046927SAndroid Build Coastguard Worker dump_cp_mem_pool(uint32_t *mempool)
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker    /* The mem pool is a shared pool of memory used for storing in-flight
77*61046927SAndroid Build Coastguard Worker     * register writes. There are 6 different queues, one for each
78*61046927SAndroid Build Coastguard Worker     * cluster. Writing to $data (or for some special registers, $addr)
79*61046927SAndroid Build Coastguard Worker     * pushes data onto the appropriate queue, and each queue is pulled
80*61046927SAndroid Build Coastguard Worker     * from by the appropriate cluster. The queues are thus written to
81*61046927SAndroid Build Coastguard Worker     * in-order, but may be read out-of-order.
82*61046927SAndroid Build Coastguard Worker     *
83*61046927SAndroid Build Coastguard Worker     * The queues are conceptually divided into 128-bit "chunks", and the
84*61046927SAndroid Build Coastguard Worker     * read and write pointers are in units of chunks.  These chunks are
85*61046927SAndroid Build Coastguard Worker     * organized internally into 8-chunk "blocks", and memory is allocated
86*61046927SAndroid Build Coastguard Worker     * dynamically in terms of blocks. Each queue is represented as a
87*61046927SAndroid Build Coastguard Worker     * singly-linked list of blocks, as well as 3-bit start/end chunk
88*61046927SAndroid Build Coastguard Worker     * pointers that point within the first/last block.  The next pointers
89*61046927SAndroid Build Coastguard Worker     * are located in a separate array, rather than inline.
90*61046927SAndroid Build Coastguard Worker     */
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker    /* TODO: The firmware CP_MEM_POOL save/restore routines do something
93*61046927SAndroid Build Coastguard Worker     * like:
94*61046927SAndroid Build Coastguard Worker     *
95*61046927SAndroid Build Coastguard Worker     * cread $02, [ $00 + 0 ]
96*61046927SAndroid Build Coastguard Worker     * and $02, $02, 0x118
97*61046927SAndroid Build Coastguard Worker     * ...
98*61046927SAndroid Build Coastguard Worker     * brne $02, 0, #label
99*61046927SAndroid Build Coastguard Worker     * mov $03, 0x2000
100*61046927SAndroid Build Coastguard Worker     * mov $03, 0x1000
101*61046927SAndroid Build Coastguard Worker     * label:
102*61046927SAndroid Build Coastguard Worker     * ...
103*61046927SAndroid Build Coastguard Worker     *
104*61046927SAndroid Build Coastguard Worker     * I think that control register 0 is the GPU version, and some
105*61046927SAndroid Build Coastguard Worker     * versions have a smaller mem pool. It seems some models have a mem
106*61046927SAndroid Build Coastguard Worker     * pool that's half the size, and a bunch of offsets are shifted
107*61046927SAndroid Build Coastguard Worker     * accordingly. Unfortunately the kernel driver's dumping code doesn't
108*61046927SAndroid Build Coastguard Worker     * seem to take this into account, even the downstream android driver,
109*61046927SAndroid Build Coastguard Worker     * and we don't know which versions 0x8, 0x10, or 0x100 correspond
110*61046927SAndroid Build Coastguard Worker     * to. Or maybe we can use CP_DBG_MEM_POOL_SIZE to figure this out?
111*61046927SAndroid Build Coastguard Worker     */
112*61046927SAndroid Build Coastguard Worker    bool small_mem_pool = false;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    /* The array of next pointers for each block. */
115*61046927SAndroid Build Coastguard Worker    const uint32_t *next_pointers =
116*61046927SAndroid Build Coastguard Worker       small_mem_pool ? &mempool[0x800] : &mempool[0x1000];
117*61046927SAndroid Build Coastguard Worker 
118*61046927SAndroid Build Coastguard Worker    /* Maximum number of blocks in the pool, also the size of the pointers
119*61046927SAndroid Build Coastguard Worker     * array.
120*61046927SAndroid Build Coastguard Worker     */
121*61046927SAndroid Build Coastguard Worker    const int num_blocks = small_mem_pool ? 0x30 : 0x80;
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    /* Number of queues */
124*61046927SAndroid Build Coastguard Worker    const unsigned num_queues = is_a6xx() ? 6 : 7;
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    /* Unfortunately the per-queue state is a little more complicated than
127*61046927SAndroid Build Coastguard Worker     * a simple pair of begin/end pointers. Instead of a single beginning
128*61046927SAndroid Build Coastguard Worker     * block, there are *two*, with the property that either the two are
129*61046927SAndroid Build Coastguard Worker     * equal or the second is the "next" of the first. Similarly there are
130*61046927SAndroid Build Coastguard Worker     * two end blocks. Thus the queue either looks like this:
131*61046927SAndroid Build Coastguard Worker     *
132*61046927SAndroid Build Coastguard Worker     * A -> B -> ... -> C -> D
133*61046927SAndroid Build Coastguard Worker     *
134*61046927SAndroid Build Coastguard Worker     * Or like this, or some combination:
135*61046927SAndroid Build Coastguard Worker     *
136*61046927SAndroid Build Coastguard Worker     * A/B -> ... -> C/D
137*61046927SAndroid Build Coastguard Worker     *
138*61046927SAndroid Build Coastguard Worker     * However, there's only one beginning/end chunk offset. Now the
139*61046927SAndroid Build Coastguard Worker     * question is, which of A or B is the actual start? I.e. is the chunk
140*61046927SAndroid Build Coastguard Worker     * offset an offset inside A or B? It depends. I'll show a typical read
141*61046927SAndroid Build Coastguard Worker     * cycle, starting here (read pointer marked with a *) with a chunk
142*61046927SAndroid Build Coastguard Worker     * offset of 0:
143*61046927SAndroid Build Coastguard Worker     *
144*61046927SAndroid Build Coastguard Worker     *	  A                    B
145*61046927SAndroid Build Coastguard Worker     *  _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _
146*61046927SAndroid Build Coastguard Worker     * |_|_|_|_|_|_|_|_| -> |*|_|_|_|_|_|_|_| -> |_|_|_|_|_|_|_|_|
147*61046927SAndroid Build Coastguard Worker     *
148*61046927SAndroid Build Coastguard Worker     * Once the pointer advances far enough, the hardware decides to free
149*61046927SAndroid Build Coastguard Worker     * A, after which the read-side state looks like:
150*61046927SAndroid Build Coastguard Worker     *
151*61046927SAndroid Build Coastguard Worker     *	(free)                A/B
152*61046927SAndroid Build Coastguard Worker     *  _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _
153*61046927SAndroid Build Coastguard Worker     * |_|_|_|_|_|_|_|_|    |_|_|_|*|_|_|_|_| -> |_|_|_|_|_|_|_|_|
154*61046927SAndroid Build Coastguard Worker     *
155*61046927SAndroid Build Coastguard Worker     * Then after advancing the pointer a bit more, the hardware fetches
156*61046927SAndroid Build Coastguard Worker     * the "next" pointer for A and stores it in B:
157*61046927SAndroid Build Coastguard Worker     *
158*61046927SAndroid Build Coastguard Worker     *	(free)                 A                     B
159*61046927SAndroid Build Coastguard Worker     *  _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _
160*61046927SAndroid Build Coastguard Worker     * |_|_|_|_|_|_|_|_|    |_|_|_|_|_|_|_|*| -> |_|_|_|_|_|_|_|_|
161*61046927SAndroid Build Coastguard Worker     *
162*61046927SAndroid Build Coastguard Worker     * Then the read pointer advances into B, at which point we've come
163*61046927SAndroid Build Coastguard Worker     * back to the first state having advanced a whole block:
164*61046927SAndroid Build Coastguard Worker     *
165*61046927SAndroid Build Coastguard Worker     *	(free)                 A                     B
166*61046927SAndroid Build Coastguard Worker     *  _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _      _ _ _ _ _ _ _ _
167*61046927SAndroid Build Coastguard Worker     * |_|_|_|_|_|_|_|_|    |_|_|_|_|_|_|_|_| -> |*|_|_|_|_|_|_|_|
168*61046927SAndroid Build Coastguard Worker     *
169*61046927SAndroid Build Coastguard Worker     *
170*61046927SAndroid Build Coastguard Worker     * There is a similar cycle for the write pointer. Now, the question
171*61046927SAndroid Build Coastguard Worker     * is, how do we know which state we're in? We need to know this to
172*61046927SAndroid Build Coastguard Worker     * know whether the pointer (*) is in A or B if they're different. It
173*61046927SAndroid Build Coastguard Worker     * seems like there should be some bit somewhere describing this, but
174*61046927SAndroid Build Coastguard Worker     * after lots of experimentation I've come up empty-handed. For now we
175*61046927SAndroid Build Coastguard Worker     * assume that if the pointer is in the first half, then we're in
176*61046927SAndroid Build Coastguard Worker     * either the first or second state and use B, and otherwise we're in
177*61046927SAndroid Build Coastguard Worker     * the second or third state and use A. So far I haven't seen anything
178*61046927SAndroid Build Coastguard Worker     * that violates this assumption.
179*61046927SAndroid Build Coastguard Worker     */
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    struct {
182*61046927SAndroid Build Coastguard Worker       uint32_t unk0;
183*61046927SAndroid Build Coastguard Worker       uint32_t padding0[7]; /* Mirrors of unk0 */
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker       struct {
186*61046927SAndroid Build Coastguard Worker          uint32_t chunk : 3;
187*61046927SAndroid Build Coastguard Worker          uint32_t first_block : 32 - 3;
188*61046927SAndroid Build Coastguard Worker       } writer[6];
189*61046927SAndroid Build Coastguard Worker       uint32_t padding1[2]; /* Mirror of writer[5] */
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker       uint32_t unk1;
192*61046927SAndroid Build Coastguard Worker       uint32_t padding2[7]; /* Mirrors of unk1 */
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker       uint32_t writer_second_block[7];
195*61046927SAndroid Build Coastguard Worker       uint32_t padding3[1];
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker       uint32_t unk2[7];
198*61046927SAndroid Build Coastguard Worker       uint32_t padding4[1];
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker       struct {
201*61046927SAndroid Build Coastguard Worker          uint32_t chunk : 3;
202*61046927SAndroid Build Coastguard Worker          uint32_t first_block : 32 - 3;
203*61046927SAndroid Build Coastguard Worker       } reader[7];
204*61046927SAndroid Build Coastguard Worker       uint32_t padding5[1]; /* Mirror of reader[5] */
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker       uint32_t unk3;
207*61046927SAndroid Build Coastguard Worker       uint32_t padding6[7]; /* Mirrors of unk3 */
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker       uint32_t reader_second_block[7];
210*61046927SAndroid Build Coastguard Worker       uint32_t padding7[1];
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker       uint32_t block_count[7];
213*61046927SAndroid Build Coastguard Worker       uint32_t padding[1];
214*61046927SAndroid Build Coastguard Worker 
215*61046927SAndroid Build Coastguard Worker       uint32_t unk4;
216*61046927SAndroid Build Coastguard Worker       uint32_t padding9[7]; /* Mirrors of unk4 */
217*61046927SAndroid Build Coastguard Worker    } data1;
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker    const uint32_t *data1_ptr =
220*61046927SAndroid Build Coastguard Worker       small_mem_pool ? &mempool[0xc00] : &mempool[0x1800];
221*61046927SAndroid Build Coastguard Worker    memcpy(&data1, data1_ptr, sizeof(data1));
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker    /* Based on the kernel, the first dword is the mem pool size (in
224*61046927SAndroid Build Coastguard Worker     * blocks?) and mirrors CP_MEM_POOL_DBG_SIZE.
225*61046927SAndroid Build Coastguard Worker     */
226*61046927SAndroid Build Coastguard Worker    const uint32_t *data2_ptr =
227*61046927SAndroid Build Coastguard Worker       small_mem_pool ? &mempool[0x1000] : &mempool[0x2000];
228*61046927SAndroid Build Coastguard Worker    const int data2_size = 0x60;
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker    /* This seems to be the size of each queue in chunks. */
231*61046927SAndroid Build Coastguard Worker    const uint32_t *queue_sizes = &data2_ptr[0x18];
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker    printf("\tdata2:\n");
234*61046927SAndroid Build Coastguard Worker    dump_hex_ascii(data2_ptr, 4 * data2_size, 1);
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker    /* These seem to be some kind of counter of allocated/deallocated blocks */
237*61046927SAndroid Build Coastguard Worker    if (verbose) {
238*61046927SAndroid Build Coastguard Worker       printf("\tunk0: %x\n", data1.unk0);
239*61046927SAndroid Build Coastguard Worker       printf("\tunk1: %x\n", data1.unk1);
240*61046927SAndroid Build Coastguard Worker       printf("\tunk3: %x\n", data1.unk3);
241*61046927SAndroid Build Coastguard Worker       printf("\tunk4: %x\n\n", data1.unk4);
242*61046927SAndroid Build Coastguard Worker    }
243*61046927SAndroid Build Coastguard Worker 
244*61046927SAndroid Build Coastguard Worker    for (int queue = 0; queue < num_queues; queue++) {
245*61046927SAndroid Build Coastguard Worker       const char *cluster_names_a6xx[6] = {"FE",   "SP_VS", "PC_VS",
246*61046927SAndroid Build Coastguard Worker                                            "GRAS", "SP_PS", "PS"};
247*61046927SAndroid Build Coastguard Worker       const char *cluster_names_a7xx[7] = {"FE",   "SP_VS", "PC_VS",
248*61046927SAndroid Build Coastguard Worker                                            "GRAS", "SP_PS", "VPC_PS", "PS"};
249*61046927SAndroid Build Coastguard Worker       printf("\tCLUSTER_%s:\n\n",
250*61046927SAndroid Build Coastguard Worker              is_a6xx() ? cluster_names_a6xx[queue] : cluster_names_a7xx[queue]);
251*61046927SAndroid Build Coastguard Worker 
252*61046927SAndroid Build Coastguard Worker       if (verbose) {
253*61046927SAndroid Build Coastguard Worker          printf("\t\twriter_first_block: 0x%x\n",
254*61046927SAndroid Build Coastguard Worker                 data1.writer[queue].first_block);
255*61046927SAndroid Build Coastguard Worker          printf("\t\twriter_second_block: 0x%x\n",
256*61046927SAndroid Build Coastguard Worker                 data1.writer_second_block[queue]);
257*61046927SAndroid Build Coastguard Worker          printf("\t\twriter_chunk: %d\n", data1.writer[queue].chunk);
258*61046927SAndroid Build Coastguard Worker          printf("\t\treader_first_block: 0x%x\n",
259*61046927SAndroid Build Coastguard Worker                 data1.reader[queue].first_block);
260*61046927SAndroid Build Coastguard Worker          printf("\t\treader_second_block: 0x%x\n",
261*61046927SAndroid Build Coastguard Worker                 data1.reader_second_block[queue]);
262*61046927SAndroid Build Coastguard Worker          printf("\t\treader_chunk: %d\n", data1.reader[queue].chunk);
263*61046927SAndroid Build Coastguard Worker          printf("\t\tblock_count: %d\n", data1.block_count[queue]);
264*61046927SAndroid Build Coastguard Worker          printf("\t\tunk2: 0x%x\n", data1.unk2[queue]);
265*61046927SAndroid Build Coastguard Worker          printf("\t\tqueue_size: %d\n\n", queue_sizes[queue]);
266*61046927SAndroid Build Coastguard Worker       }
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker       uint32_t cur_chunk = data1.reader[queue].chunk;
269*61046927SAndroid Build Coastguard Worker       uint32_t cur_block = cur_chunk > 3 ? data1.reader[queue].first_block
270*61046927SAndroid Build Coastguard Worker                                          : data1.reader_second_block[queue];
271*61046927SAndroid Build Coastguard Worker       uint32_t last_chunk = data1.writer[queue].chunk;
272*61046927SAndroid Build Coastguard Worker       uint32_t last_block = last_chunk > 3 ? data1.writer[queue].first_block
273*61046927SAndroid Build Coastguard Worker                                            : data1.writer_second_block[queue];
274*61046927SAndroid Build Coastguard Worker 
275*61046927SAndroid Build Coastguard Worker       if (verbose)
276*61046927SAndroid Build Coastguard Worker          printf("\tblock %x\n", cur_block);
277*61046927SAndroid Build Coastguard Worker       if (cur_block >= num_blocks) {
278*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "block %x too large\n", cur_block);
279*61046927SAndroid Build Coastguard Worker          exit(1);
280*61046927SAndroid Build Coastguard Worker       }
281*61046927SAndroid Build Coastguard Worker       unsigned calculated_queue_size = 0;
282*61046927SAndroid Build Coastguard Worker       while (cur_block != last_block || cur_chunk != last_chunk) {
283*61046927SAndroid Build Coastguard Worker          calculated_queue_size++;
284*61046927SAndroid Build Coastguard Worker          uint32_t *chunk_ptr = &mempool[cur_block * 0x20 + cur_chunk * 4];
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker          dump_mem_pool_chunk(chunk_ptr);
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker          printf("\t%05x: %08x %08x %08x %08x\n",
289*61046927SAndroid Build Coastguard Worker                 4 * (cur_block * 0x20 + cur_chunk + 4), chunk_ptr[0],
290*61046927SAndroid Build Coastguard Worker                 chunk_ptr[1], chunk_ptr[2], chunk_ptr[3]);
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker          cur_chunk++;
293*61046927SAndroid Build Coastguard Worker          if (cur_chunk == 8) {
294*61046927SAndroid Build Coastguard Worker             cur_block = next_pointers[cur_block];
295*61046927SAndroid Build Coastguard Worker             if (verbose)
296*61046927SAndroid Build Coastguard Worker                printf("\tblock %x\n", cur_block);
297*61046927SAndroid Build Coastguard Worker             if (cur_block >= num_blocks) {
298*61046927SAndroid Build Coastguard Worker                fprintf(stderr, "block %x too large\n", cur_block);
299*61046927SAndroid Build Coastguard Worker                exit(1);
300*61046927SAndroid Build Coastguard Worker             }
301*61046927SAndroid Build Coastguard Worker             cur_chunk = 0;
302*61046927SAndroid Build Coastguard Worker          }
303*61046927SAndroid Build Coastguard Worker       }
304*61046927SAndroid Build Coastguard Worker       if (calculated_queue_size != queue_sizes[queue]) {
305*61046927SAndroid Build Coastguard Worker          printf("\t\tCALCULATED SIZE %d DOES NOT MATCH!\n",
306*61046927SAndroid Build Coastguard Worker                 calculated_queue_size);
307*61046927SAndroid Build Coastguard Worker       }
308*61046927SAndroid Build Coastguard Worker       printf("\n");
309*61046927SAndroid Build Coastguard Worker    }
310*61046927SAndroid Build Coastguard Worker }
311*61046927SAndroid Build Coastguard Worker 
312