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 + -
显示快捷键?