mirror of https://github.com/acidanthera/audk.git
259 lines
8.0 KiB
C
259 lines
8.0 KiB
C
/** @file
|
|
|
|
This file provides the information dump support for EHCI when in debug mode.
|
|
|
|
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
|
|
#include "Ehci.h"
|
|
|
|
/**
|
|
Dump the status byte in QTD/QH to a more friendly format.
|
|
|
|
@param State The state in the QTD/QH.
|
|
|
|
**/
|
|
VOID
|
|
EhcDumpStatus (
|
|
IN UINT32 State
|
|
)
|
|
{
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_DO_PING)) {
|
|
DEBUG ((EFI_D_INFO, " Do_Ping"));
|
|
} else {
|
|
DEBUG ((EFI_D_INFO, " Do_Out"));
|
|
}
|
|
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_DO_CS)) {
|
|
DEBUG ((EFI_D_INFO, " Do_CS"));
|
|
} else {
|
|
DEBUG ((EFI_D_INFO, " Do_SS"));
|
|
}
|
|
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR)) {
|
|
DEBUG ((EFI_D_INFO, " Transfer_Error"));
|
|
}
|
|
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) {
|
|
DEBUG ((EFI_D_INFO, " Babble_Error"));
|
|
}
|
|
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) {
|
|
DEBUG ((EFI_D_INFO, " Buffer_Error"));
|
|
}
|
|
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) {
|
|
DEBUG ((EFI_D_INFO, " Halted"));
|
|
}
|
|
|
|
if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) {
|
|
DEBUG ((EFI_D_INFO, " Active"));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "\n"));
|
|
}
|
|
|
|
|
|
/**
|
|
Dump the fields of a QTD.
|
|
|
|
@param Qtd The QTD to dump.
|
|
@param Msg The message to print before the dump.
|
|
|
|
**/
|
|
VOID
|
|
EhcDumpQtd (
|
|
IN EHC_QTD *Qtd,
|
|
IN CHAR8 *Msg
|
|
)
|
|
{
|
|
QTD_HW *QtdHw;
|
|
UINTN Index;
|
|
|
|
if (Msg != NULL) {
|
|
DEBUG ((EFI_D_INFO, Msg));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "Queue TD @ 0x%p, data length %d\n", Qtd, (UINT32)Qtd->DataLen));
|
|
|
|
QtdHw = &Qtd->QtdHw;
|
|
|
|
DEBUG ((EFI_D_INFO, "Next QTD : %x\n", QtdHw->NextQtd));
|
|
DEBUG ((EFI_D_INFO, "AltNext QTD : %x\n", QtdHw->AltNext));
|
|
DEBUG ((EFI_D_INFO, "Status : %x\n", QtdHw->Status));
|
|
EhcDumpStatus (QtdHw->Status);
|
|
|
|
if (QtdHw->Pid == QTD_PID_SETUP) {
|
|
DEBUG ((EFI_D_INFO, "PID : Setup\n"));
|
|
|
|
} else if (QtdHw->Pid == QTD_PID_INPUT) {
|
|
DEBUG ((EFI_D_INFO, "PID : IN\n"));
|
|
|
|
} else if (QtdHw->Pid == QTD_PID_OUTPUT) {
|
|
DEBUG ((EFI_D_INFO, "PID : OUT\n"));
|
|
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "Error Count : %d\n", QtdHw->ErrCnt));
|
|
DEBUG ((EFI_D_INFO, "Current Page : %d\n", QtdHw->CurPage));
|
|
DEBUG ((EFI_D_INFO, "IOC : %d\n", QtdHw->Ioc));
|
|
DEBUG ((EFI_D_INFO, "Total Bytes : %d\n", QtdHw->TotalBytes));
|
|
DEBUG ((EFI_D_INFO, "Data Toggle : %d\n", QtdHw->DataToggle));
|
|
|
|
for (Index = 0; Index < 5; Index++) {
|
|
DEBUG ((EFI_D_INFO, "Page[%d] : 0x%x\n", (UINT32)Index, QtdHw->Page[Index]));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Dump the queue head.
|
|
|
|
@param Qh The queue head to dump.
|
|
@param Msg The message to print before the dump.
|
|
@param DumpBuf Whether to dump the memory buffer of the associated QTD.
|
|
|
|
**/
|
|
VOID
|
|
EhcDumpQh (
|
|
IN EHC_QH *Qh,
|
|
IN CHAR8 *Msg,
|
|
IN BOOLEAN DumpBuf
|
|
)
|
|
{
|
|
EHC_QTD *Qtd;
|
|
QH_HW *QhHw;
|
|
LIST_ENTRY *Entry;
|
|
UINTN Index;
|
|
|
|
if (Msg != NULL) {
|
|
DEBUG ((EFI_D_INFO, Msg));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "Queue head @ 0x%p, interval %ld, next qh %p\n",
|
|
Qh, (UINT64)Qh->Interval, Qh->NextQh));
|
|
|
|
QhHw = &Qh->QhHw;
|
|
|
|
DEBUG ((EFI_D_INFO, "Hoziontal link: %x\n", QhHw->HorizonLink));
|
|
DEBUG ((EFI_D_INFO, "Device address: %d\n", QhHw->DeviceAddr));
|
|
DEBUG ((EFI_D_INFO, "Inactive : %d\n", QhHw->Inactive));
|
|
DEBUG ((EFI_D_INFO, "EP number : %d\n", QhHw->EpNum));
|
|
DEBUG ((EFI_D_INFO, "EP speed : %d\n", QhHw->EpSpeed));
|
|
DEBUG ((EFI_D_INFO, "DT control : %d\n", QhHw->DtCtrl));
|
|
DEBUG ((EFI_D_INFO, "Reclaim head : %d\n", QhHw->ReclaimHead));
|
|
DEBUG ((EFI_D_INFO, "Max packet len: %d\n", QhHw->MaxPacketLen));
|
|
DEBUG ((EFI_D_INFO, "Ctrl EP : %d\n", QhHw->CtrlEp));
|
|
DEBUG ((EFI_D_INFO, "Nak reload : %d\n", QhHw->NakReload));
|
|
|
|
DEBUG ((EFI_D_INFO, "SMask : %x\n", QhHw->SMask));
|
|
DEBUG ((EFI_D_INFO, "CMask : %x\n", QhHw->CMask));
|
|
DEBUG ((EFI_D_INFO, "Hub address : %d\n", QhHw->HubAddr));
|
|
DEBUG ((EFI_D_INFO, "Hub port : %d\n", QhHw->PortNum));
|
|
DEBUG ((EFI_D_INFO, "Multiplier : %d\n", QhHw->Multiplier));
|
|
|
|
DEBUG ((EFI_D_INFO, "Cur QTD : %x\n", QhHw->CurQtd));
|
|
|
|
DEBUG ((EFI_D_INFO, "Next QTD : %x\n", QhHw->NextQtd));
|
|
DEBUG ((EFI_D_INFO, "AltNext QTD : %x\n", QhHw->AltQtd));
|
|
DEBUG ((EFI_D_INFO, "Status : %x\n", QhHw->Status));
|
|
|
|
EhcDumpStatus (QhHw->Status);
|
|
|
|
if (QhHw->Pid == QTD_PID_SETUP) {
|
|
DEBUG ((EFI_D_INFO, "PID : Setup\n"));
|
|
|
|
} else if (QhHw->Pid == QTD_PID_INPUT) {
|
|
DEBUG ((EFI_D_INFO, "PID : IN\n"));
|
|
|
|
} else if (QhHw->Pid == QTD_PID_OUTPUT) {
|
|
DEBUG ((EFI_D_INFO, "PID : OUT\n"));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "Error Count : %d\n", QhHw->ErrCnt));
|
|
DEBUG ((EFI_D_INFO, "Current Page : %d\n", QhHw->CurPage));
|
|
DEBUG ((EFI_D_INFO, "IOC : %d\n", QhHw->Ioc));
|
|
DEBUG ((EFI_D_INFO, "Total Bytes : %d\n", QhHw->TotalBytes));
|
|
DEBUG ((EFI_D_INFO, "Data Toggle : %d\n", QhHw->DataToggle));
|
|
|
|
for (Index = 0; Index < 5; Index++) {
|
|
DEBUG ((EFI_D_INFO, "Page[%d] : 0x%x\n", Index, QhHw->Page[Index]));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "\n"));
|
|
|
|
EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) {
|
|
Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);
|
|
EhcDumpQtd (Qtd, NULL);
|
|
|
|
if (DumpBuf && (Qtd->DataLen != 0)) {
|
|
EhcDumpBuf (Qtd->Data, Qtd->DataLen);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Dump the buffer in the form of hex.
|
|
|
|
@param Buf The buffer to dump.
|
|
@param Len The length of buffer.
|
|
|
|
**/
|
|
VOID
|
|
EhcDumpBuf (
|
|
IN UINT8 *Buf,
|
|
IN UINTN Len
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < Len; Index++) {
|
|
if (Index % 16 == 0) {
|
|
DEBUG ((EFI_D_INFO,"\n"));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "%02x ", Buf[Index]));
|
|
}
|
|
|
|
DEBUG ((EFI_D_INFO, "\n"));
|
|
}
|
|
|
|
/**
|
|
Dump the EHCI status registers.
|
|
|
|
@param Ehc USB EHCI Host Controller instance
|
|
|
|
**/
|
|
VOID
|
|
EhcDumpRegs (
|
|
IN USB2_HC_DEV *Ehc
|
|
)
|
|
{
|
|
UINT8 Index;
|
|
|
|
DEBUG ((EFI_D_INFO, " EHC_CAPLENGTH_OFFSET = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_HCSPARAMS_OFFSET = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_HCSPARAMS_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_HCCPARAMS_OFFSET = 0x%08x\n", EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_USBCMD_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBCMD_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_USBSTS_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBSTS_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_USBINTR_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_USBINTR_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_FRINDEX_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_FRINDEX_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_CTRLDSSEG_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_CTRLDSSEG_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_FRAME_BASE_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_FRAME_BASE_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_ASYNC_HEAD_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET)));
|
|
DEBUG ((EFI_D_INFO, " EHC_CONFIG_FLAG_OFFSET = 0x%08x\n", EhcReadOpReg (Ehc, EHC_CONFIG_FLAG_OFFSET)));
|
|
for (Index = 0; Index < (UINT8) (Ehc->HcStructParams & HCSP_NPORTS); Index++) {
|
|
DEBUG ((EFI_D_INFO, " EHC_PORT_STAT_OFFSET(%d) = 0x%08x\n", Index, EhcReadOpReg (Ehc, EHC_PORT_STAT_OFFSET + (4 * Index))));
|
|
}
|
|
}
|