uhchlp.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 3,348 行 · 第 1/5 页

C
3,348
字号
/*++

Copyright (c) 2004 - 2006, Intel Corporation                                                         
All rights reserved. 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.             

Module Name:

    UhcHlp.c
    
Abstract: 
    

Revision History
--*/

#include "uhci.h"

EFI_STATUS
USBReadPortW (
  IN       EFI_PCI_IO_PROTOCOL     *PciIo,
  IN       UINT32                  PortOffset,
  IN OUT   UINT16                  *Data
  )
/*++

Routine Description:

  USBReadPort Word

Arguments:

  PciIo       - EFI_PCI_IO_PROTOCOL
  PortOffset  - Port offset
  Data        - Data to reutrn

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Perform 16bit Read in PCI IO Space
  //
  return PciIo->Io.Read (
                     PciIo,
                     EfiPciIoWidthUint16,
                     USB_BAR_INDEX,
                     (UINT64) PortOffset,
                     1,
                     Data
                     );
}

EFI_STATUS
USBReadPortDW (
  IN       EFI_PCI_IO_PROTOCOL     *PciIo,
  IN       UINT32                  PortOffset,
  IN OUT   UINT32                  *Data
  )
/*++

Routine Description:

  USBReadPort DWord

Arguments:

  PciIo       - EFI_PCI_IO_PROTOCOL
  PortOffset  - Port offset
  Data        - Data to reutrn

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Perform 32bit Read in PCI IO Space
  //
  return PciIo->Io.Read (
                     PciIo,
                     EfiPciIoWidthUint32,
                     USB_BAR_INDEX,
                     (UINT64) PortOffset,
                     1,
                     Data
                     );
}

EFI_STATUS
USBWritePortW (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  PortOffset,
  IN UINT16                  Data
  )
/*++

Routine Description:

  USB Write Port Word

Arguments:

  PciIo       - EFI_PCI_IO_PROTOCOL
  PortOffset  - Port offset
  Data        - Data to write

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Perform 16bit Write in PCI IO Space
  //
  return PciIo->Io.Write (
                     PciIo,
                     EfiPciIoWidthUint16,
                     USB_BAR_INDEX,
                     (UINT64) PortOffset,
                     1,
                     &Data
                     );
}

EFI_STATUS
USBWritePortDW (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  PortOffset,
  IN UINT32                  Data
  )
/*++

Routine Description:

  USB Write Port DWord

Arguments:

  PciIo       - EFI_PCI_IO_PROTOCOL
  PortOffset  - Port offset
  Data        - Data to write

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Perform 32bit Write in PCI IO Space
  //
  return PciIo->Io.Write (
                     PciIo,
                     EfiPciIoWidthUint32,
                     USB_BAR_INDEX,
                     (UINT64) PortOffset,
                     1,
                     &Data
                     );
}
//
//  USB register-base helper functions
//
EFI_STATUS
WriteUHCCommandReg (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  CmdAddrOffset,
  IN UINT16                  UsbCmd
  )
/*++

Routine Description:

  Write UHCI Command Register

Arguments:

  PciIo         - EFI_PCI_IO_PROTOCOL
  CmdAddrOffset - Command address offset
  UsbCmd        - Data to write

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Write to UHC's Command Register
  //
  return USBWritePortW (PciIo, CmdAddrOffset, UsbCmd);
}

EFI_STATUS
ReadUHCCommandReg (
  IN       EFI_PCI_IO_PROTOCOL     *PciIo,
  IN       UINT32                  CmdAddrOffset,
  IN OUT   UINT16                  *Data
  )
/*++

Routine Description:

  Read UHCI Command Register

Arguments:

  PciIo         - EFI_PCI_IO_PROTOCOL
  CmdAddrOffset - Command address offset
  Data          - Data to return

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Read from UHC's Command Register
  //
  return USBReadPortW (PciIo, CmdAddrOffset, Data);
}

EFI_STATUS
WriteUHCStatusReg (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  StatusAddrOffset,
  IN UINT16                  UsbSts
  )
/*++

Routine Description:

  Write UHCI Staus Register

Arguments:

  PciIo            - EFI_PCI_IO_PROTOCOL
  StatusAddrOffset - Status address offset
  UsbSts           - Data to write

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Write to UHC's Status Register
  //
  return USBWritePortW (PciIo, StatusAddrOffset, UsbSts);
}

EFI_STATUS
ReadUHCStatusReg (
  IN     EFI_PCI_IO_PROTOCOL     *PciIo,
  IN     UINT32                  StatusAddrOffset,
  IN OUT UINT16                  *Data
  )
/*++

Routine Description:

  Read UHCI Staus Register

Arguments:

  PciIo            - EFI_PCI_IO_PROTOCOL
  StatusAddrOffset - Status address offset
  UsbSts           - Data to return

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Read from UHC's Status Register
  //
  return USBReadPortW (PciIo, StatusAddrOffset, Data);
}


EFI_STATUS
ClearStatusReg (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  StatusAddrOffset
  )
/*++

Routine Description:

  Clear the content of UHC's Status Register

Arguments:

  PciIo             - EFI_PCI_IO_PROTOCOL
  StatusAddrOffset  - Status address offset
  
Returns:

  EFI_SUCCESS

--*/
{
 
  return WriteUHCStatusReg (PciIo, StatusAddrOffset, 0x003F);
}

EFI_STATUS
ReadUHCFrameNumberReg (
  IN       EFI_PCI_IO_PROTOCOL     *PciIo,
  IN       UINT32                  FrameNumAddrOffset,
  IN OUT   UINT16                  *Data
  )
/*++

Routine Description:

  Read from UHC's Frame Number Register

Arguments:

  PciIo              - EFI_PCI_IO_PROTOCOL
  FrameNumAddrOffset - Frame number register offset
  Data               - Data to return 
Returns:

  EFI_SUCCESS

--*/
{
  
  return USBReadPortW (PciIo, FrameNumAddrOffset, Data);
}

EFI_STATUS
WriteUHCFrameListBaseReg (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  FlBaseAddrOffset,
  IN UINT32                  UsbFrameListBaseAddr
  )
/*++

Routine Description:

  Write to UHC's Frame List Base Register

Arguments:

  PciIo                - EFI_PCI_IO_PROTOCOL
  FlBaseAddrOffset     - Frame Base address register
  UsbFrameListBaseAddr - Address to write

Returns:

  EFI_SUCCESS

--*/
{
  
  return USBWritePortDW (PciIo, FlBaseAddrOffset, UsbFrameListBaseAddr);
}

EFI_STATUS
ReadRootPortReg (
  IN     EFI_PCI_IO_PROTOCOL     *PciIo,
  IN     UINT32                  PortAddrOffset,
  IN OUT UINT16                  *Data
  )
/*++

Routine Description:

  Read from UHC's Root Port Register

Arguments:

  PciIo           - EFI_PCI_IO_PROTOCOL
  PortAddrOffset  - Port Addrress Offset,
  Data            - Data to return
Returns:

  EFI_SUCCESS

--*/
{
 
  return USBReadPortW (PciIo, PortAddrOffset, Data);
}

EFI_STATUS
WriteRootPortReg (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  PortAddrOffset,
  IN UINT16                  ControlBits
  )
/*++

Routine Description:

   Write to UHC's Root Port Register

Arguments:

  PciIo           - EFI_PCI_IO_PROTOCOL
  PortAddrOffset  - Port Addrress Offset,
  ControlBits     - Data to write
Returns:

  EFI_SUCCESS

--*/
{
 
  return USBWritePortW (PciIo, PortAddrOffset, ControlBits);
}



EFI_STATUS
WaitForUHCHalt (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  StatusRegAddr,
  IN UINTN                   Timeout
  )
/*++

Routine Description:

  Wait until UHCI halt or timeout

Arguments:

  PciIo         - EFI_PCI_IO_PROTOCOL
  StatusRegAddr - Status Register Address
  Timeout       - Time out value in us

Returns:

  EFI_DEVICE_ERROR - Unable to read the status register
  EFI_TIMEOUT      - Time out
  EFI_SUCCESS      - Success

--*/
{
  UINTN       Delay;
  EFI_STATUS  Status;
  UINT16      HcStatus;

  //
  // Timeout is in us unit
  //
  Delay = (Timeout / 50) + 1;
  do {
    Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    if ((HcStatus & USBSTS_HCH) == USBSTS_HCH) {
      break;
    }
    //
    // Stall for 50 us
    //
    gBS->Stall (50);

  } while (Delay--);

  if (Delay == 0) {
    return EFI_TIMEOUT;
  }

  return EFI_SUCCESS;
}

BOOLEAN
IsStatusOK (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  StatusRegAddr
  )
/*++

Routine Description:

  Judge whether the host controller operates well

Arguments:

  PciIo         - EFI_PCI_IO_PROTOCOL
  StatusRegAddr - Status register address

Returns:

   TRUE  -  Status is good
   FALSE -  Status is bad

--*/
{
  EFI_STATUS  Status;
  UINT16      HcStatus;
  //
  // Detect whether the interrupt is caused by fatal error.
  // see "UHCI Design Guid".
  //
  Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  if (HcStatus & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) {
    return FALSE;
  } else {
    return TRUE;
  }

}


BOOLEAN 
IsHostSysOrProcessErr (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  StatusRegAddr
  )
/*++

Routine Description:

  Judge the status is HostSys,ProcessErr error or good

Arguments:

  PciIo         - EFI_PCI_IO_PROTOCOL
  StatusRegAddr - Status register address

Returns:

   TRUE  -  Status is good
   FALSE -  Status is bad

--*/
{
  EFI_STATUS  Status;
  UINT16      HcStatus;
  //
  // Detect whether the interrupt is caused by serious error.
  // see "UHCI Design Guid".
  //
  Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  if (HcStatus & (USBSTS_HSE | USBSTS_HCPE)) {
    return TRUE;
  } else {
    return FALSE;
  }
}


UINT16
GetCurrentFrameNumber (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  FrameNumAddrOffset
  )
/*++

Routine Description:

  Get Current Frame Number

Arguments:

  PciIo               - EFI_PCI_IO_PROTOCOL
  FrameNumAddrOffset  - FrameNum register AddrOffset

Returns:

  Frame number 

--*/
{
  //
  // Gets value in the USB frame number register.
  //
  UINT16  FrameNumber;

  ReadUHCFrameNumberReg (PciIo, FrameNumAddrOffset, &FrameNumber);

  return (UINT16) (FrameNumber & 0x03FF);
}

EFI_STATUS
SetFrameListBaseAddress (
  IN EFI_PCI_IO_PROTOCOL     *PciIo,
  IN UINT32                  FlBaseAddrReg,
  IN UINT32                  Addr
  )
/*++

Routine Description:

  Set FrameListBase Address

Arguments:

  PciIo         - EFI_PCI_IO_PROTOCOL
  FlBaseAddrReg - FrameListBase register
  Addr          - Address to set

Returns:

  EFI_SUCCESS

--*/
{
  //
  // Sets value in the USB Frame List Base Address register.
  //
  return WriteUHCFrameListBaseReg (PciIo, FlBaseAddrReg, (UINT32) (Addr & 0xFFFFF000));
}

VOID
EnableMaxPacketSize (
  IN USB_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Enable Max Packet Size

Arguments:

  HcDev - USB_HC_DEV

Returns:

  VOID

--*/
{
  UINT16      CommandContent;
  EFI_STATUS  Status;

  Status = ReadUHCCommandReg (
             HcDev->PciIo,
             (UINT32) (USBCMD),
             &CommandContent
             );

  if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {
    CommandContent |= USBCMD_MAXP;
    WriteUHCCommandReg (
      HcDev->PciIo,
      (UINT32) (USBCMD),
      CommandContent

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?