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 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 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 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 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 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