Home | History | Annotate | Download | only in EhciDxe
      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