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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution.  The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10 
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 
17 #include "Ehci.h"
18 
19 /**
20   Dump the status byte in QTD/QH to a more friendly format.
21 
22   @param  State    The state in the QTD/QH.
23 
24 **/
25 VOID
EhcDumpStatus(IN UINT32 State)26 EhcDumpStatus (
27   IN UINT32               State
28   )
29 {
30   if (EHC_BIT_IS_SET (State, QTD_STAT_DO_PING)) {
31     DEBUG ((EFI_D_VERBOSE, "  Do_Ping"));
32   } else {
33     DEBUG ((EFI_D_VERBOSE, "  Do_Out"));
34   }
35 
36   if (EHC_BIT_IS_SET (State, QTD_STAT_DO_CS)) {
37     DEBUG ((EFI_D_VERBOSE, "  Do_CS"));
38   } else {
39     DEBUG ((EFI_D_VERBOSE, "  Do_SS"));
40   }
41 
42   if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR)) {
43     DEBUG ((EFI_D_VERBOSE, "  Transfer_Error"));
44   }
45 
46   if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) {
47     DEBUG ((EFI_D_VERBOSE, "  Babble_Error"));
48   }
49 
50   if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) {
51     DEBUG ((EFI_D_VERBOSE, "  Buffer_Error"));
52   }
53 
54   if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) {
55     DEBUG ((EFI_D_VERBOSE, "  Halted"));
56   }
57 
58   if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) {
59     DEBUG ((EFI_D_VERBOSE, "  Active"));
60   }
61 
62   DEBUG ((EFI_D_VERBOSE, "\n"));
63 }
64 
65 
66 /**
67   Dump the fields of a QTD.
68 
69   @param  Qtd      The QTD to dump.
70   @param  Msg      The message to print before the dump.
71 
72 **/
73 VOID
EhcDumpQtd(IN EHC_QTD * Qtd,IN CHAR8 * Msg)74 EhcDumpQtd (
75   IN EHC_QTD              *Qtd,
76   IN CHAR8                *Msg
77   )
78 {
79   QTD_HW                  *QtdHw;
80   UINTN                   Index;
81 
82   if (Msg != NULL) {
83     DEBUG ((EFI_D_VERBOSE, Msg));
84   }
85 
86   DEBUG ((EFI_D_VERBOSE, "Queue TD @ 0x%p, data length %d\n", Qtd, (UINT32)Qtd->DataLen));
87 
88   QtdHw = &Qtd->QtdHw;
89 
90   DEBUG ((EFI_D_VERBOSE, "Next QTD     : %x\n", QtdHw->NextQtd));
91   DEBUG ((EFI_D_VERBOSE, "AltNext QTD  : %x\n", QtdHw->AltNext));
92   DEBUG ((EFI_D_VERBOSE, "Status       : %x\n", QtdHw->Status));
93   EhcDumpStatus (QtdHw->Status);
94 
95   if (QtdHw->Pid == QTD_PID_SETUP) {
96     DEBUG ((EFI_D_VERBOSE, "PID          : Setup\n"));
97 
98   } else if (QtdHw->Pid == QTD_PID_INPUT) {
99     DEBUG ((EFI_D_VERBOSE, "PID          : IN\n"));
100 
101   } else if (QtdHw->Pid == QTD_PID_OUTPUT) {
102     DEBUG ((EFI_D_VERBOSE, "PID          : OUT\n"));
103 
104   }
105 
106   DEBUG ((EFI_D_VERBOSE, "Error Count  : %d\n", QtdHw->ErrCnt));
107   DEBUG ((EFI_D_VERBOSE, "Current Page : %d\n", QtdHw->CurPage));
108   DEBUG ((EFI_D_VERBOSE, "IOC          : %d\n", QtdHw->Ioc));
109   DEBUG ((EFI_D_VERBOSE, "Total Bytes  : %d\n", QtdHw->TotalBytes));
110   DEBUG ((EFI_D_VERBOSE, "Data Toggle  : %d\n", QtdHw->DataToggle));
111 
112   for (Index = 0; Index < 5; Index++) {
113     DEBUG ((EFI_D_VERBOSE, "Page[%d]      : 0x%x\n", (UINT32)Index, QtdHw->Page[Index]));
114   }
115 }
116 
117 
118 /**
119   Dump the queue head.
120 
121   @param  Qh       The queue head to dump.
122   @param  Msg      The message to print before the dump.
123   @param  DumpBuf  Whether to dump the memory buffer of the associated QTD.
124 
125 **/
126 VOID
EhcDumpQh(IN EHC_QH * Qh,IN CHAR8 * Msg,IN BOOLEAN DumpBuf)127 EhcDumpQh (
128   IN EHC_QH               *Qh,
129   IN CHAR8                *Msg,
130   IN BOOLEAN              DumpBuf
131   )
132 {
133   EHC_QTD                 *Qtd;
134   QH_HW                   *QhHw;
135   LIST_ENTRY              *Entry;
136   UINTN                   Index;
137 
138   if (Msg != NULL) {
139     DEBUG ((EFI_D_VERBOSE, Msg));
140   }
141 
142   DEBUG ((EFI_D_VERBOSE, "Queue head @ 0x%p, interval %ld, next qh %p\n",
143                                 Qh, (UINT64)Qh->Interval, Qh->NextQh));
144 
145   QhHw = &Qh->QhHw;
146 
147   DEBUG ((EFI_D_VERBOSE, "Hoziontal link: %x\n", QhHw->HorizonLink));
148   DEBUG ((EFI_D_VERBOSE, "Device address: %d\n", QhHw->DeviceAddr));
149   DEBUG ((EFI_D_VERBOSE, "Inactive      : %d\n", QhHw->Inactive));
150   DEBUG ((EFI_D_VERBOSE, "EP number     : %d\n", QhHw->EpNum));
151   DEBUG ((EFI_D_VERBOSE, "EP speed      : %d\n", QhHw->EpSpeed));
152   DEBUG ((EFI_D_VERBOSE, "DT control    : %d\n", QhHw->DtCtrl));
153   DEBUG ((EFI_D_VERBOSE, "Reclaim head  : %d\n", QhHw->ReclaimHead));
154   DEBUG ((EFI_D_VERBOSE, "Max packet len: %d\n", QhHw->MaxPacketLen));
155   DEBUG ((EFI_D_VERBOSE, "Ctrl EP       : %d\n", QhHw->CtrlEp));
156   DEBUG ((EFI_D_VERBOSE, "Nak reload    : %d\n", QhHw->NakReload));
157 
158   DEBUG ((EFI_D_VERBOSE, "SMask         : %x\n", QhHw->SMask));
159   DEBUG ((EFI_D_VERBOSE, "CMask         : %x\n", QhHw->CMask));
160   DEBUG ((EFI_D_VERBOSE, "Hub address   : %d\n", QhHw->HubAddr));
161   DEBUG ((EFI_D_VERBOSE, "Hub port      : %d\n", QhHw->PortNum));
162   DEBUG ((EFI_D_VERBOSE, "Multiplier    : %d\n", QhHw->Multiplier));
163 
164   DEBUG ((EFI_D_VERBOSE, "Cur QTD       : %x\n", QhHw->CurQtd));
165 
166   DEBUG ((EFI_D_VERBOSE, "Next QTD      : %x\n", QhHw->NextQtd));
167   DEBUG ((EFI_D_VERBOSE, "AltNext QTD   : %x\n", QhHw->AltQtd));
168   DEBUG ((EFI_D_VERBOSE, "Status        : %x\n", QhHw->Status));
169 
170   EhcDumpStatus (QhHw->Status);
171 
172   if (QhHw->Pid == QTD_PID_SETUP) {
173     DEBUG ((EFI_D_VERBOSE, "PID           : Setup\n"));
174 
175   } else if (QhHw->Pid == QTD_PID_INPUT) {
176     DEBUG ((EFI_D_VERBOSE, "PID           : IN\n"));
177 
178   } else if (QhHw->Pid == QTD_PID_OUTPUT) {
179     DEBUG ((EFI_D_VERBOSE, "PID           : OUT\n"));
180   }
181 
182   DEBUG ((EFI_D_VERBOSE, "Error Count   : %d\n", QhHw->ErrCnt));
183   DEBUG ((EFI_D_VERBOSE, "Current Page  : %d\n", QhHw->CurPage));
184   DEBUG ((EFI_D_VERBOSE, "IOC           : %d\n", QhHw->Ioc));
185   DEBUG ((EFI_D_VERBOSE, "Total Bytes   : %d\n", QhHw->TotalBytes));
186   DEBUG ((EFI_D_VERBOSE, "Data Toggle   : %d\n", QhHw->DataToggle));
187 
188   for (Index = 0; Index < 5; Index++) {
189     DEBUG ((EFI_D_VERBOSE, "Page[%d]       : 0x%x\n", Index, QhHw->Page[Index]));
190   }
191 
192   DEBUG ((EFI_D_VERBOSE, "\n"));
193 
194   EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) {
195     Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);
196     EhcDumpQtd (Qtd, NULL);
197 
198     if (DumpBuf && (Qtd->DataLen != 0)) {
199       EhcDumpBuf (Qtd->Data, Qtd->DataLen);
200     }
201   }
202 }
203 
204 
205 /**
206   Dump the buffer in the form of hex.
207 
208   @param  Buf      The buffer to dump.
209   @param  Len      The length of buffer.
210 
211 **/
212 VOID
EhcDumpBuf(IN UINT8 * Buf,IN UINTN Len)213 EhcDumpBuf (
214   IN UINT8                *Buf,
215   IN UINTN                Len
216   )
217 {
218   UINTN                   Index;
219 
220   for (Index = 0; Index < Len; Index++) {
221     if (Index % 16 == 0) {
222       DEBUG ((EFI_D_VERBOSE,"\n"));
223     }
224 
225     DEBUG ((EFI_D_VERBOSE, "%02x ", Buf[Index]));
226   }
227 
228   DEBUG ((EFI_D_VERBOSE, "\n"));
229 }
230 
231 /**
232   Dump the EHCI status registers.
233 
234   @param  Ehc    USB EHCI Host Controller instance
235 
236 **/
237 VOID
EhcDumpRegs(IN USB2_HC_DEV * Ehc)238 EhcDumpRegs (
239   IN  USB2_HC_DEV         *Ehc
240   )
241 {
242   UINT8   Index;
243 
244   DEBUG ((EFI_D_VERBOSE, "  EHC_CAPLENGTH_OFFSET   = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET)));
245   DEBUG ((EFI_D_VERBOSE, "  EHC_HCSPARAMS_OFFSET   = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_HCSPARAMS_OFFSET)));
246   DEBUG ((EFI_D_VERBOSE, "  EHC_HCCPARAMS_OFFSET   = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET)));
247   DEBUG ((EFI_D_VERBOSE, "  EHC_USBCMD_OFFSET      = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBCMD_OFFSET)));
248   DEBUG ((EFI_D_VERBOSE, "  EHC_USBSTS_OFFSET      = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET)));
249   DEBUG ((EFI_D_VERBOSE, "  EHC_USBINTR_OFFSET     = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBINTR_OFFSET)));
250   DEBUG ((EFI_D_VERBOSE, "  EHC_FRINDEX_OFFSET     = 0x%08x\n", EhcReadOpReg (Ehc, EHC_FRINDEX_OFFSET)));
251   DEBUG ((EFI_D_VERBOSE, "  EHC_CTRLDSSEG_OFFSET   = 0x%08x\n", EhcReadOpReg (Ehc,  EHC_CTRLDSSEG_OFFSET)));
252   DEBUG ((EFI_D_VERBOSE, "  EHC_FRAME_BASE_OFFSET  = 0x%08x\n", EhcReadOpReg (Ehc,  EHC_FRAME_BASE_OFFSET)));
253   DEBUG ((EFI_D_VERBOSE, "  EHC_ASYNC_HEAD_OFFSET  = 0x%08x\n", EhcReadOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET)));
254   DEBUG ((EFI_D_VERBOSE, "  EHC_CONFIG_FLAG_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_CONFIG_FLAG_OFFSET)));
255   for (Index = 0; Index < (UINT8) (Ehc->HcStructParams & HCSP_NPORTS); Index++) {
256     DEBUG ((EFI_D_VERBOSE, "  EHC_PORT_STAT_OFFSET(%d)  = 0x%08x\n", Index, EhcReadOpReg (Ehc, EHC_PORT_STAT_OFFSET + (4 * Index))));
257   }
258 }
259