⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uhchlp.c

📁 Next BIOS Source code : Extensible Firmware Interface
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.


Module Name:

    UhcHlp.c
    
Abstract: 
    

Revision History
--*/

#include "Efi.h"
#include "EfiDriverLib.h"

#include "uhci.h"

//
// UHCI IO Space Address Register Register locates at 
// offset 20 ~ 23h of PCI Configuration Space (UHCI spec, Revision 1.1),
// so, its BAR Index is 4.
//
#define USB_BAR_INDEX       4

UINT8
USBReadPortB (
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                PortOffset
  )
{
  UINT8         Data;
  
  //
  // Perform 8bit Read in PCI IO Space 
  //
  PciIo->Io.Read (PciIo,
                 EfiPciIoWidthUint8,
                 USB_BAR_INDEX,
                 (UINT64)PortOffset,
                 1,
                 &Data
                 );
  return Data;                 
}   

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


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

VOID
USBWritePortB (
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                PortOffset, 
  IN  UINT8                 Data
  )
{
  //
  // Perform 8bit Write in PCI IO Space 
  //
  PciIo->Io.Write (PciIo,
                  EfiPciIoWidthUint8,
                  USB_BAR_INDEX,
                  (UINT64)PortOffset,
                  1,
                  &Data
                  );
}   

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

VOID
USBWritePortDW (
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                PortOffset, 
  IN  UINT32                Data
  )
{
  //
  // Perform 32bit Write in PCI IO Space 
  //
  PciIo->Io.Write (PciIo,
                  EfiPciIoWidthUint32,
                  USB_BAR_INDEX,
                  (UINT64)PortOffset,
                  1,
                  &Data
                  );
}


//
//  USB register-base helper functions
//

VOID
WriteUHCCommandReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                CmdAddrOffset,
  IN  UINT16                UsbCmd
  )
{
  //
  // Write to UHC's Command Register
  //
  USBWritePortW (PciIo,CmdAddrOffset, UsbCmd);
  return;
}


UINT16 
ReadUHCCommandReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                 CmdAddrOffset
  )
{
  //
  // Read from UHC's Command Register
  //
  return USBReadPortW (PciIo,CmdAddrOffset);
}

VOID
WriteUHCStatusReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusAddrOffset,
  IN  UINT16                UsbSts
)
{
  //
  // Write to UHC's Status Register
  //
  USBWritePortW (PciIo,StatusAddrOffset, UsbSts);
  return;
}

UINT16 
ReadUHCStatusReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusAddrOffset
)
{
  //
  // Read from UHC's Status Register
  //
  return USBReadPortW (PciIo,StatusAddrOffset);
}


VOID
ClearStatusReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusAddrOffset
)
{
  UINT16 UsbSts;
  
  //
  // Clear the content of UHC's Status Register
  //
  UsbSts = 0x003F;
  WriteUHCStatusReg (PciIo,StatusAddrOffset,UsbSts);
}


VOID  
WriteUHCIntReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                InterruptAddrOffset,
  IN  UINT16                UsbInt
)
{
  //
  // Write to UHC's Interrupt Enable Register
  //
  USBWritePortW (PciIo,InterruptAddrOffset, UsbInt);
  return;
}


UINT16 
ReadUHCIntReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                InterruptAddrOffset
)
{
  //
  // Read from UHC's Interrupt Enable Register
  //
  return USBReadPortW (PciIo,InterruptAddrOffset);
}


VOID  
WriteUHCFrameNumberReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                FrameNumAddrOffset,
  IN  UINT16                UsbFrameNum
)
{
  //
  // Write to UHC's Frame Number Register
  //
  USBWritePortW (PciIo,FrameNumAddrOffset, UsbFrameNum);
  return;
}


UINT16 
ReadUHCFrameNumberReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                FrameNumAddrOffset
)
{
  //
  // Read from UHC's Frame Number Register
  //
  return USBReadPortW (PciIo,FrameNumAddrOffset);
}


VOID  
WriteUHCFrameListBaseReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                FlBaseAddrOffset,
  IN  UINT32                UsbFrameListBaseAddr
  )
{
  //
  // Write to UHC's Frame List Base Register
  //
  USBWritePortDW (PciIo,FlBaseAddrOffset, UsbFrameListBaseAddr);  
  return;
}


UINT32 
ReadUHCFrameListBaseReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                FlBaseAddrOffset
  )
{
  UINT32 UsbFrameListBaseAddr;
  
  //
  // Read from UHC's Frame List Register, and return the valid value.
  //
  UsbFrameListBaseAddr = USBReadPortDW (PciIo,FlBaseAddrOffset);
  
  UsbFrameListBaseAddr  = UsbFrameListBaseAddr & 0xFFFFF000 ;
  
  return UsbFrameListBaseAddr;
}


UINT16 
ReadRootPortReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                PortAddrOffset
  )
{
  //
  // Read from UHC's Root Port Register
  //
  return USBReadPortW (PciIo,PortAddrOffset);
}


VOID 
WriteRootPortReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                PortAddrOffset,
  IN  UINT16                ControlBits
  )
{
  //
  // Write to UHC's Root Port Register
  //
  USBWritePortW (PciIo,PortAddrOffset,ControlBits);
  return ;
}



EFI_STATUS
WaitForUHCHalt(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN UINT32                 StatusRegAddr,
  IN UINTN                  Timeout
  )
{
  UINTN               Delay; 
  UINT16              Status ;
  
  //
  // Timeout is in us unit
  //
  Delay = (Timeout / 50) + 1;
  do {
    Status = ReadUHCStatusReg(PciIo,StatusRegAddr) ;
    if ( (Status & USBSTS_HCH) == USBSTS_HCH) {
      break;
    }

    gBS->Stall(50);   // Stall for 50 us

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

  return EFI_SUCCESS;
}


BOOLEAN
DetectUHCInterrupt(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusRegAddr
  )
{
  UINT16      Status ;
  
  //
  // Scan whether there is any interrupt flag set in Status Register. 
  //
  Status = ReadUHCStatusReg (PciIo,StatusRegAddr) ;

  if (Status & 0x003B) {   // bit0~bit1,bit3~bit5
    return TRUE;
  } else {
    return FALSE;
  }
}

BOOLEAN 
IsUSBInterrupt(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusRegAddr
)
{
  UINT16      Status ;
  
  //
  // Detect whether the interrupt is caused by IOC or Short Packet Detected.
  // see "UHCI Design Guid".
  //
  Status = ReadUHCStatusReg (PciIo,StatusRegAddr) ;
  
  if (Status & USBSTS_USBINT) {
    return TRUE;
  } else {
    return FALSE;
  }

}

BOOLEAN 
IsUSBErrInterrupt(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusRegAddr
  )
{
  UINT16      Status ;
  
  //
  // Detect whether the interrupt is caused by any error condition.
  // see "UHCI Design Guid".
  //
  Status = ReadUHCStatusReg (PciIo,StatusRegAddr) ;
  
  if (Status & USBSTS_ERROR) {
    return TRUE;
  } else {
    return FALSE;
  }
}

BOOLEAN 
IsHostSysErr(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusRegAddr
  )
{
  UINT16      Status ;
  
  //
  // Detect whether the interrupt is caused by serious error.
  // see "UHCI Design Guid".
  //
  Status = ReadUHCStatusReg (PciIo,StatusRegAddr) ;
  
  if (Status & USBSTS_HSE) {
    return TRUE;
  } else {
    return FALSE;
  }
}

BOOLEAN 
IsHCProcessErr(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusRegAddr
  )
{
  UINT16      Status ;
  
  //
  // Detect whether the interrupt is caused by fatal error.
  // see "UHCI Design Guid".
  //
  Status = ReadUHCStatusReg (PciIo,StatusRegAddr) ;
  
  if (Status & USBSTS_HCPE) {
    return TRUE;
  } else {
    return FALSE;
  }
}

BOOLEAN 
IsHCHalted(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                StatusRegAddr
  )
{
  UINT16      Status ;
  
  //
  // Detect whether the the Host Controller is halted.
  //
  Status = ReadUHCStatusReg (PciIo,StatusRegAddr) ;
    
  if (Status & USBSTS_HCH) {
    return TRUE;
  } else {
    return FALSE;
  }
}


VOID
SetFrameNumberReg(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN  UINT32                FrameNumAddrOffset,
  IN  UINT16                Index
 )
{
  //
  // Modifies the USB frame number register. 
  // It is assumed that the HC schedule execution is stopped.
  //
  Index &= 0x03FF;
  WriteUHCFrameNumberReg (PciIo,FrameNumAddrOffset,Index);
}


UINT16 
GetCurrentFrameNumber(
  IN  EFI_PCI_IO_PROTOCOL   *PciIo,
  IN   UINT32               FrameNumAddrOffset
  )
{
  //
  // Gets value in the USB frame number register. 
  //
  return (UINT16)(ReadUHCFrameNumberReg (PciIo,FrameNumAddrOffset) & 0x03FF);
}

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

UINT32 
GetFrameListBaseAddress(
  EFI_PCI_IO_PROTOCOL   *PciIo,
  UINT32                    FLBAddr
)
{
  //
  // Gets value from the USB Frame List Base Address register. 
  //
  return ReadUHCFrameListBaseReg(PciIo,FLBAddr) & 0xFFFFF000;
}


VOID
EnableUhc (
  IN EFI_PCI_IO_PROTOCOL  *PciIo
  )
{
  UINT16  Command;
  
  //
  // Enable Bas master & IO access
  //
  Command = 0x05;
  PciIo->Pci.Write (
          PciIo,
          EfiPciIoWidthUint16,
          0x04,                 //command reg
          1,
          &Command
         );          

  return;
}

VOID
EnableMaxPacketSize (
  USB_HC_DEV          *HcDev
  )
{
  UINT16    CommandContent;
  
  CommandContent = ReadUHCCommandReg (
                     HcDev->PciIo,
                     (UINT32)(USBCMD)
                   );

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

⌨️ 快捷键说明

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