1 /** @file
2 
3   This file provides the information dump support for EHCI when in debug mode.
4 
5 Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
6 Copyright (c) Microsoft Corporation.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 
12 #include "Ehci.h"
13 
14 /**
15   Dump the status byte in QTD/QH to a more friendly format.
16 
17   @param  State    The state in the QTD/QH.
18 
19 **/
20 VOID
EhcDumpStatus(IN UINT32 State)21 EhcDumpStatus (
22   IN UINT32               State
23   )
24 {
25   if (EHC_BIT_IS_SET (State, QTD_STAT_DO_PING)) {
26     DEBUG ((EFI_D_VERBOSE, "  Do_Ping"));
27   } else {
28     DEBUG ((EFI_D_VERBOSE, "  Do_Out"));
29   }
30 
31   if (EHC_BIT_IS_SET (State, QTD_STAT_DO_CS)) {
32     DEBUG ((EFI_D_VERBOSE, "  Do_CS"));
33   } else {
34     DEBUG ((EFI_D_VERBOSE, "  Do_SS"));
35   }
36 
37   if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR)) {
38     DEBUG ((EFI_D_VERBOSE, "  Transfer_Error"));
39   }
40 
41   if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) {
42     DEBUG ((EFI_D_VERBOSE, "  Babble_Error"));
43   }
44 
45   if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) {
46     DEBUG ((EFI_D_VERBOSE, "  Buffer_Error"));
47   }
48 
49   if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) {
50     DEBUG ((EFI_D_VERBOSE, "  Halted"));
51   }
52 
53   if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) {
54     DEBUG ((EFI_D_VERBOSE, "  Active"));
55   }
56 
57   DEBUG ((EFI_D_VERBOSE, "\n"));
58 }
59 
60 
61 /**
62   Dump the fields of a QTD.
63 
64   @param  Qtd      The QTD to dump.
65   @param  Msg      The message to print before the dump.
66 
67 **/
68 VOID
EhcDumpQtd(IN EHC_QTD * Qtd,IN CHAR8 * Msg)69 EhcDumpQtd (
70   IN EHC_QTD              *Qtd,
71   IN CHAR8                *Msg
72   )
73 {
74   QTD_HW                  *QtdHw;
75   UINTN                   Index;
76 
77   if (Msg != NULL) {
78     DEBUG ((EFI_D_VERBOSE, Msg));
79   }
80 
81   DEBUG ((EFI_D_VERBOSE, "Queue TD @ 0x%p, data length %d\n", Qtd, (UINT32)Qtd->DataLen));
82 
83   QtdHw = &Qtd->QtdHw;
84 
85   DEBUG ((EFI_D_VERBOSE, "Next QTD     : %x\n", QtdHw->NextQtd));
86   DEBUG ((EFI_D_VERBOSE, "AltNext QTD  : %x\n", QtdHw->AltNext));
87   DEBUG ((EFI_D_VERBOSE, "Status       : %x\n", QtdHw->Status));
88   EhcDumpStatus (QtdHw->Status);
89 
90   if (QtdHw->Pid == QTD_PID_SETUP) {
91     DEBUG ((EFI_D_VERBOSE, "PID          : Setup\n"));
92 
93   } else if (QtdHw->Pid == QTD_PID_INPUT) {
94     DEBUG ((EFI_D_VERBOSE, "PID          : IN\n"));
95 
96   } else if (QtdHw->Pid == QTD_PID_OUTPUT) {
97     DEBUG ((EFI_D_VERBOSE, "PID          : OUT\n"));
98 
99   }
100 
101   DEBUG ((EFI_D_VERBOSE, "Error Count  : %d\n", QtdHw->ErrCnt));
102   DEBUG ((EFI_D_VERBOSE, "Current Page : %d\n", QtdHw->CurPage));
103   DEBUG ((EFI_D_VERBOSE, "IOC          : %d\n", QtdHw->Ioc));
104   DEBUG ((EFI_D_VERBOSE, "Total Bytes  : %d\n", QtdHw->TotalBytes));
105   DEBUG ((EFI_D_VERBOSE, "Data Toggle  : %d\n", QtdHw->DataToggle));
106 
107   for (Index = 0; Index < 5; Index++) {
108     DEBUG ((EFI_D_VERBOSE, "Page[%d]      : 0x%x\n", (UINT32)Index, QtdHw->Page[Index]));
109   }
110 }
111 
112 
113 /**
114   Dump the queue head.
115 
116   @param  Qh       The queue head to dump.
117   @param  Msg      The message to print before the dump.
118   @param  DumpBuf  Whether to dump the memory buffer of the associated QTD.
119 
120 **/
121 VOID
EhcDumpQh(IN EHC_QH * Qh,IN CHAR8 * Msg,IN BOOLEAN DumpBuf)122 EhcDumpQh (
123   IN EHC_QH               *Qh,
124   IN CHAR8                *Msg,
125   IN BOOLEAN              DumpBuf
126   )
127 {
128   EHC_QTD                 *Qtd;
129   QH_HW                   *QhHw;
130   LIST_ENTRY              *Entry;
131   UINTN                   Index;
132 
133   if (Msg != NULL) {
134     DEBUG ((EFI_D_VERBOSE, Msg));
135   }
136 
137   DEBUG ((EFI_D_VERBOSE, "Queue head @ 0x%p, interval %ld, next qh %p\n",
138                                 Qh, (UINT64)Qh->Interval, Qh->NextQh));
139 
140   QhHw = &Qh->QhHw;
141 
142   DEBUG ((EFI_D_VERBOSE, "Hoziontal link: %x\n", QhHw->HorizonLink));
143   DEBUG ((EFI_D_VERBOSE, "Device address: %d\n", QhHw->DeviceAddr));
144   DEBUG ((EFI_D_VERBOSE, "Inactive      : %d\n", QhHw->Inactive));
145   DEBUG ((EFI_D_VERBOSE, "EP number     : %d\n", QhHw->EpNum));
146   DEBUG ((EFI_D_VERBOSE, "EP speed      : %d\n", QhHw->EpSpeed));
147   DEBUG ((EFI_D_VERBOSE, "DT control    : %d\n", QhHw->DtCtrl));
148   DEBUG ((EFI_D_VERBOSE, "Reclaim head  : %d\n", QhHw->ReclaimHead));
149   DEBUG ((EFI_D_VERBOSE, "Max packet len: %d\n", QhHw->MaxPacketLen));
150   DEBUG ((EFI_D_VERBOSE, "Ctrl EP       : %d\n", QhHw->CtrlEp));
151   DEBUG ((EFI_D_VERBOSE, "Nak reload    : %d\n", QhHw->NakReload));
152 
153   DEBUG ((EFI_D_VERBOSE, "SMask         : %x\n", QhHw->SMask));
154   DEBUG ((EFI_D_VERBOSE, "CMask         : %x\n", QhHw->CMask));
155   DEBUG ((EFI_D_VERBOSE, "Hub address   : %d\n", QhHw->HubAddr));
156   DEBUG ((EFI_D_VERBOSE, "Hub port      : %d\n", QhHw->PortNum));
157   DEBUG ((EFI_D_VERBOSE, "Multiplier    : %d\n", QhHw->Multiplier));
158 
159   DEBUG ((EFI_D_VERBOSE, "Cur QTD       : %x\n", QhHw->CurQtd));
160 
161   DEBUG ((EFI_D_VERBOSE, "Next QTD      : %x\n", QhHw->NextQtd));
162   DEBUG ((EFI_D_VERBOSE, "AltNext QTD   : %x\n", QhHw->AltQtd));
163   DEBUG ((EFI_D_VERBOSE, "Status        : %x\n", QhHw->Status));
164 
165   EhcDumpStatus (QhHw->Status);
166 
167   if (QhHw->Pid == QTD_PID_SETUP) {
168     DEBUG ((EFI_D_VERBOSE, "PID           : Setup\n"));
169 
170   } else if (QhHw->Pid == QTD_PID_INPUT) {
171     DEBUG ((EFI_D_VERBOSE, "PID           : IN\n"));
172 
173   } else if (QhHw->Pid == QTD_PID_OUTPUT) {
174     DEBUG ((EFI_D_VERBOSE, "PID           : OUT\n"));
175   }
176 
177   DEBUG ((EFI_D_VERBOSE, "Error Count   : %d\n", QhHw->ErrCnt));
178   DEBUG ((EFI_D_VERBOSE, "Current Page  : %d\n", QhHw->CurPage));
179   DEBUG ((EFI_D_VERBOSE, "IOC           : %d\n", QhHw->Ioc));
180   DEBUG ((EFI_D_VERBOSE, "Total Bytes   : %d\n", QhHw->TotalBytes));
181   DEBUG ((EFI_D_VERBOSE, "Data Toggle   : %d\n", QhHw->DataToggle));
182 
183   for (Index = 0; Index < 5; Index++) {
184     DEBUG ((EFI_D_VERBOSE, "Page[%d]       : 0x%x\n", Index, QhHw->Page[Index]));
185   }
186 
187   DEBUG ((EFI_D_VERBOSE, "\n"));
188 
189   BASE_LIST_FOR_EACH (Entry, &Qh->Qtds) {
190     Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);
191     EhcDumpQtd (Qtd, NULL);
192 
193     if (DumpBuf && (Qtd->DataLen != 0)) {
194       EhcDumpBuf (Qtd->Data, Qtd->DataLen);
195     }
196   }
197 }
198 
199 
200 /**
201   Dump the buffer in the form of hex.
202 
203   @param  Buf      The buffer to dump.
204   @param  Len      The length of buffer.
205 
206 **/
207 VOID
EhcDumpBuf(IN UINT8 * Buf,IN UINTN Len)208 EhcDumpBuf (
209   IN UINT8                *Buf,
210   IN UINTN                Len
211   )
212 {
213   UINTN                   Index;
214 
215   for (Index = 0; Index < Len; Index++) {
216     if (Index % 16 == 0) {
217       DEBUG ((EFI_D_VERBOSE,"\n"));
218     }
219 
220     DEBUG ((EFI_D_VERBOSE, "%02x ", Buf[Index]));
221   }
222 
223   DEBUG ((EFI_D_VERBOSE, "\n"));
224 }
225 
226 
227