1210284Sjmallett/***********************license start***************
2232812Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3215990Sjmallett * reserved.
4210284Sjmallett *
5210284Sjmallett *
6215990Sjmallett * Redistribution and use in source and binary forms, with or without
7215990Sjmallett * modification, are permitted provided that the following conditions are
8215990Sjmallett * met:
9210284Sjmallett *
10215990Sjmallett *   * Redistributions of source code must retain the above copyright
11215990Sjmallett *     notice, this list of conditions and the following disclaimer.
12210284Sjmallett *
13215990Sjmallett *   * Redistributions in binary form must reproduce the above
14215990Sjmallett *     copyright notice, this list of conditions and the following
15215990Sjmallett *     disclaimer in the documentation and/or other materials provided
16215990Sjmallett *     with the distribution.
17215990Sjmallett
18232812Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19215990Sjmallett *     its contributors may be used to endorse or promote products
20215990Sjmallett *     derived from this software without specific prior written
21215990Sjmallett *     permission.
22215990Sjmallett
23215990Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24215990Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25215990Sjmallett * regulations, and may be subject to export or import  regulations in other
26215990Sjmallett * countries.
27215990Sjmallett
28215990Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232812Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30215990Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31215990Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32215990Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33215990Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34215990Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35215990Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36215990Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37215990Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38210284Sjmallett ***********************license end**************************************/
39210284Sjmallett
40210284Sjmallett
41210284Sjmallett
42210284Sjmallett
43210284Sjmallett
44210284Sjmallett
45215990Sjmallett
46210284Sjmallett/**
47210284Sjmallett * @file
48210284Sjmallett *
49210284Sjmallett * Interface to the hardware Packet Order / Work unit.
50210284Sjmallett *
51210284Sjmallett * <hr>$Revision: 29727 $<hr>
52210284Sjmallett */
53210284Sjmallett
54210284Sjmallett#include "cvmx.h"
55210284Sjmallett#include "cvmx-pow.h"
56210284Sjmallett
57210284Sjmallett/**
58210284Sjmallett * @INTERNAL
59210284Sjmallett * This structure stores the internal POW state captured by
60210284Sjmallett * cvmx_pow_capture(). It is purposely not exposed to the user
61210284Sjmallett * since the format may change without notice.
62210284Sjmallett */
63210284Sjmalletttypedef struct
64210284Sjmallett{
65232812Sjmallett    cvmx_pow_tag_load_resp_t sstatus[CVMX_MAX_CORES][8];
66232812Sjmallett    cvmx_pow_tag_load_resp_t smemload[2048][8];
67232812Sjmallett    cvmx_pow_tag_load_resp_t sindexload[64][8];
68210284Sjmallett} __cvmx_pow_dump_t;
69210284Sjmallett
70210284Sjmalletttypedef enum
71210284Sjmallett{
72210284Sjmallett    CVMX_POW_LIST_UNKNOWN=0,
73210284Sjmallett    CVMX_POW_LIST_FREE=1,
74210284Sjmallett    CVMX_POW_LIST_INPUT=2,
75210284Sjmallett    CVMX_POW_LIST_CORE=CVMX_POW_LIST_INPUT+8,
76232812Sjmallett    CVMX_POW_LIST_DESCHED=CVMX_POW_LIST_CORE+32,
77232812Sjmallett    CVMX_POW_LIST_NOSCHED=CVMX_POW_LIST_DESCHED+64,
78210284Sjmallett} __cvmx_pow_list_types_t;
79210284Sjmallett
80210284Sjmallettstatic const char *__cvmx_pow_list_names[] = {
81210284Sjmallett    "Unknown",
82210284Sjmallett    "Free List",
83210284Sjmallett    "Queue 0", "Queue 1", "Queue 2", "Queue 3",
84210284Sjmallett    "Queue 4", "Queue 5", "Queue 6", "Queue 7",
85210284Sjmallett    "Core 0", "Core 1", "Core 2", "Core 3",
86210284Sjmallett    "Core 4", "Core 5", "Core 6", "Core 7",
87210284Sjmallett    "Core 8", "Core 9", "Core 10", "Core 11",
88210284Sjmallett    "Core 12", "Core 13", "Core 14", "Core 15",
89232812Sjmallett    "Core 16", "Core 17", "Core 18", "Core 19",
90232812Sjmallett    "Core 20", "Core 21", "Core 22", "Core 23",
91232812Sjmallett    "Core 24", "Core 25", "Core 26", "Core 27",
92232812Sjmallett    "Core 28", "Core 29", "Core 30", "Core 31",
93210284Sjmallett    "Desched 0", "Desched 1", "Desched 2", "Desched 3",
94210284Sjmallett    "Desched 4", "Desched 5", "Desched 6", "Desched 7",
95210284Sjmallett    "Desched 8", "Desched 9", "Desched 10", "Desched 11",
96210284Sjmallett    "Desched 12", "Desched 13", "Desched 14", "Desched 15",
97232812Sjmallett    "Desched 16", "Desched 17", "Desched 18", "Desched 19",
98232812Sjmallett    "Desched 20", "Desched 21", "Desched 22", "Desched 23",
99232812Sjmallett    "Desched 24", "Desched 25", "Desched 26", "Desched 27",
100232812Sjmallett    "Desched 28", "Desched 29", "Desched 30", "Desched 31",
101232812Sjmallett    "Desched 32", "Desched 33", "Desched 34", "Desched 35",
102232812Sjmallett    "Desched 36", "Desched 37", "Desched 38", "Desched 39",
103232812Sjmallett    "Desched 40", "Desched 41", "Desched 42", "Desched 43",
104232812Sjmallett    "Desched 44", "Desched 45", "Desched 46", "Desched 47",
105232812Sjmallett    "Desched 48", "Desched 49", "Desched 50", "Desched 51",
106232812Sjmallett    "Desched 52", "Desched 53", "Desched 54", "Desched 55",
107232812Sjmallett    "Desched 56", "Desched 57", "Desched 58", "Desched 59",
108232812Sjmallett    "Desched 60", "Desched 61", "Desched 62", "Desched 63",
109232812Sjmallett    "Nosched 0"
110210284Sjmallett};
111210284Sjmallett
112210284Sjmallett
113210284Sjmallett/**
114210284Sjmallett * Return the number of POW entries supported by this chip
115210284Sjmallett *
116210284Sjmallett * @return Number of POW entries
117210284Sjmallett */
118210284Sjmallettint cvmx_pow_get_num_entries(void)
119210284Sjmallett{
120210284Sjmallett    if (OCTEON_IS_MODEL(OCTEON_CN30XX))
121210284Sjmallett        return 64;
122210284Sjmallett    else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
123210284Sjmallett        return 256;
124232812Sjmallett    else if (OCTEON_IS_MODEL(OCTEON_CN52XX)
125232812Sjmallett             || OCTEON_IS_MODEL(OCTEON_CN61XX)
126232812Sjmallett             || OCTEON_IS_MODEL(OCTEON_CNF71XX))
127210284Sjmallett        return 512;
128232812Sjmallett    else if (OCTEON_IS_MODEL(OCTEON_CN63XX) || OCTEON_IS_MODEL(OCTEON_CN66XX))
129215990Sjmallett	return 1024;
130210284Sjmallett    else
131210284Sjmallett        return 2048;
132210284Sjmallett}
133210284Sjmallett
134210284Sjmallett
135232812Sjmallettstatic int __cvmx_pow_capture_v1(void *buffer, int buffer_size)
136210284Sjmallett{
137210284Sjmallett    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
138210284Sjmallett    int num_cores;
139210284Sjmallett    int num_pow_entries = cvmx_pow_get_num_entries();
140210284Sjmallett    int core;
141210284Sjmallett    int index;
142210284Sjmallett    int bits;
143210284Sjmallett
144210284Sjmallett    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
145210284Sjmallett    {
146210284Sjmallett        cvmx_dprintf("cvmx_pow_capture: Buffer too small\n");
147210284Sjmallett        return -1;
148210284Sjmallett    }
149210284Sjmallett
150210284Sjmallett    num_cores = cvmx_octeon_num_cores();
151210284Sjmallett
152210284Sjmallett    /* Read all core related state */
153210284Sjmallett    for (core=0; core<num_cores; core++)
154210284Sjmallett    {
155210284Sjmallett        cvmx_pow_load_addr_t load_addr;
156210284Sjmallett        load_addr.u64 = 0;
157210284Sjmallett        load_addr.sstatus.mem_region = CVMX_IO_SEG;
158210284Sjmallett        load_addr.sstatus.is_io = 1;
159210284Sjmallett        load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
160210284Sjmallett        load_addr.sstatus.coreid = core;
161210284Sjmallett        for (bits=0; bits<8; bits++)
162210284Sjmallett        {
163210284Sjmallett            load_addr.sstatus.get_rev = (bits & 1) != 0;
164210284Sjmallett            load_addr.sstatus.get_cur = (bits & 2) != 0;
165210284Sjmallett            load_addr.sstatus.get_wqp = (bits & 4) != 0;
166210284Sjmallett            if ((load_addr.sstatus.get_cur == 0) && load_addr.sstatus.get_rev)
167210284Sjmallett                dump->sstatus[core][bits].u64 = -1;
168210284Sjmallett            else
169210284Sjmallett                dump->sstatus[core][bits].u64 = cvmx_read_csr(load_addr.u64);
170210284Sjmallett        }
171210284Sjmallett    }
172210284Sjmallett
173210284Sjmallett    /* Read all internal POW entries */
174210284Sjmallett    for (index=0; index<num_pow_entries; index++)
175210284Sjmallett    {
176210284Sjmallett        cvmx_pow_load_addr_t load_addr;
177210284Sjmallett        load_addr.u64 = 0;
178210284Sjmallett        load_addr.smemload.mem_region = CVMX_IO_SEG;
179210284Sjmallett        load_addr.smemload.is_io = 1;
180210284Sjmallett        load_addr.smemload.did = CVMX_OCT_DID_TAG_TAG2;
181210284Sjmallett        load_addr.smemload.index = index;
182210284Sjmallett        for (bits=0; bits<3; bits++)
183210284Sjmallett        {
184210284Sjmallett            load_addr.smemload.get_des = (bits & 1) != 0;
185210284Sjmallett            load_addr.smemload.get_wqp = (bits & 2) != 0;
186210284Sjmallett            dump->smemload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
187210284Sjmallett        }
188210284Sjmallett    }
189210284Sjmallett
190210284Sjmallett    /* Read all group and queue pointers */
191210284Sjmallett    for (index=0; index<16; index++)
192210284Sjmallett    {
193210284Sjmallett        cvmx_pow_load_addr_t load_addr;
194210284Sjmallett        load_addr.u64 = 0;
195210284Sjmallett        load_addr.sindexload.mem_region = CVMX_IO_SEG;
196210284Sjmallett        load_addr.sindexload.is_io = 1;
197210284Sjmallett        load_addr.sindexload.did = CVMX_OCT_DID_TAG_TAG3;
198210284Sjmallett        load_addr.sindexload.qosgrp = index;
199210284Sjmallett        for (bits=0; bits<4; bits++)
200210284Sjmallett        {
201210284Sjmallett            load_addr.sindexload.get_rmt =  (bits & 1) != 0;
202210284Sjmallett            load_addr.sindexload.get_des_get_tail =  (bits & 2) != 0;
203210284Sjmallett            /* The first pass only has 8 valid index values */
204210284Sjmallett            if ((load_addr.sindexload.get_rmt == 0) &&
205210284Sjmallett                (load_addr.sindexload.get_des_get_tail == 0) &&
206210284Sjmallett                (index >= 8))
207210284Sjmallett                dump->sindexload[index][bits].u64 = -1;
208210284Sjmallett            else
209210284Sjmallett                dump->sindexload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
210210284Sjmallett        }
211210284Sjmallett    }
212210284Sjmallett    return 0;
213210284Sjmallett}
214210284Sjmallett
215232812Sjmallettstatic int __cvmx_pow_capture_v2(void *buffer, int buffer_size)
216232812Sjmallett{
217232812Sjmallett    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
218232812Sjmallett    int num_cores;
219232812Sjmallett    int num_pow_entries = cvmx_pow_get_num_entries();
220232812Sjmallett    int core;
221232812Sjmallett    int index;
222232812Sjmallett    int bits;
223210284Sjmallett
224232812Sjmallett    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
225232812Sjmallett    {
226232812Sjmallett        cvmx_dprintf("cvmx_pow_capture: Buffer too small\n");
227232812Sjmallett        return -1;
228232812Sjmallett    }
229232812Sjmallett
230232812Sjmallett    num_cores = cvmx_octeon_num_cores();
231232812Sjmallett
232232812Sjmallett    /* Read all core related state */
233232812Sjmallett    for (core=0; core<num_cores; core++)
234232812Sjmallett    {
235232812Sjmallett        cvmx_pow_load_addr_t load_addr;
236232812Sjmallett        load_addr.u64 = 0;
237232812Sjmallett        load_addr.sstatus_cn68xx.mem_region = CVMX_IO_SEG;
238232812Sjmallett        load_addr.sstatus_cn68xx.is_io = 1;
239232812Sjmallett        load_addr.sstatus_cn68xx.did = CVMX_OCT_DID_TAG_TAG5;
240232812Sjmallett        load_addr.sstatus_cn68xx.coreid = core;
241232812Sjmallett        for (bits=1; bits<6; bits++)
242232812Sjmallett        {
243232812Sjmallett            load_addr.sstatus_cn68xx.opcode = bits;
244232812Sjmallett            dump->sstatus[core][bits].u64 = cvmx_read_csr(load_addr.u64);
245232812Sjmallett        }
246232812Sjmallett    }
247232812Sjmallett    /* Read all internal POW entries */
248232812Sjmallett    for (index=0; index<num_pow_entries; index++)
249232812Sjmallett    {
250232812Sjmallett        cvmx_pow_load_addr_t load_addr;
251232812Sjmallett        load_addr.u64 = 0;
252232812Sjmallett        load_addr.smemload_cn68xx.mem_region = CVMX_IO_SEG;
253232812Sjmallett        load_addr.smemload_cn68xx.is_io = 1;
254232812Sjmallett        load_addr.smemload_cn68xx.did = CVMX_OCT_DID_TAG_TAG2;
255232812Sjmallett        load_addr.smemload_cn68xx.index = index;
256232812Sjmallett        for (bits=1; bits<5; bits++)
257232812Sjmallett        {
258232812Sjmallett            load_addr.smemload_cn68xx.opcode = bits;
259232812Sjmallett            dump->smemload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
260232812Sjmallett        }
261232812Sjmallett    }
262232812Sjmallett
263232812Sjmallett    /* Read all group and queue pointers */
264232812Sjmallett    for (index=0; index<64; index++)
265232812Sjmallett    {
266232812Sjmallett        cvmx_pow_load_addr_t load_addr;
267232812Sjmallett        load_addr.u64 = 0;
268232812Sjmallett        load_addr.sindexload_cn68xx.mem_region = CVMX_IO_SEG;
269232812Sjmallett        load_addr.sindexload_cn68xx.is_io = 1;
270232812Sjmallett        load_addr.sindexload_cn68xx.did = CVMX_OCT_DID_TAG_TAG3;
271232812Sjmallett        load_addr.sindexload_cn68xx.qos_grp = index;
272232812Sjmallett        for (bits=1; bits<7; bits++)
273232812Sjmallett        {
274232812Sjmallett            load_addr.sindexload_cn68xx.opcode = bits;
275232812Sjmallett            dump->sindexload[index][bits].u64 = cvmx_read_csr(load_addr.u64);
276232812Sjmallett        }
277232812Sjmallett    }
278232812Sjmallett    return 0;
279232812Sjmallett}
280232812Sjmallett
281210284Sjmallett/**
282232812Sjmallett * Store the current POW internal state into the supplied
283232812Sjmallett * buffer. It is recommended that you pass a buffer of at least
284232812Sjmallett * 128KB. The format of the capture may change based on SDK
285232812Sjmallett * version and Octeon chip.
286232812Sjmallett *
287232812Sjmallett * @param buffer Buffer to store capture into
288232812Sjmallett * @param buffer_size
289232812Sjmallett *               The size of the supplied buffer
290232812Sjmallett *
291232812Sjmallett * @return Zero on sucess, negative on failure
292232812Sjmallett */
293232812Sjmallettint cvmx_pow_capture(void *buffer, int buffer_size)
294232812Sjmallett{
295232812Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_PKND))
296232812Sjmallett        return __cvmx_pow_capture_v2(buffer, buffer_size);
297232812Sjmallett    else
298232812Sjmallett        return __cvmx_pow_capture_v1(buffer, buffer_size);
299232812Sjmallett}
300232812Sjmallett
301232812Sjmallett/**
302210284Sjmallett * Function to display a POW internal queue to the user
303210284Sjmallett *
304210284Sjmallett * @param name       User visible name for the queue
305210284Sjmallett * @param name_param Parameter for printf in creating the name
306210284Sjmallett * @param valid      Set if the queue contains any elements
307210284Sjmallett * @param has_one    Set if the queue contains exactly one element
308210284Sjmallett * @param head       The head pointer
309210284Sjmallett * @param tail       The tail pointer
310210284Sjmallett */
311210284Sjmallettstatic void __cvmx_pow_display_list(const char *name, int name_param, int valid, int has_one, uint64_t head, uint64_t tail)
312210284Sjmallett{
313210284Sjmallett    printf(name, name_param);
314210284Sjmallett    printf(": ");
315210284Sjmallett    if (valid)
316210284Sjmallett    {
317210284Sjmallett        if (has_one)
318210284Sjmallett            printf("One element index=%llu(0x%llx)\n", CAST64(head), CAST64(head));
319210284Sjmallett        else
320210284Sjmallett            printf("Multiple elements head=%llu(0x%llx) tail=%llu(0x%llx)\n", CAST64(head), CAST64(head), CAST64(tail), CAST64(tail));
321210284Sjmallett    }
322210284Sjmallett    else
323210284Sjmallett        printf("Empty\n");
324210284Sjmallett}
325210284Sjmallett
326210284Sjmallett
327210284Sjmallett/**
328210284Sjmallett * Mark which list a POW entry is on. Print a warning message if the
329210284Sjmallett * entry is already on a list. This happens if the POW changed while
330210284Sjmallett * the capture was running.
331210284Sjmallett *
332210284Sjmallett * @param entry_num  Entry number to mark
333210284Sjmallett * @param entry_type List type
334210284Sjmallett * @param entry_list Array to store marks
335210284Sjmallett *
336210284Sjmallett * @return Zero on success, negative if already on a list
337210284Sjmallett */
338210284Sjmallettstatic int __cvmx_pow_entry_mark_list(int entry_num, __cvmx_pow_list_types_t entry_type, uint8_t entry_list[])
339210284Sjmallett{
340210284Sjmallett    if (entry_list[entry_num] == 0)
341210284Sjmallett    {
342210284Sjmallett        entry_list[entry_num] = entry_type;
343210284Sjmallett        return 0;
344210284Sjmallett    }
345210284Sjmallett    else
346210284Sjmallett    {
347210284Sjmallett        printf("\nWARNING: Entry %d already on list %s, but we tried to add it to %s\n",
348210284Sjmallett               entry_num, __cvmx_pow_list_names[entry_list[entry_num]], __cvmx_pow_list_names[entry_type]);
349210284Sjmallett        return -1;
350210284Sjmallett    }
351210284Sjmallett}
352210284Sjmallett
353210284Sjmallett
354210284Sjmallett/**
355210284Sjmallett * Display a list and mark all elements on the list as belonging to
356210284Sjmallett * the list.
357210284Sjmallett *
358210284Sjmallett * @param entry_type Type of the list to display and mark
359210284Sjmallett * @param dump       POW capture data
360210284Sjmallett * @param entry_list Array to store marks in
361210284Sjmallett * @param valid      Set if the queue contains any elements
362210284Sjmallett * @param has_one    Set if the queue contains exactly one element
363210284Sjmallett * @param head       The head pointer
364210284Sjmallett * @param tail       The tail pointer
365210284Sjmallett */
366210284Sjmallettstatic void __cvmx_pow_display_list_and_walk(__cvmx_pow_list_types_t entry_type,
367210284Sjmallett                                             __cvmx_pow_dump_t *dump, uint8_t entry_list[],
368210284Sjmallett                                             int valid, int has_one, uint64_t head, uint64_t tail)
369210284Sjmallett{
370210284Sjmallett    __cvmx_pow_display_list(__cvmx_pow_list_names[entry_type], 0, valid, has_one, head, tail);
371210284Sjmallett    if (valid)
372210284Sjmallett    {
373210284Sjmallett        if (has_one)
374210284Sjmallett            __cvmx_pow_entry_mark_list(head, entry_type, entry_list);
375210284Sjmallett        else
376210284Sjmallett        {
377210284Sjmallett            while (head != tail)
378210284Sjmallett            {
379210284Sjmallett                if (__cvmx_pow_entry_mark_list(head, entry_type, entry_list))
380210284Sjmallett                    break;
381232812Sjmallett                if (octeon_has_feature(OCTEON_FEATURE_PKND))
382232812Sjmallett                {
383232812Sjmallett                    if (entry_type >= CVMX_POW_LIST_INPUT && entry_type < CVMX_POW_LIST_CORE)
384232812Sjmallett
385232812Sjmallett                        head = dump->smemload[head][4].s_smemload3_cn68xx.next_index;
386232812Sjmallett                    else
387232812Sjmallett                        head = dump->smemload[head][4].s_smemload3_cn68xx.fwd_index;
388232812Sjmallett                }
389232812Sjmallett                else
390232812Sjmallett                    head = dump->smemload[head][0].s_smemload0.next_index;
391210284Sjmallett            }
392210284Sjmallett            __cvmx_pow_entry_mark_list(tail, entry_type, entry_list);
393210284Sjmallett        }
394210284Sjmallett    }
395210284Sjmallett}
396210284Sjmallett
397210284Sjmallett
398232812Sjmallettvoid __cvmx_pow_display_v1(void *buffer, int buffer_size)
399210284Sjmallett{
400210284Sjmallett    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
401210284Sjmallett    int num_pow_entries = cvmx_pow_get_num_entries();
402210284Sjmallett    int num_cores;
403210284Sjmallett    int core;
404210284Sjmallett    int index;
405210284Sjmallett    uint8_t entry_list[2048];
406210284Sjmallett
407210284Sjmallett    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
408210284Sjmallett    {
409210284Sjmallett        cvmx_dprintf("cvmx_pow_dump: Buffer too small\n");
410210284Sjmallett        return;
411210284Sjmallett    }
412210284Sjmallett
413210284Sjmallett    memset(entry_list, 0, sizeof(entry_list));
414210284Sjmallett    num_cores = cvmx_octeon_num_cores();
415210284Sjmallett
416210284Sjmallett    /* Print the free list info */
417210284Sjmallett    __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_FREE, dump, entry_list,
418210284Sjmallett                                     dump->sindexload[0][0].sindexload0.free_val,
419210284Sjmallett                                     dump->sindexload[0][0].sindexload0.free_one,
420210284Sjmallett                                     dump->sindexload[0][0].sindexload0.free_head,
421210284Sjmallett                                     dump->sindexload[0][0].sindexload0.free_tail);
422210284Sjmallett
423210284Sjmallett    /* Print the core state */
424210284Sjmallett    for (core=0; core<num_cores; core++)
425210284Sjmallett    {
426210284Sjmallett        const int bit_rev = 1;
427210284Sjmallett        const int bit_cur = 2;
428210284Sjmallett        const int bit_wqp = 4;
429210284Sjmallett        printf("Core %d State:  tag=%s,0x%08x", core,
430210284Sjmallett               OCT_TAG_TYPE_STRING(dump->sstatus[core][bit_cur].s_sstatus2.tag_type),
431210284Sjmallett               dump->sstatus[core][bit_cur].s_sstatus2.tag);
432210284Sjmallett        if (dump->sstatus[core][bit_cur].s_sstatus2.tag_type != CVMX_POW_TAG_TYPE_NULL_NULL)
433210284Sjmallett        {
434210284Sjmallett            __cvmx_pow_entry_mark_list(dump->sstatus[core][bit_cur].s_sstatus2.index, CVMX_POW_LIST_CORE + core, entry_list);
435210284Sjmallett            printf(" grp=%d",                   dump->sstatus[core][bit_cur].s_sstatus2.grp);
436210284Sjmallett            printf(" wqp=0x%016llx",            CAST64(dump->sstatus[core][bit_cur|bit_wqp].s_sstatus4.wqp));
437210284Sjmallett            printf(" index=%d",                 dump->sstatus[core][bit_cur].s_sstatus2.index);
438210284Sjmallett            if (dump->sstatus[core][bit_cur].s_sstatus2.head)
439210284Sjmallett                printf(" head");
440210284Sjmallett            else
441210284Sjmallett                printf(" prev=%d", dump->sstatus[core][bit_cur|bit_rev].s_sstatus3.revlink_index);
442210284Sjmallett            if (dump->sstatus[core][bit_cur].s_sstatus2.tail)
443210284Sjmallett                printf(" tail");
444210284Sjmallett            else
445210284Sjmallett                printf(" next=%d", dump->sstatus[core][bit_cur].s_sstatus2.link_index);
446210284Sjmallett        }
447210284Sjmallett
448210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_switch)
449210284Sjmallett        {
450210284Sjmallett            printf(" pend_switch=%d",           dump->sstatus[core][0].s_sstatus0.pend_switch);
451210284Sjmallett            printf(" pend_switch_full=%d",      dump->sstatus[core][0].s_sstatus0.pend_switch_full);
452210284Sjmallett            printf(" pend_switch_null=%d",      dump->sstatus[core][0].s_sstatus0.pend_switch_null);
453210284Sjmallett        }
454210284Sjmallett
455210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_desched)
456210284Sjmallett        {
457210284Sjmallett            printf(" pend_desched=%d",          dump->sstatus[core][0].s_sstatus0.pend_desched);
458210284Sjmallett            printf(" pend_desched_switch=%d",   dump->sstatus[core][0].s_sstatus0.pend_desched_switch);
459210284Sjmallett            printf(" pend_nosched=%d",          dump->sstatus[core][0].s_sstatus0.pend_nosched);
460210284Sjmallett            if (dump->sstatus[core][0].s_sstatus0.pend_desched_switch)
461210284Sjmallett                printf(" pend_grp=%d",              dump->sstatus[core][0].s_sstatus0.pend_grp);
462210284Sjmallett        }
463210284Sjmallett
464210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_new_work)
465210284Sjmallett        {
466210284Sjmallett            if (dump->sstatus[core][0].s_sstatus0.pend_new_work_wait)
467210284Sjmallett                printf(" (Waiting for work)");
468210284Sjmallett            else
469210284Sjmallett                printf(" (Getting work)");
470210284Sjmallett        }
471210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_null_rd)
472210284Sjmallett            printf(" pend_null_rd=%d",          dump->sstatus[core][0].s_sstatus0.pend_null_rd);
473210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_nosched_clr)
474210284Sjmallett        {
475210284Sjmallett            printf(" pend_nosched_clr=%d",      dump->sstatus[core][0].s_sstatus0.pend_nosched_clr);
476210284Sjmallett            printf(" pend_index=%d",            dump->sstatus[core][0].s_sstatus0.pend_index);
477210284Sjmallett        }
478210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_switch ||
479210284Sjmallett            (dump->sstatus[core][0].s_sstatus0.pend_desched &&
480210284Sjmallett            dump->sstatus[core][0].s_sstatus0.pend_desched_switch))
481210284Sjmallett        {
482210284Sjmallett            printf(" pending tag=%s,0x%08x",
483210284Sjmallett                   OCT_TAG_TYPE_STRING(dump->sstatus[core][0].s_sstatus0.pend_type),
484210284Sjmallett                   dump->sstatus[core][0].s_sstatus0.pend_tag);
485210284Sjmallett        }
486210284Sjmallett        if (dump->sstatus[core][0].s_sstatus0.pend_nosched_clr)
487210284Sjmallett            printf(" pend_wqp=0x%016llx\n",     CAST64(dump->sstatus[core][bit_wqp].s_sstatus1.pend_wqp));
488210284Sjmallett        printf("\n");
489210284Sjmallett    }
490210284Sjmallett
491215990Sjmallett    /* Print out the state of the nosched list and the 16 deschedule lists. */
492215990Sjmallett    __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_NOSCHED, dump, entry_list,
493215990Sjmallett                            dump->sindexload[0][2].sindexload1.nosched_val,
494215990Sjmallett                            dump->sindexload[0][2].sindexload1.nosched_one,
495215990Sjmallett                            dump->sindexload[0][2].sindexload1.nosched_head,
496215990Sjmallett                            dump->sindexload[0][2].sindexload1.nosched_tail);
497210284Sjmallett    for (index=0; index<16; index++)
498210284Sjmallett    {
499210284Sjmallett        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_DESCHED + index, dump, entry_list,
500210284Sjmallett                                dump->sindexload[index][2].sindexload1.des_val,
501210284Sjmallett                                dump->sindexload[index][2].sindexload1.des_one,
502210284Sjmallett                                dump->sindexload[index][2].sindexload1.des_head,
503210284Sjmallett                                dump->sindexload[index][2].sindexload1.des_tail);
504210284Sjmallett    }
505210284Sjmallett
506210284Sjmallett    /* Print out the state of the 8 internal input queues */
507210284Sjmallett    for (index=0; index<8; index++)
508210284Sjmallett    {
509210284Sjmallett        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_INPUT + index, dump, entry_list,
510210284Sjmallett                                dump->sindexload[index][0].sindexload0.loc_val,
511210284Sjmallett                                dump->sindexload[index][0].sindexload0.loc_one,
512210284Sjmallett                                dump->sindexload[index][0].sindexload0.loc_head,
513210284Sjmallett                                dump->sindexload[index][0].sindexload0.loc_tail);
514210284Sjmallett    }
515210284Sjmallett
516210284Sjmallett    /* Print out the state of the 16 memory queues */
517210284Sjmallett    for (index=0; index<8; index++)
518210284Sjmallett    {
519210284Sjmallett        const char *name;
520210284Sjmallett        if (dump->sindexload[index][1].sindexload2.rmt_is_head)
521210284Sjmallett            name = "Queue %da Memory (is head)";
522210284Sjmallett        else
523210284Sjmallett            name = "Queue %da Memory";
524210284Sjmallett        __cvmx_pow_display_list(name, index,
525210284Sjmallett                                dump->sindexload[index][1].sindexload2.rmt_val,
526210284Sjmallett                                dump->sindexload[index][1].sindexload2.rmt_one,
527210284Sjmallett                                dump->sindexload[index][1].sindexload2.rmt_head,
528210284Sjmallett                                dump->sindexload[index][3].sindexload3.rmt_tail);
529210284Sjmallett        if (dump->sindexload[index+8][1].sindexload2.rmt_is_head)
530210284Sjmallett            name = "Queue %db Memory (is head)";
531210284Sjmallett        else
532210284Sjmallett            name = "Queue %db Memory";
533210284Sjmallett        __cvmx_pow_display_list(name, index,
534210284Sjmallett                                dump->sindexload[index+8][1].sindexload2.rmt_val,
535210284Sjmallett                                dump->sindexload[index+8][1].sindexload2.rmt_one,
536210284Sjmallett                                dump->sindexload[index+8][1].sindexload2.rmt_head,
537210284Sjmallett                                dump->sindexload[index+8][3].sindexload3.rmt_tail);
538210284Sjmallett    }
539210284Sjmallett
540210284Sjmallett    /* Print out each of the internal POW entries. Each entry has a tag, group,
541210284Sjmallett        wqe, and possibly a next pointer. The next pointer is only valid if this
542210284Sjmallett        entry isn't make as a tail */
543210284Sjmallett    for (index=0; index<num_pow_entries; index++)
544210284Sjmallett    {
545210284Sjmallett        printf("Entry %d(%-10s): tag=%s,0x%08x grp=%d wqp=0x%016llx", index,
546210284Sjmallett               __cvmx_pow_list_names[entry_list[index]],
547210284Sjmallett               OCT_TAG_TYPE_STRING(dump->smemload[index][0].s_smemload0.tag_type),
548210284Sjmallett               dump->smemload[index][0].s_smemload0.tag,
549210284Sjmallett               dump->smemload[index][0].s_smemload0.grp,
550210284Sjmallett               CAST64(dump->smemload[index][2].s_smemload1.wqp));
551210284Sjmallett        if (dump->smemload[index][0].s_smemload0.tail)
552210284Sjmallett            printf(" tail");
553210284Sjmallett        else
554210284Sjmallett            printf(" next=%d", dump->smemload[index][0].s_smemload0.next_index);
555210284Sjmallett        if (entry_list[index] >= CVMX_POW_LIST_DESCHED)
556210284Sjmallett        {
557210284Sjmallett            printf(" nosched=%d", dump->smemload[index][1].s_smemload2.nosched);
558210284Sjmallett            if (dump->smemload[index][1].s_smemload2.pend_switch)
559210284Sjmallett            {
560210284Sjmallett                printf(" pending tag=%s,0x%08x",
561210284Sjmallett                       OCT_TAG_TYPE_STRING(dump->smemload[index][1].s_smemload2.pend_type),
562210284Sjmallett                       dump->smemload[index][1].s_smemload2.pend_tag);
563210284Sjmallett            }
564210284Sjmallett        }
565210284Sjmallett        printf("\n");
566210284Sjmallett    }
567232812Sjmallett}
568210284Sjmallett
569232812Sjmallettvoid __cvmx_pow_display_v2(void *buffer, int buffer_size)
570232812Sjmallett{
571232812Sjmallett    __cvmx_pow_dump_t *dump = (__cvmx_pow_dump_t*)buffer;
572232812Sjmallett    int num_pow_entries = cvmx_pow_get_num_entries();
573232812Sjmallett    int num_cores;
574232812Sjmallett    int core;
575232812Sjmallett    int index;
576232812Sjmallett    uint8_t entry_list[2048];
577232812Sjmallett
578232812Sjmallett    if (buffer_size < (int)sizeof(__cvmx_pow_dump_t))
579232812Sjmallett    {
580232812Sjmallett        cvmx_dprintf("cvmx_pow_dump: Buffer too small, pow_dump_t = 0x%x, buffer_size = 0x%x\n", (int)sizeof(__cvmx_pow_dump_t), buffer_size);
581232812Sjmallett        return;
582232812Sjmallett    }
583232812Sjmallett
584232812Sjmallett    memset(entry_list, 0, sizeof(entry_list));
585232812Sjmallett    num_cores = cvmx_octeon_num_cores();
586232812Sjmallett
587232812Sjmallett    /* Print the free list info */
588232812Sjmallett    {
589232812Sjmallett        int valid[3], has_one[3], head[3], tail[3], qnum_head, qnum_tail;
590232812Sjmallett        int idx;
591232812Sjmallett
592232812Sjmallett        valid[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_val;
593232812Sjmallett        valid[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_val;
594232812Sjmallett        valid[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_val;
595232812Sjmallett        has_one[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_one;
596232812Sjmallett        has_one[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_one;
597232812Sjmallett        has_one[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_one;
598232812Sjmallett        head[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_head;
599232812Sjmallett        head[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_head;
600232812Sjmallett        head[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_head;
601232812Sjmallett        tail[0] = dump->sindexload[0][4].sindexload1_cn68xx.queue_tail;
602232812Sjmallett        tail[1] = dump->sindexload[0][5].sindexload1_cn68xx.queue_tail;
603232812Sjmallett        tail[2] = dump->sindexload[0][6].sindexload1_cn68xx.queue_tail;
604232812Sjmallett        qnum_head = dump->sindexload[0][4].sindexload1_cn68xx.qnum_head;
605232812Sjmallett        qnum_tail = dump->sindexload[0][4].sindexload1_cn68xx.qnum_tail;
606232812Sjmallett
607232812Sjmallett        printf("Free List: qnum_head=%d, qnum_tail=%d\n", qnum_head, qnum_tail);
608232812Sjmallett        printf("Free0: valid=%d, one=%d, head=%llu, tail=%llu\n", valid[0], has_one[0], CAST64(head[0]), CAST64(tail[0]));
609232812Sjmallett        printf("Free1: valid=%d, one=%d, head=%llu, tail=%llu\n", valid[1], has_one[1], CAST64(head[1]), CAST64(tail[1]));
610232812Sjmallett        printf("Free2: valid=%d, one=%d, head=%llu, tail=%llu\n", valid[2], has_one[2], CAST64(head[2]), CAST64(tail[2]));
611232812Sjmallett
612232812Sjmallett        idx=qnum_head;
613232812Sjmallett        while (valid[0] || valid[1] || valid[2])
614232812Sjmallett        {
615232812Sjmallett            int qidx = idx % 3;
616232812Sjmallett
617232812Sjmallett            if (head[qidx] == tail[qidx])
618232812Sjmallett                valid[qidx] = 0;
619232812Sjmallett
620232812Sjmallett            if (__cvmx_pow_entry_mark_list(head[qidx], CVMX_POW_LIST_FREE, entry_list))
621232812Sjmallett                break;
622232812Sjmallett            head[qidx] = dump->smemload[head[qidx]][4].s_smemload3_cn68xx.fwd_index;
623232812Sjmallett            //printf("qidx = %d, idx = %d, head[qidx] = %d\n", qidx, idx, head[qidx]);
624232812Sjmallett            idx++;
625232812Sjmallett        }
626232812Sjmallett    }
627232812Sjmallett
628232812Sjmallett    /* Print the core state */
629232812Sjmallett    for (core = 0; core < num_cores; core++)
630232812Sjmallett    {
631232812Sjmallett        int pendtag = 1;
632232812Sjmallett        int pendwqp = 2;
633232812Sjmallett        int tag = 3;
634232812Sjmallett        int wqp = 4;
635232812Sjmallett        int links = 5;
636232812Sjmallett
637232812Sjmallett        printf("Core %d State: tag=%s,0x%08x", core,
638232812Sjmallett               OCT_TAG_TYPE_STRING(dump->sstatus[core][tag].s_sstatus2_cn68xx.tag_type),
639232812Sjmallett               dump->sstatus[core][tag].s_sstatus2_cn68xx.tag);
640232812Sjmallett        if (dump->sstatus[core][tag].s_sstatus2_cn68xx.tag_type != CVMX_POW_TAG_TYPE_NULL_NULL)
641232812Sjmallett        {
642232812Sjmallett            __cvmx_pow_entry_mark_list(dump->sstatus[core][tag].s_sstatus2_cn68xx.index, CVMX_POW_LIST_CORE + core, entry_list);
643232812Sjmallett            printf(" grp=%d",                   dump->sstatus[core][tag].s_sstatus2_cn68xx.grp);
644232812Sjmallett            printf(" wqp=0x%016llx",            CAST64(dump->sstatus[core][wqp].s_sstatus3_cn68xx.wqp));
645232812Sjmallett            printf(" index=%d",                 dump->sstatus[core][tag].s_sstatus2_cn68xx.index);
646232812Sjmallett            if (dump->sstatus[core][links].s_sstatus4_cn68xx.head)
647232812Sjmallett                printf(" head");
648232812Sjmallett            else
649232812Sjmallett                printf(" prev=%d", dump->sstatus[core][links].s_sstatus4_cn68xx.revlink_index);
650232812Sjmallett            if (dump->sstatus[core][links].s_sstatus4_cn68xx.tail)
651232812Sjmallett                printf(" tail");
652232812Sjmallett            else
653232812Sjmallett                printf(" next=%d", dump->sstatus[core][links].s_sstatus4_cn68xx.link_index);
654232812Sjmallett        }
655232812Sjmallett        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_switch)
656232812Sjmallett        {
657232812Sjmallett            printf(" pend_switch=%d",           dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_switch);
658232812Sjmallett        }
659232812Sjmallett
660232812Sjmallett        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_desched)
661232812Sjmallett        {
662232812Sjmallett            printf(" pend_desched=%d",          dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_desched);
663232812Sjmallett            printf(" pend_nosched=%d",          dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_nosched);
664232812Sjmallett        }
665232812Sjmallett        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_get_work)
666232812Sjmallett        {
667232812Sjmallett            if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_get_work_wait)
668232812Sjmallett                printf(" (Waiting for work)");
669232812Sjmallett            else
670232812Sjmallett                printf(" (Getting work)");
671232812Sjmallett        }
672232812Sjmallett        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_alloc_we)
673232812Sjmallett            printf(" pend_alloc_we=%d",          dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_alloc_we);
674232812Sjmallett        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_nosched_clr)
675232812Sjmallett        {
676232812Sjmallett            printf(" pend_nosched_clr=%d",      dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_nosched_clr);
677232812Sjmallett            printf(" pend_index=%d",            dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_index);
678232812Sjmallett        }
679232812Sjmallett        if (dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_switch)
680232812Sjmallett        {
681232812Sjmallett            printf(" pending tag=%s,0x%08x",
682232812Sjmallett                   OCT_TAG_TYPE_STRING(dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_type),
683232812Sjmallett                   dump->sstatus[core][pendtag].s_sstatus0_cn68xx.pend_tag);
684232812Sjmallett        }
685232812Sjmallett        if (dump->sstatus[core][pendwqp].s_sstatus1_cn68xx.pend_nosched_clr)
686232812Sjmallett            printf(" pend_wqp=0x%016llx\n",     CAST64(dump->sstatus[core][pendwqp].s_sstatus1_cn68xx.pend_wqp));
687232812Sjmallett        printf("\n");
688232812Sjmallett    }
689232812Sjmallett
690232812Sjmallett    /* Print out the state of the nosched list and the 16 deschedule lists. */
691232812Sjmallett    __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_NOSCHED, dump, entry_list,
692232812Sjmallett                            dump->sindexload[0][3].sindexload0_cn68xx.queue_val,
693232812Sjmallett                            dump->sindexload[0][3].sindexload0_cn68xx.queue_one,
694232812Sjmallett                            dump->sindexload[0][3].sindexload0_cn68xx.queue_head,
695232812Sjmallett                            dump->sindexload[0][3].sindexload0_cn68xx.queue_tail);
696232812Sjmallett    for (index=0; index<64; index++)
697232812Sjmallett    {
698232812Sjmallett        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_DESCHED + index, dump, entry_list,
699232812Sjmallett                                dump->sindexload[index][2].sindexload0_cn68xx.queue_val,
700232812Sjmallett                                dump->sindexload[index][2].sindexload0_cn68xx.queue_one,
701232812Sjmallett                                dump->sindexload[index][2].sindexload0_cn68xx.queue_head,
702232812Sjmallett                                dump->sindexload[index][2].sindexload0_cn68xx.queue_tail);
703232812Sjmallett    }
704232812Sjmallett
705232812Sjmallett    /* Print out the state of the 8 internal input queues */
706232812Sjmallett    for (index=0; index<8; index++)
707232812Sjmallett    {
708232812Sjmallett        __cvmx_pow_display_list_and_walk(CVMX_POW_LIST_INPUT + index, dump, entry_list,
709232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_val,
710232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_one,
711232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_head,
712232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_tail);
713232812Sjmallett    }
714232812Sjmallett
715232812Sjmallett    /* Print out the state of the 16 memory queues */
716232812Sjmallett    for (index=0; index<8; index++)
717232812Sjmallett    {
718232812Sjmallett        const char *name;
719232812Sjmallett        if (dump->sindexload[index][1].sindexload0_cn68xx.queue_head)
720232812Sjmallett            name = "Queue %da Memory (is head)";
721232812Sjmallett        else
722232812Sjmallett            name = "Queue %da Memory";
723232812Sjmallett        __cvmx_pow_display_list(name, index,
724232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_val,
725232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_one,
726232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_head,
727232812Sjmallett                                dump->sindexload[index][1].sindexload0_cn68xx.queue_tail);
728232812Sjmallett        if (dump->sindexload[index+8][1].sindexload0_cn68xx.queue_head)
729232812Sjmallett            name = "Queue %db Memory (is head)";
730232812Sjmallett        else
731232812Sjmallett            name = "Queue %db Memory";
732232812Sjmallett        __cvmx_pow_display_list(name, index,
733232812Sjmallett                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_val,
734232812Sjmallett                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_one,
735232812Sjmallett                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_head,
736232812Sjmallett                                dump->sindexload[index+8][1].sindexload0_cn68xx.queue_tail);
737232812Sjmallett    }
738232812Sjmallett
739232812Sjmallett    /* Print out each of the internal POW entries. Each entry has a tag, group,
740232812Sjmallett       wqe, and possibly a next pointer. The next pointer is only valid if this
741232812Sjmallett       entry isn't make as a tail */
742232812Sjmallett    for (index=0; index<num_pow_entries; index++)
743232812Sjmallett    {
744232812Sjmallett        printf("Entry %d(%-10s): tag=%s,0x%08x grp=%d wqp=0x%016llx", index,
745232812Sjmallett               __cvmx_pow_list_names[entry_list[index]],
746232812Sjmallett               OCT_TAG_TYPE_STRING(dump->smemload[index][1].s_smemload0_cn68xx.tag_type),
747232812Sjmallett               dump->smemload[index][1].s_smemload0_cn68xx.tag,
748232812Sjmallett               dump->smemload[index][2].s_smemload1_cn68xx.grp,
749232812Sjmallett               CAST64(dump->smemload[index][2].s_smemload1_cn68xx.wqp));
750232812Sjmallett        if (dump->smemload[index][1].s_smemload0_cn68xx.tail)
751232812Sjmallett            printf(" tail");
752232812Sjmallett        else
753232812Sjmallett            printf(" next=%d", dump->smemload[index][4].s_smemload3_cn68xx.fwd_index);
754232812Sjmallett        if (entry_list[index] >= CVMX_POW_LIST_DESCHED)
755232812Sjmallett        {
756232812Sjmallett            printf(" prev=%d", dump->smemload[index][4].s_smemload3_cn68xx.fwd_index);
757232812Sjmallett            printf(" nosched=%d", dump->smemload[index][1].s_smemload1_cn68xx.nosched);
758232812Sjmallett            if (dump->smemload[index][3].s_smemload2_cn68xx.pend_switch)
759232812Sjmallett            {
760232812Sjmallett                printf(" pending tag=%s,0x%08x",
761232812Sjmallett                       OCT_TAG_TYPE_STRING(dump->smemload[index][3].s_smemload2_cn68xx.pend_type),
762232812Sjmallett                       dump->smemload[index][3].s_smemload2_cn68xx.pend_tag);
763232812Sjmallett            }
764232812Sjmallett        }
765232812Sjmallett        printf("\n");
766232812Sjmallett    }
767232812Sjmallett}
768232812Sjmallett
769232812Sjmallett/**
770232812Sjmallett * Dump a POW capture to the console in a human readable format.
771232812Sjmallett *
772232812Sjmallett * @param buffer POW capture from cvmx_pow_capture()
773232812Sjmallett * @param buffer_size
774232812Sjmallett *               Size of the buffer
775232812Sjmallett */
776232812Sjmallettvoid cvmx_pow_display(void *buffer, int buffer_size)
777232812Sjmallett{
778232812Sjmallett    printf("POW Display Start\n");
779232812Sjmallett
780232812Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_PKND))
781232812Sjmallett        __cvmx_pow_display_v2(buffer, buffer_size);
782232812Sjmallett    else
783232812Sjmallett        __cvmx_pow_display_v1(buffer, buffer_size);
784232812Sjmallett
785210284Sjmallett    printf("POW Display End\n");
786232812Sjmallett    return;
787210284Sjmallett}
788210284Sjmallett
789