PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
which is used to enable recovery function from USB Drivers.\r
\r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
- \r
+Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
of the BSD License which accompanies this distribution. The\r
\r
/**\r
Read Ehc Operation register.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Offset The operation register offset.\r
\r
)\r
{\r
UINT32 Data;\r
- \r
+\r
ASSERT (Ehc->CapLen != 0);\r
\r
Data = MmioRead32 (Ehc->UsbHostControllerBaseAddress + Ehc->CapLen + Offset);\r
- \r
+\r
return Data;\r
}\r
\r
/**\r
Write the data to the EHCI operation register.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Offset EHCI operation register offset.\r
@param Data The data to write.\r
\r
/**\r
Set one bit of the operational register while keeping other bits.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Offset The offset of the operational register.\r
@param Bit The bit mask of the register to set.\r
\r
/**\r
Clear one bit of the operational register while keeping other bits.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Offset The offset of the operational register.\r
@param Bit The bit mask of the register to clear.\r
}\r
\r
/**\r
- Wait the operation register's bit as specified by Bit \r
+ Wait the operation register's bit as specified by Bit\r
to become set (or clear).\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Offset The offset of the operational register.\r
@param Bit The bit mask of the register to wait for.\r
\r
/**\r
Read EHCI capability register.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Offset Capability register address.\r
\r
)\r
{\r
UINT32 Data;\r
- \r
+\r
Data = MmioRead32(Ehc->UsbHostControllerBaseAddress + Offset);\r
- \r
+\r
return Data;\r
}\r
\r
/**\r
Set door bell and wait it to be ACKed by host controller.\r
This function is used to synchronize with the hardware.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Timeout The time to wait before abort (in millisecond, ms).\r
\r
}\r
\r
/**\r
- Clear all the interrutp status bits, these bits \r
+ Clear all the interrutp status bits, these bits\r
are Write-Clean.\r
- \r
+\r
@param Ehc The EHCI device.\r
\r
**/\r
}\r
\r
/**\r
- Enable the periodic schedule then wait EHC to \r
+ Enable the periodic schedule then wait EHC to\r
actually enable it.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Timeout The time to wait before abort (in millisecond, ms).\r
\r
\r
/**\r
Enable asynchrounous schedule.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Timeout Time to wait before abort.\r
\r
\r
/**\r
Check whether Ehc is halted.\r
- \r
+\r
@param Ehc The EHCI device.\r
\r
@retval TRUE The controller is halted.\r
\r
/**\r
Check whether system error occurred.\r
- \r
+\r
@param Ehc The EHCI device.\r
\r
@retval TRUE System error happened.\r
\r
/**\r
Reset the host controller.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Timeout Time to wait before abort (in millisecond, ms).\r
\r
\r
/**\r
Halt the host controller.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Timeout Time to wait before abort.\r
\r
\r
/**\r
Set the EHCI to run.\r
- \r
+\r
@param Ehc The EHCI device.\r
@param Timeout Time to wait before abort.\r
\r
}\r
\r
/**\r
- Initialize the HC hardware. \r
+ Power On All EHCI Ports.\r
+\r
+ @param Ehc The EHCI device.\r
+\r
+**/\r
+VOID\r
+EhcPowerOnAllPorts (\r
+ IN PEI_USB2_HC_DEV *Ehc\r
+ )\r
+{\r
+ UINT8 PortNumber;\r
+ UINT8 Index;\r
+ UINT32 RegVal;\r
+\r
+ PortNumber = (UINT8)(Ehc->HcStructParams & HCSP_NPORTS);\r
+ for (Index = 0; Index < PortNumber; Index++) {\r
+ //\r
+ // Do not clear port status bits on initialization. Otherwise devices will\r
+ // not enumerate properly at startup.\r
+ //\r
+ RegVal = EhcReadOpReg(Ehc, EHC_PORT_STAT_OFFSET + 4 * Index);\r
+ RegVal &= ~PORTSC_CHANGE_MASK;\r
+ RegVal |= PORTSC_POWER;\r
+ EhcWriteOpReg (Ehc, EHC_PORT_STAT_OFFSET + 4 * Index, RegVal);\r
+ }\r
+}\r
+\r
+/**\r
+ Initialize the HC hardware.\r
EHCI spec lists the five things to do to initialize the hardware.\r
1. Program CTRLDSSEGMENT.\r
2. Set USBINTR to enable interrupts.\r
3. Set periodic list base.\r
4. Set USBCMD, interrupt threshold, frame list size etc.\r
5. Write 1 to CONFIGFLAG to route all ports to EHCI.\r
- \r
+\r
@param Ehc The EHCI device.\r
\r
@retval EFI_SUCCESS The EHCI has come out of halt state.\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS TempPtr;\r
UINTN PageNumber;\r
- \r
+\r
ASSERT (EhcIsHalt (Ehc));\r
\r
//\r
if (Ehc->Urb == NULL) {\r
return Status;\r
}\r
- \r
+\r
+ EhcPowerOnAllPorts (Ehc);\r
+ MicroSecondDelay (EHC_ROOT_PORT_RECOVERY_STALL);\r
+\r
Status = EhcInitSched (Ehc);\r
\r
if (EFI_ERROR (Status)) {\r
\r
/**\r
Submits bulk transfer to a bulk endpoint of a USB device.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
@param DeviceAddress Target device address.\r
@param EndPointAddress Endpoint number and its direction in bit 7.\r
- @param DeviceSpeed Device speed, Low speed device doesn't support \r
+ @param DeviceSpeed Device speed, Low speed device doesn't support\r
bulk transfer.\r
- @param MaximumPacketLength Maximum packet size the endpoint is capable of \r
+ @param MaximumPacketLength Maximum packet size the endpoint is capable of\r
sending or receiving.\r
- @param Data Array of pointers to the buffers of data to transmit \r
+ @param Data Array of pointers to the buffers of data to transmit\r
from or receive into.\r
@param DataLength The lenght of the data buffer.\r
@param DataToggle On input, the initial data toggle for the transfer;\r
- On output, it is updated to to next data toggle to use of \r
+ On output, it is updated to to next data toggle to use of\r
the subsequent bulk transfer.\r
@param TimeOut Indicates the maximum time, in millisecond, which the\r
transfer is allowed to complete.\r
- @param Translator A pointr to the transaction translator data. \r
+ If Timeout is 0, then the caller must wait for the function\r
+ to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.\r
+ @param Translator A pointr to the transaction translator data.\r
@param TransferResult A pointer to the detailed result information of the\r
bulk transfer.\r
\r
//\r
// Validate the parameters\r
//\r
- if ((DataLength == NULL) || (*DataLength == 0) || \r
+ if ((DataLength == NULL) || (*DataLength == 0) ||\r
(Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
Retrieves the number of root hub ports.\r
\r
@param[in] PeiServices The pointer to the PEI Services Table.\r
- @param[in] This The pointer to this instance of the \r
+ @param[in] This The pointer to this instance of the\r
PEI_USB2_HOST_CONTROLLER_PPI.\r
- @param[out] PortNumber The pointer to the number of the root hub ports. \r
- \r
+ @param[out] PortNumber The pointer to the number of the root hub ports.\r
+\r
@retval EFI_SUCCESS The port number was retrieved successfully.\r
@retval EFI_INVALID_PARAMETER PortNumber is NULL.\r
\r
\r
PEI_USB2_HC_DEV *EhcDev;\r
EhcDev = PEI_RECOVERY_USB_EHC_DEV_FROM_EHCI_THIS (This);\r
- \r
+\r
if (PortNumber == NULL) {\r
return EFI_INVALID_PARAMETER;\r
- } \r
- \r
+ }\r
+\r
*PortNumber = (UINT8)(EhcDev->HcStructParams & HCSP_NPORTS);\r
return EFI_SUCCESS;\r
- \r
+\r
}\r
\r
/**\r
Clears a feature for the specified root hub port.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
@param PortNumber Specifies the root hub port whose feature\r
@param PortFeature Indicates the feature selector associated with the\r
feature clear request.\r
\r
- @retval EFI_SUCCESS The feature specified by PortFeature was cleared \r
+ @retval EFI_SUCCESS The feature specified by PortFeature was cleared\r
for the USB root hub port specified by PortNumber.\r
@retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
\r
\r
/**\r
Sets a feature for the specified root hub port.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES\r
@param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI\r
@param PortNumber Root hub port to set.\r
break;\r
}\r
}\r
- \r
+\r
//\r
// Set one to PortReset bit must also set zero to PortEnable bit\r
//\r
\r
/**\r
Retrieves the current status of a USB root hub port.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
- @param PortNumber The root hub port to retrieve the state from. \r
+ @param PortNumber The root hub port to retrieve the state from.\r
@param PortStatus Variable to receive the port state.\r
\r
@retval EFI_SUCCESS The status of the USB root hub port specified.\r
\r
//\r
// Identify device speed. If in K state, it is low speed.\r
- // If the port is enabled after reset, the device is of \r
+ // If the port is enabled after reset, the device is of\r
// high speed. The USB bus driver should retrieve the actual\r
- // port speed after reset. \r
+ // port speed after reset.\r
//\r
if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) {\r
PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
} else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) {\r
PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;\r
}\r
- \r
+\r
//\r
// Convert the EHCI port/port change state to UEFI status\r
//\r
\r
/**\r
Submits control transfer to a target USB device.\r
- \r
+\r
@param PeiServices The pointer of EFI_PEI_SERVICES.\r
@param This The pointer of PEI_USB2_HOST_CONTROLLER_PPI.\r
@param DeviceAddress The target device address.\r
@param DeviceSpeed Target device speed.\r
- @param MaximumPacketLength Maximum packet size the default control transfer \r
+ @param MaximumPacketLength Maximum packet size the default control transfer\r
endpoint is capable of sending or receiving.\r
@param Request USB device request to send.\r
@param TransferDirection Specifies the data direction for the data stage.\r
@param Data Data buffer to be transmitted or received from USB device.\r
@param DataLength The size (in bytes) of the data buffer.\r
@param TimeOut Indicates the maximum timeout, in millisecond.\r
+ If Timeout is 0, then the caller must wait for the function\r
+ to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.\r
@param Translator Transaction translator to be used by this device.\r
@param TransferResult Return the result of this control transfer.\r
\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if ((TransferDirection == EfiUsbNoData) && \r
+ if ((TransferDirection == EfiUsbNoData) &&\r
((Data != NULL) || (*DataLength != 0))) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if ((TransferDirection != EfiUsbNoData) && \r
+ if ((TransferDirection != EfiUsbNoData) &&\r
((Data == NULL) || (*DataLength == 0))) {\r
return EFI_INVALID_PARAMETER;\r
}\r
return Status;\r
}\r
\r
+/**\r
+ One notified function to stop the Host Controller at the end of PEI\r
+\r
+ @param[in] PeiServices Pointer to PEI Services Table.\r
+ @param[in] NotifyDescriptor Pointer to the descriptor for the Notification event that\r
+ caused this function to execute.\r
+ @param[in] Ppi Pointer to the PPI data associated with this function.\r
+\r
+ @retval EFI_SUCCESS The function completes successfully\r
+ @retval others\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EhcEndOfPei (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{\r
+ PEI_USB2_HC_DEV *Ehc;\r
+\r
+ Ehc = PEI_RECOVERY_USB_EHC_DEV_FROM_THIS_NOTIFY (NotifyDescriptor);\r
+\r
+ EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+\r
+ EhcFreeSched (Ehc);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
@param FileHandle Handle of the file being invoked.\r
@param PeiServices Describes the list of possible PEI Services.\r
if (EFI_ERROR (Status)) {\r
break;\r
}\r
- \r
+\r
//\r
// This PEIM is for UHC type controller.\r
//\r
\r
EhcDev->Signature = USB2_HC_DEV_SIGNATURE;\r
\r
+ IoMmuInit (&EhcDev->IoMmu);\r
+\r
EhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;\r
\r
\r
continue;\r
}\r
\r
+ EhcDev->EndOfPeiNotifyList.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
+ EhcDev->EndOfPeiNotifyList.Guid = &gEfiEndOfPeiSignalPpiGuid;\r
+ EhcDev->EndOfPeiNotifyList.Notify = EhcEndOfPei;\r
+\r
+ PeiServicesNotifyPpi (&EhcDev->EndOfPeiNotifyList);\r
+\r
Index++;\r
}\r
\r
**/\r
EFI_STATUS\r
InitializeUsbHC (\r
- IN PEI_USB2_HC_DEV *EhcDev \r
+ IN PEI_USB2_HC_DEV *EhcDev\r
)\r
{\r
EFI_STATUS Status;\r
\r
- \r
+\r
EhcResetHC (EhcDev, EHC_RESET_TIMEOUT);\r
\r
Status = EhcInitHC (EhcDev);\r
\r
if (EFI_ERROR (Status)) {\r
- return EFI_ABORTED; \r
+ return EFI_ABORTED;\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\r