uhchlp.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 3,348 行 · 第 1/5 页
C
3,348 行
);
}
return ;
}
EFI_STATUS
CreateFrameList (
IN USB_HC_DEV *HcDev,
IN UINT32 FlBaseAddrReg
)
/*++
Routine Description:
CreateFrameList
Arguments:
HcDev - USB_HC_DEV
FlBaseAddrReg - Frame List register
Returns:
EFI_OUT_OF_RESOURCES - Can't allocate memory resources
EFI_UNSUPPORTED - Map memory fail
EFI_SUCCESS - Success
--*/
{
EFI_STATUS Status;
VOID *CommonBuffer;
EFI_PHYSICAL_ADDRESS MappedAddress;
VOID *Mapping;
UINTN BufferSizeInPages;
UINTN BufferSizeInBytes;
//
// The Frame List is a common buffer that will be
// accessed by both the cpu and the usb bus master
// at the same time.
// The Frame List ocupies 4K bytes,
// and must be aligned on 4-Kbyte boundaries.
//
BufferSizeInBytes = 4096;
BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);
Status = HcDev->PciIo->AllocateBuffer (
HcDev->PciIo,
AllocateAnyPages,
EfiBootServicesData,
BufferSizeInPages,
&CommonBuffer,
0
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = HcDev->PciIo->Map (
HcDev->PciIo,
EfiPciIoOperationBusMasterCommonBuffer,
CommonBuffer,
&BufferSizeInBytes,
&MappedAddress,
&Mapping
);
if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {
HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);
return EFI_UNSUPPORTED;
}
HcDev->FrameListEntry = (FRAMELIST_ENTRY *) ((UINTN) MappedAddress);
HcDev->FrameListMapping = Mapping;
InitFrameList (HcDev);
//
// Tell the Host Controller where the Frame List lies,
// by set the Frame List Base Address Register.
//
SetFrameListBaseAddress (
HcDev->PciIo,
FlBaseAddrReg,
(UINT32) ((UINTN) HcDev->FrameListEntry)
);
return EFI_SUCCESS;
}
EFI_STATUS
FreeFrameListEntry (
IN USB_HC_DEV *HcDev
)
/*++
Routine Description:
Free FrameList buffer
Arguments:
HcDev - USB_HC_DEV
Returns:
EFI_SUCCESS - success
--*/
{
//
// Unmap the common buffer for framelist entry,
// and free the common buffer.
// Uhci's frame list occupy 4k memory.
//
HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->FrameListMapping);
HcDev->PciIo->FreeBuffer (
HcDev->PciIo,
EFI_SIZE_TO_PAGES (4096),
(VOID *) (HcDev->FrameListEntry)
);
return EFI_SUCCESS;
}
VOID
InitFrameList (
IN USB_HC_DEV *HcDev
)
/*++
Routine Description:
Initialize FrameList
Arguments:
HcDev - USB_HC_DEV
Returns:
VOID
--*/
{
FRAMELIST_ENTRY *FrameListPtr;
UINTN Index;
//
// Validate each Frame List Entry
//
FrameListPtr = HcDev->FrameListEntry;
for (Index = 0; Index < 1024; Index++) {
FrameListPtr->FrameListPtrTerminate = 1;
FrameListPtr->FrameListPtr = 0;
FrameListPtr->FrameListPtrQSelect = 0;
FrameListPtr->FrameListRsvd = 0;
FrameListPtr++;
}
}
//
// //////////////////////////////////////////////////////////////
//
// QH TD related Helper Functions
//
////////////////////////////////////////////////////////////////
//
// functions for QH
//
EFI_STATUS
AllocateQHStruct (
IN USB_HC_DEV *HcDev,
OUT QH_STRUCT **ppQHStruct
)
/*++
Routine Description:
Allocate QH Struct
Arguments:
HcDev - USB_HC_DEV
ppQHStruct - QH_STRUCT content to return
Returns:
EFI_SUCCESS
--*/
{
*ppQHStruct = NULL;
//
// QH must align on 16 bytes alignment,
// since the memory allocated by UhciAllocatePool ()
// is aligned on 32 bytes, it is no need to adjust
// the allocated memory returned.
//
return UhciAllocatePool (HcDev, (UINT8 **) ppQHStruct, sizeof (QH_STRUCT));
}
EFI_STATUS
CreateQH (
IN USB_HC_DEV *HcDev,
OUT QH_STRUCT **pptrQH
)
/*++
Routine Description:
CreateQH
Arguments:
HcDev - USB_HC_DEV
ppQHStruct - QH_STRUCT content to return
Returns:
EFI_SUCCESS - Success
EFI_OUT_OF_RESOURCES - Can't allocate memory
--*/
{
EFI_STATUS Status;
//
// allocate align memory for QH_STRUCT
//
Status = AllocateQHStruct (HcDev, pptrQH);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
//
// init each field of the QH_STRUCT
//
//
// Make QH ready
//
SetQHHorizontalValidorInvalid (*pptrQH, FALSE);
SetQHVerticalValidorInvalid (*pptrQH, FALSE);
return EFI_SUCCESS;
}
VOID
SetQHHorizontalLinkPtr (
IN QH_STRUCT *PtrQH,
IN VOID *ptrNext
)
/*++
Routine Description:
Set QH Horizontal Link Pointer
Arguments:
PtrQH - QH_STRUCT
ptrNext - Data to write
Returns:
VOID
--*/
{
//
// Since the QH_STRUCT is aligned on 16-byte boundaries,
// Only the highest 28bit of the address is valid
// (take 32bit address as an example).
//
PtrQH->QH.QHHorizontalPtr = (UINT32) ((UINTN) ptrNext >> 4);
}
VOID *
GetQHHorizontalLinkPtr (
IN QH_STRUCT *PtrQH
)
/*++
Routine Description:
Get QH Horizontal Link Pointer
Arguments:
PtrQH - QH_STRUCT
Returns:
Data to return
--*/
{
//
// Restore the 28bit address to 32bit address
// (take 32bit address as an example)
//
return (VOID *) ((UINTN) (PtrQH->QH.QHHorizontalPtr << 4));
}
VOID
SetQHHorizontalQHorTDSelect (
IN QH_STRUCT *PtrQH,
IN BOOLEAN bQH
)
/*++
Routine Description:
Set QH Horizontal QH or TD
Arguments:
PtrQH - QH_STRUCT
bQH - TRUE is QH FALSE is TD
Returns:
VOID
--*/
{
//
// if QH is connected, the specified bit is set,
// if TD is connected, the specified bit is cleared.
//
PtrQH->QH.QHHorizontalQSelect = bQH ? 1 : 0;
}
VOID
SetQHHorizontalValidorInvalid (
IN QH_STRUCT *PtrQH,
IN BOOLEAN bValid
)
/*++
Routine Description:
Set QH Horizontal Valid or Invalid
Arguments:
PtrQH - QH_STRUCT
bValid - TRUE is Valid FALSE is Invalid
Returns:
VOID
--*/
{
//
// Valid means the horizontal link pointer is valid,
// else, it's invalid.
//
PtrQH->QH.QHHorizontalTerminate = bValid ? 0 : 1;
}
VOID
SetQHVerticalLinkPtr (
IN QH_STRUCT *PtrQH,
IN VOID *ptrNext
)
/*++
Routine Description:
Set QH Vertical Link Pointer
Arguments:
PtrQH - QH_STRUCT
ptrNext - Data to write
Returns:
VOID
--*/
{
//
// Since the QH_STRUCT is aligned on 16-byte boundaries,
// Only the highest 28bit of the address is valid
// (take 32bit address as an example).
//
PtrQH->QH.QHVerticalPtr = (UINT32) ((UINTN) ptrNext >> 4);
}
VOID *
GetQHVerticalLinkPtr (
IN QH_STRUCT *PtrQH
)
/*++
Routine Description:
Get QH Vertical Link Pointer
Arguments:
PtrQH - QH_STRUCT
Returns:
Data to return
--*/
{
//
// Restore the 28bit address to 32bit address
// (take 32bit address as an example)
//
return (VOID *) ((UINTN) (PtrQH->QH.QHVerticalPtr << 4));
}
VOID
SetQHVerticalQHorTDSelect (
IN QH_STRUCT *PtrQH,
IN BOOLEAN bQH
)
/*++
Routine Description:
Set QH Vertical QH or TD
Arguments:
PtrQH - QH_STRUCT
bQH - TRUE is QH FALSE is TD
Returns:
VOID
--*/
{
//
// Set the specified bit if the Vertical Link Pointer pointing to a QH,
// Clear the specified bit if the Vertical Link Pointer pointing to a TD.
//
PtrQH->QH.QHVerticalQSelect = bQH ? 1 : 0;
}
BOOLEAN
IsQHHorizontalQHSelect (
IN QH_STRUCT *PtrQH
)
/*++
Routine Description:
Is QH Horizontal QH Select
Arguments:
PtrQH - QH_STRUCT
Returns:
TRUE - QH
FALSE - TD
--*/
{
//
// Retrieve the information about whether the Horizontal Link Pointer
// pointing to a QH or TD.
//
return (BOOLEAN) (PtrQH->QH.QHHorizontalQSelect ? TRUE : FALSE);
}
VOID
SetQHVerticalValidorInvalid (
IN QH_STRUCT *PtrQH,
IN BOOLEAN IsValid
)
/*++
Routine Description:
Set QH Vertical Valid or Invalid
Arguments:
PtrQH - QH_STRUCT
IsValid - TRUE is valid FALSE is invalid
Returns:
VOID
--*/
{
//
// If TRUE, indicates the Vertical Link Pointer field is valid,
// else, the field is invalid.
//
PtrQH->QH.QHVerticalTerminate = IsValid ? 0 : 1;
}
BOOLEAN
GetQHVerticalValidorInvalid (
IN QH_STRUCT *PtrQH
)
/*++
Routine Description:
Get QH Vertical Valid or Invalid
Arguments:
PtrQH - QH_STRUCT
Returns:
TRUE - Valid
FALSE - Invalid
--*/
{
//
// If TRUE, indicates the Vertical Link Pointer field is valid,
// else, the field is invalid.
//
return (BOOLEAN) (!(PtrQH->QH.QHVerticalTerminate));
}
BOOLEAN
GetQHHorizontalValidorInvalid (
IN QH_STRUCT *PtrQH
)
/*++
Routine Description:
Get QH Horizontal Valid or Invalid
Arguments:
PtrQH - QH_STRUCT
Returns:
TRUE - Valid
FALSE - Invalid
--*/
{
//
// If TRUE, meaning the Horizontal Link Pointer field is valid,
// else, the field is invalid.
//
return (BOOLEAN) (!(PtrQH->QH.QHHorizontalTerminate));
}
//
// functions for TD
//
EFI_STATUS
AllocateTDStruct (
IN USB_HC_DEV *HcDev,
OUT TD_STRUCT **ppTDStruct
)
/*++
Routine Description:
Allocate TD Struct
Arguments:
HcDev - USB_HC_DEV
ppTDStruct - place to store TD_STRUCT pointer
Returns:
EFI_SUCCESS
--*/
{
*ppTDStruct = NULL;
//
// TD must align on 16 bytes alignment,
// since the memory allocated by UhciAllocatePool ()
// is aligned on 32 bytes, it is no need to adjust
// the allocated memory returned.
//
return UhciAllocatePool (
HcDev,
(UINT8 **) ppTDStruct,
sizeof (TD_STRUCT)
);
}
EFI_STATUS
CreateTD (
IN USB_HC_DEV *HcDev,
OUT TD_STRUCT **pptrTD
)
/*++
Routine Description:
Create TD
Arguments:
HcDev - USB_HC_DEV
pptrTD - TD_STRUCT pointer to store
Returns:
EFI_OUT_OF_RESOURCES - Can't allocate resources
EFI_SUCCESS - Success
--*/
{
EFI_STATUS Status;
//
// create memory for TD_STRUCT, and align the memory.
//
Status = AllocateTDStruct (HcDev, pptrTD);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
//
// Make TD ready.
//
SetTDLinkPtrValidorInvalid (*pptrTD, FALSE);
return EFI_SUCCESS;
}
EFI_STATUS
GenSetupStageTD (
IN USB_HC_DEV *HcDev,
IN UINT8 DevAddr,
IN UINT8 Endpoint,
IN BOOLEAN bSlow,
IN UINT8 *pDevReq,
IN UINT8 RequestLen,
OUT TD_STRUCT **ppTD
)
/*++
Routine Description:
Generate Setup Stage TD
Arguments:
HcDev - USB_HC_DEV
DevAddr - Device address
Endpoint - Endpoint number
bSlow - Full speed or low speed
pDevReq - Device request
RequestLen - Request length
ppTD - TD_STRUCT to return
Returns:
EFI_OUT_OF_RESOURCES - Can't allocate memory
EFI_SUCCESS - Success
--*/
{
EFI_STATUS Status;
TD_STRUCT *pTDStruct;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?