diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/UsbRecovery/UsbPeimSrc | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/UsbRecovery/UsbPeimSrc')
-rw-r--r-- | Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c | 889 | ||||
-rw-r--r-- | Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c | 334 | ||||
-rw-r--r-- | Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c | 1006 | ||||
-rw-r--r-- | Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif | 12 |
4 files changed, 2241 insertions, 0 deletions
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c new file mode 100644 index 0000000..a2a2246 --- /dev/null +++ b/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c @@ -0,0 +1,889 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2007, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// +// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/HubPeim.c 12 11/24/12 5:46a Ryanchou $ +// +// $Revision: 12 $ +// +// $Date: 11/24/12 5:46a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/HubPeim.c $ +// +// 12 11/24/12 5:46a Ryanchou +// [TAG] EIP103990 +// [Category] Improvement +// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24. +// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c, +// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h, +// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c, +// PeiUsbLib.h, UsbPeim.h +// +// 11 8/24/11 4:24a Roberthsu +// [TAG] EIP67320 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] USB recovery will fail when plug-in USB touch panel on +// Oaktrail platform +// [RootCause] Usbrecovery will exit when get portchanged.Touch panel +// port status is early than usbkey.So usbrecovery fail. +// [Solution] Add delay after hub set port power. +// [Files] HubPeim.c +// +// 10 1/18/11 12:54a Ryanchou +// [TAG] EIP47931 +// [Category] Improvement +// [Description] Added USB 3.0 hub support. +// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c, +// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h, +// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h +// +// 9 4/26/10 4:17p Krishnakumarg +// DebugRx causes the system to hang in Recovery mode EIP#34401 +// +// 8 4/06/10 3:31p Fasihm +// EIP#31987 - Added the generic USBRecovery Fix in the module. +// +// 7 3/17/09 5:03p Olegi +// Removed unnecessary CLEAR_FEATURE (Reset) and SET_FEATURE (Enable) in +// the hub enumeration routine. +// +// 6 7/18/08 5:05p Michaela +// 1 File-level debugging is now available +// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns +// the keypress so that conditional debugging can +// be dynamic (alphanumeric keys only) +// 3 Added more function headers. +// 4 Removed code that will never be used (I.e., Bala?). +// 5 Moved typedef, contants and extern declarations +// into header files. +// 6 Now all controller blocks are enabled for SB700 +// (EHCI controllers route to companion controller +// by default) +// 7 Removed unused constants and typedefs n OhciPei.h +// (also reorganized the file to make it more +// readable.) +// 8 Renamed many functions/variables according to +// coding standard. +// 9 Removed code initializing data structures for +// periodic lists, as this is not needed. +// 10 Removed the CONTROLLER_TYPE SDL token to +// allow UHCI and OHCI controllers to supported +// simultaneously. (modified MAKE files +// accordingly) +// +// 5 7/10/08 6:37p Michaela +// Updated to support OHCI controllers +// +// 4 8/17/07 4:14p Ambikas +// +// 3 4/16/07 12:54p Sivagarn +// - Updated as per coding standard review +// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file +// is included +// +// 2 3/28/07 3:38a Meenakshim +// +// 1 9/22/06 12:19p Sivagarn +// - Initial Checkin +// - Included Recovery code in Source +// +//***************************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: HubPeim.C +// +// Description: This file belongs to "Framework". +// This file is modified by AMI to include copyright message, +// appropriate header and integration code. +// This file contains generic routines needed for USB recovery +// PEIM +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +/*++ + This file contains 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. + --*/ + +/*++ + + 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: + + HubPeim.c + + Abstract: + + Usb Hub Request Support In PEI Phase + + Revision History + + --*/ +//NOT NEEDED FOR APTIO +//#include "Efi.h" +//#include "EfiDriverLib.h" +//#include "usb.h" + +#include "HubPeim.h" +#include "UsbPeim.h" +#include "PeiUsbLib.h" + +#include EFI_PPI_DEFINITION( Stall ) +static EFI_GUID gPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID; + +//NOT NEEDED FOR APTIO +//#include "usbbus.h" +//#include "usblib.h" +//#include "hub.h" + +extern VOID ZeroMem ( + IN VOID *Buffer, + IN UINTN Size ); + +typedef struct { + UINT32 HubPortStatus; + UINT32 EfiPortStatus; +} EFI_USB_PORT_STATUS_MAP; + +EFI_USB_PORT_STATUS_MAP HubPortStatusMap[] = { + // Port status bits + {HUB_PORT_CONNECTION, USB_PORT_STAT_CONNECTION}, + {HUB_PORT_ENABLE, USB_PORT_STAT_ENABLE}, + {HUB_PORT_SUSPEND, USB_PORT_STAT_SUSPEND}, + {HUB_PORT_OVER_CURRENT, USB_PORT_STAT_OVERCURRENT}, + {HUB_PORT_RESET, USB_PORT_STAT_RESET}, + {HUB_PORT_POWER, USB_PORT_STAT_POWER}, + {HUB_PORT_LOW_SPEED, USB_PORT_STAT_LOW_SPEED}, + {HUB_PORT_HIGH_SPEED, USB_PORT_STAT_HIGH_SPEED}, + // Port status change bits + {HUB_C_PORT_CONNECTION << 16, USB_PORT_STAT_C_CONNECTION << 16}, + {HUB_C_PORT_ENABLE << 16, USB_PORT_STAT_C_ENABLE << 16}, + {HUB_C_PORT_SUSPEND << 16, USB_PORT_STAT_C_SUSPEND << 16}, + {HUB_C_PORT_OVER_CURRENT << 16, USB_PORT_STAT_C_OVERCURRENT << 16}, + {HUB_C_PORT_RESET << 16, USB_PORT_STAT_C_RESET << 16} +}; + +EFI_USB_PORT_STATUS_MAP SsHubPortStatusMap[] = { + // Port status bits + {SS_HUB_PORT_CONNECTION, USB_PORT_STAT_CONNECTION | USB_PORT_STAT_SUPER_SPEED}, + {SS_HUB_PORT_ENABLE, USB_PORT_STAT_ENABLE}, + {SS_HUB_PORT_OVER_CURRENT, USB_PORT_STAT_OVERCURRENT}, + {SS_HUB_PORT_RESET, USB_PORT_STAT_RESET}, + {SS_HUB_PORT_POWER, USB_PORT_STAT_POWER}, + // Port status change bits + {SS_HUB_C_PORT_CONNECTION << 16, USB_PORT_STAT_C_CONNECTION << 16}, + {SS_HUB_C_PORT_ENABLE << 16, USB_PORT_STAT_C_ENABLE << 16}, + {SS_HUB_C_PORT_SUSPEND << 16, USB_PORT_STAT_C_SUSPEND << 16}, + {SS_HUB_C_PORT_OVER_CURRENT << 16, USB_PORT_STAT_C_OVERCURRENT << 16}, + {SS_HUB_C_PORT_RESET << 16, USB_PORT_STAT_C_RESET << 16} +}; + +//<AMI_PHDR_START> +//--------------------------------------------------------------------------- +// +// Procedure: PeiHubGetPortStatus +// +// Description: +// This function uses a device's PEI_USB_IO_PPI interface to execute a +// control transfer on the default control pipe to issue a Hub +// Class-specific request to obtain the port status and port status +// change bits. +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices +// -- PEI Sevices table pointer +// IN PEI_USB_IO_PPI *UsbIoPpi +// -- PEI_USB_IO_PPI interface pointer for the device +// that is being accessed +// IN UINT8 Port +// -- This value is the hub port number for which the +// status is to be returned. +// OUT UINT32 *PortStatus +// -- This output value is the USB Specification +// (Revision 2.0) Hub Port Status field (upper word) +// and Change Status field (lower word) values as +// returned by the Get Port Status Hub Class device +// standard request. +// +// Output: +// EFI_STATUS (Return Value) +// = EFI_SUCCESS on successful completion +// or valid EFI error code +// +//--------------------------------------------------------------------------- +//<AMI_PHDR_END> + +EFI_STATUS PeiHubGetPortStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + OUT UINT32 *PortStatus ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + PEI_USB_DEVICE *PeiUsbDev; + EFI_STATUS EfiStatus; + UINT32 HubPortStatus = 0; + UINT32 Timeout; + EFI_USB_PORT_STATUS_MAP *PortStatusMap; + UINT8 Index; + UINT8 Count; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi ); + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_GET_PORT_STATUS_REQ_TYPE; + DevReq.Request = HUB_GET_PORT_STATUS; + DevReq.Value = 0; + DevReq.Index = Port; + DevReq.Length = sizeof(UINT32); + + Timeout = 3000; + + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbDataIn, + Timeout, + &HubPortStatus, + sizeof(UINT32) + ); + + if (PeiUsbDev->DeviceSpeed != USB_SUPER_SPEED_DEVICE) { + PortStatusMap = HubPortStatusMap; + Count = sizeof(HubPortStatusMap) / sizeof(EFI_USB_PORT_STATUS_MAP); + } else { + PortStatusMap = SsHubPortStatusMap; + Count = sizeof(SsHubPortStatusMap) / sizeof(EFI_USB_PORT_STATUS_MAP); + } + + for (*PortStatus = 0, Index = 0; Index < Count; Index++) { + if (HubPortStatus & PortStatusMap[Index].HubPortStatus) { + *PortStatus |= PortStatusMap[Index].EfiPortStatus; + } + } + + return EfiStatus; +} + + +EFI_STATUS PeiHubSetPortFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + IN UINT8 Value ) + +/*++ + + Routine Description: + Set specified feature to a give hub port + + Arguments: + UsbIoPpi - EFI_USB_IO_PROTOCOL instance + Port - Usb hub port number (starting from 1). + Value - New feature value. + + Returns: + EFI_SUCCESS + EFI_DEVICE + EFI_TIME_OUT + EFI_INVALID_PARAMETER + + --*/ + +{ + EFI_USB_DEVICE_REQUEST DevReq; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_SET_PORT_FEATURE_REQ_TYPE; + DevReq.Request = HUB_SET_PORT_FEATURE; + DevReq.Value = Value; + DevReq.Index = Port; + DevReq.Length = 0; + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + Timeout, + NULL, + 0 + ); + + return EfiStatus; +} + + +EFI_STATUS PeiHubClearPortFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + IN UINT8 Value ) + +/*++ + + Routine Description: + Clear a specified feature of a given hub port + + Arguments: + UsbIoPpi - EFI_USB_IO_PROTOCOL instance + Port - Usb hub port number (starting from 1). + Value - Feature value that will be cleared from + that hub port. + + Returns: + EFI_SUCCESS + EFI_DEVICE + EFI_TIME_OUT + EFI_INVALID_PARAMETER + + --*/ +{ + EFI_USB_DEVICE_REQUEST DevReq; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_CLEAR_FEATURE_PORT_REQ_TYPE; + DevReq.Request = HUB_CLEAR_FEATURE_PORT; + DevReq.Value = Value; + DevReq.Index = Port; + DevReq.Length = 0; + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + Timeout, + NULL, + 0 + ); + + return EfiStatus; +} + + +EFI_STATUS PeiHubGetHubStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + OUT UINT32 *HubStatus ) + +/*++ + + Routine Description: + Get Hub Status + + Arguments: + UsbIoPpi - EFI_USB_IO_PROTOCOL instance + HubStatus - Current Hub status and change status. + + Returns: + EFI_SUCCESS + EFI_DEVICE + EFI_TIME_OUT + + --*/ +{ + EFI_USB_DEVICE_REQUEST DevReq; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_GET_HUB_STATUS_REQ_TYPE; + DevReq.Request = HUB_GET_HUB_STATUS; + DevReq.Value = 0; + DevReq.Index = 0; + DevReq.Length = sizeof(UINT32); + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbDataIn, + Timeout, + HubStatus, + sizeof(UINT32) + ); + + return EfiStatus; +} + + +EFI_STATUS PeiHubSetHubFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Value ) + +/*++ + + Routine Description: + Set a specified feature to the hub + + Arguments: + UsbIoPpi - EFI_USB_IO_PROTOCOL instance + Value - Feature value that will be set to the hub. + + Returns: + EFI_SUCCESS + EFI_DEVICE + EFI_TIME_OUT + + --*/ +{ + EFI_USB_DEVICE_REQUEST DevReq; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_SET_HUB_FEATURE_REQ_TYPE; + DevReq.Request = HUB_SET_HUB_FEATURE; + DevReq.Value = Value; + DevReq.Index = 0; + DevReq.Length = 0; + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + Timeout, + NULL, + 0 + ); + + return EfiStatus; +} + + +EFI_STATUS PeiHubClearHubFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Value ) + +/*++ + + Routine Description: + Set a specified feature to the hub + + Arguments: + UsbIoPpi - EFI_USB_IO_PROTOCOL instance + Value - Feature value that will be cleared from the hub. + + Returns: + EFI_SUCCESS + EFI_DEVICE + EFI_TIME_OUT + + --*/ +{ + EFI_USB_DEVICE_REQUEST DevReq; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_CLEAR_FEATURE_REQ_TYPE; + DevReq.Request = HUB_CLEAR_FEATURE; + DevReq.Value = Value; + DevReq.Index = 0; + DevReq.Length = 0; + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + Timeout, + NULL, + 0 + ); + + return EfiStatus; + +} + +EFI_STATUS PeiSetHubDepth ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT16 HubDepth) +{ + EFI_USB_DEVICE_REQUEST DevReq; + PEI_USB_DEVICE *PeiUsbDev; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi ); + if (PeiUsbDev->DeviceSpeed != USB_SUPER_SPEED_DEVICE) { + return EFI_SUCCESS; + } + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = HUB_SET_HUB_DEPTH_REQ_TYPE; + DevReq.Request = HUB_SET_HUB_DEPTH; + DevReq.Value = HubDepth; + DevReq.Index = 0; + DevReq.Length = 0; + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + Timeout, + NULL, + 0 + ); + + return EfiStatus; +} + +EFI_STATUS PeiGetHubDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINTN DescriptorSize, + OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor ) + +/*++ + + Routine Description: + Get the hub descriptor + + Arguments: + UsbIoPpi - EFI_USB_IO_PROTOCOL instance + DescriptorSize - The length of Hub Descriptor buffer. + HubDescriptor - Caller allocated buffer to store the hub descriptor + if successfully returned. + + Returns: + EFI_SUCCESS + EFI_DEVICE + EFI_TIME_OUT + + --*/ +{ + EFI_USB_DEVICE_REQUEST DevReq; + PEI_USB_DEVICE *PeiUsbDev; + EFI_STATUS EfiStatus; + UINT32 Timeout; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi ); + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + // + // Fill Device request packet + // + DevReq.RequestType = USB_RT_HUB | 0x80; + DevReq.Request = HUB_GET_DESCRIPTOR; + DevReq.Value = PeiUsbDev->DeviceSpeed == USB_SUPER_SPEED_DEVICE ? + USB_DT_SS_HUB << 8: USB_DT_HUB << 8; + DevReq.Index = 0; + DevReq.Length = (UINT16) DescriptorSize; + + Timeout = 3000; + EfiStatus = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbDataIn, + Timeout, + HubDescriptor, + (UINT16) DescriptorSize + ); + + return EfiStatus; + +} + + +EFI_STATUS PeiDoHubConfig ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice ) + +/*++ + + Routine Description: + Configure the hub + + Arguments: + PeiUsbDevice - Indicating the hub controller device that + will be configured + + Returns: + EFI_SUCCESS + EFI_DEVICE_ERROR + + --*/ +{ + EFI_USB_HUB_DESCRIPTOR HubDescriptor; + EFI_STATUS Status; + EFI_USB_HUB_STATUS HubStatus; + UINTN i; + UINT32 PortStatus; + PEI_USB_IO_PPI *UsbIoPpi; + + BOOLEAN SkipDebugPort = PeiUsbDevice->UsbHcPpi->DebugPortUsed; +//(EIP67320+)> + PEI_STALL_PPI *PeiStall; + (**PeiServices).LocatePpi( + PeiServices, + &gPeiStallPpiGuid, + 0, + NULL, + &PeiStall + ); +//<(EIP67320+) + ZeroMem( &HubDescriptor, sizeof(HubDescriptor) ); + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + + Status = PeiSetHubDepth(PeiServices, + UsbIoPpi, + PeiUsbDevice->HubDepth); + if ( EFI_ERROR( Status ) ) { + return EFI_DEVICE_ERROR; + } + + // + // First get the whole descriptor, then + // get the number of hub ports + // + Status = PeiGetHubDescriptor( + PeiServices, + UsbIoPpi, + sizeof(EFI_USB_HUB_DESCRIPTOR), + &HubDescriptor + ); + if ( EFI_ERROR( Status ) ) { + return EFI_DEVICE_ERROR; + } + + PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts; + + Status = PeiHubGetHubStatus( PeiServices, + UsbIoPpi, + (UINT32 *) &HubStatus + ); + + if ( EFI_ERROR( Status ) ) { + return EFI_DEVICE_ERROR; + } + + // + // Get all hub ports status + // + for (i = 0; i < PeiUsbDevice->DownStreamPortNo; i++) { + +// Intel Debug port - Second port of the controller + if(SkipDebugPort && (i == 1) ) + continue; + + Status = PeiHubGetPortStatus( PeiServices, + UsbIoPpi, + (UINT8) (i + 1), + &PortStatus + ); + if ( EFI_ERROR( Status ) ) { + continue; + } + } + + // + // Power all the hub ports + // + for (i = 0; i < PeiUsbDevice->DownStreamPortNo; i++) { +// Intel Debug port - Second port of the controller + if( SkipDebugPort && (i == 1) ) + continue; + + Status = PeiHubSetPortFeature( PeiServices, + UsbIoPpi, + (UINT8) (i + 1), + EfiUsbPortPower + ); + if ( EFI_ERROR( Status ) ) { + continue; + } + } + + // + // Clear Hub Status Change + // + Status = PeiHubGetHubStatus( PeiServices, + UsbIoPpi, + (UINT32 *) &HubStatus + ); + if ( EFI_ERROR( Status ) ) { + return EFI_DEVICE_ERROR; + } + else { + // + // Hub power supply change happens + // + if (HubStatus.HubChange & HUB_CHANGE_LOCAL_POWER) { + PeiHubClearHubFeature( PeiServices, + UsbIoPpi, + C_HUB_LOCAL_POWER + ); + } + + // + // Hub change overcurrent happens + // + if (HubStatus.HubChange & HUB_CHANGE_OVERCURRENT) { + PeiHubClearHubFeature( PeiServices, + UsbIoPpi, + C_HUB_OVER_CURRENT + ); + } + } + PeiStall->Stall( PeiServices, PeiStall, (HubDescriptor.PwrOn2PwrGood << 1) *1000); //(EIP67320) + return EFI_SUCCESS; + +} + + +// +// Send reset signal over the given root hub port +// +VOID PeiResetHubPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + UINT8 PortNum ) +{ + PEI_STALL_PPI *PeiStall; + UINT8 n; + EFI_USB_PORT_STATUS HubPortStatus; + + + (**PeiServices).LocatePpi( + PeiServices, + &gPeiStallPpiGuid, + 0, + NULL, + &PeiStall + ); + + // + // reset root port + // + PeiHubSetPortFeature( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortReset + ); + + n = 20; + do { + PeiHubGetPortStatus( + PeiServices, + UsbIoPpi, + PortNum, + (UINT32 *) &HubPortStatus + ); + PeiStall->Stall( + PeiServices, + PeiStall, + 1000 + ); + n -= 1; + } while ( (HubPortStatus.PortChangeStatus & + USB_PORT_STAT_C_RESET) == 0 && n > 0 ); + + PeiStall->Stall( + PeiServices, + PeiStall, + 500 + ); + // + // Clear any change status + // + PeiHubClearPortFeature( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortResetChange + ); + + return; +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2007, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c new file mode 100644 index 0000000..157cb9b --- /dev/null +++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c @@ -0,0 +1,334 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2006, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// +// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbIoPeim.c 6 1/18/11 1:05a Ryanchou $ +// +// $Revision: 6 $ +// +// $Date: 1/18/11 1:05a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbIoPeim.c $ +// +// 6 1/18/11 1:05a Ryanchou +// [TAG] EIP47931 +// [Category] Improvement +// [Description] Added USB 3.0 hub support. +// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c, +// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h, +// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h +// +// 5 3/17/09 5:04p Olegi +// Added TransactionTranslator for slow/full speed devices behind USB2 +// hub. +// +// 4 3/03/09 7:21p Olegi +// Changed the type of MaxPktSize from UINT8 to UINT16. +// +// 3 7/18/08 5:05p Michaela +// 1 File-level debugging is now available +// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns +// the keypress so that conditional debugging can +// be dynamic (alphanumeric keys only) +// 3 Added more function headers. +// 4 Removed code that will never be used (I.e., Bala?). +// 5 Moved typedef, contants and extern declarations +// into header files. +// 6 Now all controller blocks are enabled for SB700 +// (EHCI controllers route to companion controller +// by default) +// 7 Removed unused constants and typedefs n OhciPei.h +// (also reorganized the file to make it more +// readable.) +// 8 Renamed many functions/variables according to +// coding standard. +// 9 Removed code initializing data structures for +// periodic lists, as this is not needed. +// 10 Removed the CONTROLLER_TYPE SDL token to +// allow UHCI and OHCI controllers to supported +// simultaneously. (modified MAKE files +// accordingly) +// +// 2 7/10/08 6:37p Michaela +// Updated to support OHCI controllers +// +// 1 9/22/06 12:19p Sivagarn +// - Initial Checkin +// - Included Recovery code in Source +// +//***************************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: UsbIoPeim.C +// +// Description: This file belongs to "Framework". +// This file is modified by AMI to include copyright message, +// appropriate header and integration code. +// This file contains generic routines needed for USB recovery +// PEIM +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +/*++ + This file contains 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. + --*/ + +/*++ + + 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: + + UsbIoPeim.c + + Abstract: + + Usb Io PPI + + --*/ + +#include "UsbPeim.h" +#include "PeiUsbLib.h" + +#define PAGESIZE 4096 + +VOID +ResetRootPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + UINT8 PortNum ); + +EFI_STATUS PeiUsbControlTransfer ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN EFI_USB_DEVICE_REQUEST *Request, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT32 Timeout, + IN OUT VOID *Data OPTIONAL, + IN UINTN DataLength OPTIONAL ) +{ + EFI_STATUS Status; + PEI_USB_DEVICE *PeiUsbDev; + PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi; + UINT32 TransferResult; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This ); + UsbHcPpi = PeiUsbDev->UsbHcPpi; + + Status = UsbHcPpi->ControlTransfer( + PeiServices, + UsbHcPpi, + PeiUsbDev->DeviceAddress, + PeiUsbDev->DeviceSpeed, + PeiUsbDev->MaxPacketSize0, + PeiUsbDev->TransactionTranslator, + Request, + Direction, + Data, + &DataLength, + Timeout, + &TransferResult + ); + + return Status; +} + + +EFI_STATUS PeiUsbBulkTransfer ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout ) +{ + EFI_STATUS Status; + PEI_USB_DEVICE *PeiUsbDev; + PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi; + UINT32 TransferResult; + UINT16 MaxPacketLength; + UINT8 DataToggle; + UINT8 OldToggle; + EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor; + UINT8 EndpointIndex; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This ); + UsbHcPpi = PeiUsbDev->UsbHcPpi; + + EndpointIndex = 0; + + while (EndpointIndex < MAX_ENDPOINT) { + Status = PeiUsbGetEndpointDescriptor( PeiServices, + This, EndpointIndex, &EndpointDescriptor ); + if ( EFI_ERROR( Status ) ) { + return EFI_INVALID_PARAMETER; + } + + if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) { + break; + } + + EndpointIndex++; + } + + if (EndpointIndex == MAX_ENDPOINT) { + return EFI_INVALID_PARAMETER; + } + + MaxPacketLength = (PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize); + if ( ( PeiUsbDev->DataToggle & (1 << EndpointIndex) ) != 0 ) { + DataToggle = 1; + } + else { + DataToggle = 0; + } + + OldToggle = DataToggle; + + Status = UsbHcPpi->BulkTransfer( + PeiServices, + UsbHcPpi, + PeiUsbDev->DeviceAddress, + DeviceEndpoint, + PeiUsbDev->DeviceSpeed, + MaxPacketLength, + PeiUsbDev->TransactionTranslator, + Data, + DataLength, + &DataToggle, + Timeout, + &TransferResult + ); + + if (OldToggle != DataToggle) { + PeiUsbDev->DataToggle = + (UINT8) ( PeiUsbDev->DataToggle ^ (1 << EndpointIndex) ); + } + + return Status; +} + + +EFI_STATUS PeiUsbGetInterfaceDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor ) +{ + PEI_USB_DEVICE *PeiUsbDev; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This ); + + *InterfaceDescriptor = PeiUsbDev->InterfaceDesc; + + return EFI_SUCCESS; +} + + +EFI_STATUS PeiUsbGetEndpointDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN UINT8 EndpointIndex, + IN EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor ) +{ + PEI_USB_DEVICE *PeiUsbDev; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This ); + + if (EndpointIndex >= PeiUsbDev->InterfaceDesc->NumEndpoints) { + return EFI_INVALID_PARAMETER; + } + + *EndpointDescriptor = PeiUsbDev->EndpointDesc[EndpointIndex]; + + return EFI_SUCCESS; +} + + +EFI_STATUS PeiUsbPortReset ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This ) +{ + PEI_USB_DEVICE *PeiUsbDev; + EFI_STATUS Status; + UINT8 Address; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This ); + + ResetRootPort( + PeiServices, + PeiUsbDev->UsbHcPpi, + PeiUsbDev->DeviceAddress + ); + + // + // Set address + // + Address = PeiUsbDev->DeviceAddress; + PeiUsbDev->DeviceAddress = 0; + + Status = PeiUsbSetDeviceAddress( + PeiServices, + This, + Address + ); + + if ( EFI_ERROR( Status ) ) { + return Status; + } + + PeiUsbDev->DeviceAddress = Address; + + // + // Set default configuration + // + Status = PeiUsbSetConfiguration( + PeiServices, + This + ); + + return Status; +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2006, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c new file mode 100644 index 0000000..87afc78 --- /dev/null +++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c @@ -0,0 +1,1006 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// +// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbPeim.c 17 11/24/12 5:46a Ryanchou $ +// +// $Revision: 17 $ +// +// $Date: 11/24/12 5:46a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbPeim.c $ +// +// 17 11/24/12 5:46a Ryanchou +// [TAG] EIP103990 +// [Category] Improvement +// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24. +// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c, +// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h, +// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c, +// PeiUsbLib.h, UsbPeim.h +// +// 16 8/23/12 10:01p Wilsonlee +// [TAG] EIP97069 +// [Category] Improvement +// [Description] Reset root port algorythm update. +// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c, +// UhcPeim.h, UsbPeim.c, usb.h +// +// 15 1/18/11 1:06a Ryanchou +// [TAG] EIP47931 +// [Category] Improvement +// [Description] Added USB 3.0 hub support. +// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c, +// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h, +// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h +// +// 14 10/22/10 2:55a Rameshr +// [TAG]- EIP 43687 +// [Category]-IMPROVEMENT +// [Description]- Build warning from UsbRecovery driver - +// UsbHostController.obj : warning LNK4221: no public symbols found; +// archive member will be inaccessible. +// [Files]- uhcpeim.c, usbpeim.c, UsbHostcontroller.h +// +// 13 10/12/10 11:20a Olegi +// XHCI support added. +// +// 12 1/06/10 11:23a Olegi +// Fix for EIP32503: The Interface descriptor of some devices is not +// directly after the configuration descriptor, and the first Endpoint +// descriptor is not directly after the Interface either. Changed the +// descriptior data parser. +// +// 11 10/20/09 9:17a Olegi +// EIP#28255: Set proper TransactionTranslator field for a non-hispeed USB +// device. +// +// 10 3/17/09 5:07p Olegi +// Added TransactionTranslator for slow/full speed devices behind USB2 +// hub. +// +// 9 10/21/08 5:57p Michaela +// Added EHCI-related fixes for issues +// that may occur if EHCI is used before +// USB Recovery is invoked: +// Added SDL Tokens: +// PEI_EHCI_PCI_BDFS and +// PEI_EHCI_MEM_BASE_ADDRESSES. +// +// Removed/modified some debugging +// development code: +// Removed SDL Tokens: +// USBR_DEBUG_SUPPORT and +// USBR_SERIAL_PORT_AVAILABLE +// Removed Elinks: +// UsbRecoveryDebug_DIR and +// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs +// Modified SDL Token: +// FORCE_RECOVERY to default value of 0. +// +// (See this module's Help documentation +// for more information.) +// +// 8 7/29/08 5:52p Michaela +// 1) Updated code to move most porting tasks to SDL +// 2) Added more debug break points and improved interactive +// debugging capability for when a serial port is not available. +// 3) Updated help files +// +// 7 7/18/08 5:05p Michaela +// 1 File-level debugging is now available +// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns +// the keypress so that conditional debugging can +// be dynamic (alphanumeric keys only) +// 3 Added more function headers. +// 4 Removed code that will never be used (I.e., Bala?). +// 5 Moved typedef, contants and extern declarations +// into header files. +// 6 Now all controller blocks are enabled for SB700 +// (EHCI controllers route to companion controller +// by default) +// 7 Removed unused constants and typedefs n OhciPei.h +// (also reorganized the file to make it more +// readable.) +// 8 Renamed many functions/variables according to +// coding standard. +// 9 Removed code initializing data structures for +// periodic lists, as this is not needed. +// 10 Removed the CONTROLLER_TYPE SDL token to +// allow UHCI and OHCI controllers to supported +// simultaneously. (modified MAKE files +// accordingly) +// +// 6 7/10/08 6:37p Michaela +// Updated to support OHCI controllers +// +// 5 10/23/07 5:41p Ambikas +// +// 4 8/17/07 4:13p Ambikas +// +// 3 4/16/07 12:55p Sivagarn +// - Updated as per coding standard review +// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file +// is included +// +// 2 3/28/07 3:36a Meenakshim +// +// 1 9/22/06 12:19p Sivagarn +// - Initial Checkin +// - Included Recovery code in Source +// +//***************************************************************************** + +//<AMI_FHDR_START> +//---------------------------------------------------------------------------- +// +// Name: UsbPeim.C +// +// Description: This file belongs to "Framework". +// This file is modified by AMI to include copyright message, +// appropriate header and integration code. +// This file contains generic routines needed for USB recovery +// PEIM +// +//---------------------------------------------------------------------------- +//<AMI_FHDR_END> + +/*++ + This file contains 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. + --*/ + +/*++ + + 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: + + UsbPeim.c + + Abstract: + + Usb Bus PPI + + --*/ + +#include "UsbPeim.h" +#include "HubPeim.h" +#include "PeiUsbLib.h" + + +#include EFI_PPI_DEFINITION (Stall) +#include EFI_PPI_DEFINITION (LoadFile) + +EFI_GUID gPeiUsbIoPpiGuid = PEI_USB_IO_PPI_GUID; + +extern EFI_GUID gPeiStallPpiGuid; + + +#define PAGESIZE 4096 + +//static BOOLEAN mImageInMemory = FALSE; + + +// +// Driver Entry Point +// + + +EFI_STATUS +PeimInitializeUsb ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices ); + +// +// UsbIo PPI interface function +// +STATIC PEI_USB_IO_PPI mUsbIoPpi = { + PeiUsbControlTransfer, + PeiUsbBulkTransfer, + PeiUsbGetInterfaceDescriptor, + PeiUsbGetEndpointDescriptor, + PeiUsbPortReset +}; + +STATIC EFI_PEI_PPI_DESCRIPTOR mUsbIoPpiList = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPeiUsbIoPpiGuid, + NULL +}; + +// +// Helper functions +// +STATIC +EFI_STATUS +PeiUsbEnumeration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi ); + +STATIC +EFI_STATUS +PeiConfigureUsbDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice, + IN UINT8 Port, + IN OUT UINT8 *DeviceAddress ); + +STATIC +EFI_STATUS +PeiUsbGetAllConfiguration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice ); + + +VOID +ResetRootPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + UINT8 PortNum ); + +extern VOID ZeroMem ( + IN VOID *Buffer, + IN UINTN Size ); + + + +// +// PEIM Entry Point +// +// EFI_PEIM_ENTRY_POINT (PeimInitializeUsb); + +EFI_STATUS PeimInitializeUsb ( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices ) +{ + EFI_STATUS Status; + UINTN i; + PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi; + + // Assign resources and enable UHCI controllers + // + // when the image is in flash, the global variable + // mImageInMemory could not be modified; + // when the image is successfully loaded into memory, + // mImageInMemory could be modified to TRUE. + // + + i = 0; + while (TRUE) { + // + // Get UsbHcPpi at first. + // + Status = (**PeiServices).LocatePpi( PeiServices, + &gPeiUsbHostControllerPpiGuid, i, NULL, &UsbHcPpi ); + + if ( EFI_ERROR( Status ) ) { + break; + } + + PeiUsbEnumeration( PeiServices, UsbHcPpi ); // 0xff06 + i++; + } + + return EFI_SUCCESS; +} + + +STATIC +EFI_STATUS PeiHubEnumeration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice, + IN UINT8 *CurrentAddress ) +// +// Since we are not going to support hot-plug, we will do a +// dedicated polling process to get all ports change event +// discovered. This can help to avoid introduce interrupt +// transfer into the system, for each hub, we will wait for +// 3s and if one port is enabled we will not wait for others +// We will start parsing each of them in sequence. +// +{ + UINTN Delay; + UINT8 Port; + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + EFI_USB_PORT_STATUS PortStatus; + BOOLEAN PortChanged; + UINT8 *AllocateAddress; + PEI_USB_DEVICE *NewPeiUsbDevice; + PEI_STALL_PPI *StallPpi; + + + PortChanged = FALSE; + + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid, + 0, NULL, &StallPpi ); + + Delay = (HUB_TIME_OUT * STALL_1_MILLI_SECOND / 50000) + 1; + + // + // Do while will do a 3s scan for the USB HUB for a connected + // device. If we have found one, the waiting process will be + // breaked since we assue other ports will be discovered at + // the same time. + // + do { + for (Port = 1; Port <= PeiUsbDevice->DownStreamPortNo; Port++) { + + Status = PeiHubGetPortStatus( PeiServices, UsbIoPpi, + Port, (UINT32 *) &PortStatus ); + + if ( EFI_ERROR( Status ) ) { + continue; + } + + if ( IsPortConnectChange( PortStatus.PortChangeStatus ) ) { + PortChanged = TRUE; + PeiHubClearPortFeature( PeiServices, UsbIoPpi, + Port, EfiUsbPortConnectChange ); + + if ( IsPortConnect( PortStatus.PortStatus ) ) { + + if (IsPortEnable(PortStatus.PortStatus) == FALSE) { + // + // First reset and enable this port + // + PeiResetHubPort( PeiServices, UsbIoPpi, Port ); + + PeiHubGetPortStatus( PeiServices, UsbIoPpi, + Port, (UINT32 *) &PortStatus ); + } + + // + // Begin to deal with the new device + // + Status = (*PeiServices)->AllocatePool( PeiServices, + sizeof(PEI_USB_DEVICE), &AllocateAddress ); + if ( EFI_ERROR( Status ) ) { + return EFI_OUT_OF_RESOURCES; + } + + NewPeiUsbDevice = (PEI_USB_DEVICE *)AllocateAddress; + + ZeroMem( NewPeiUsbDevice, sizeof(PEI_USB_DEVICE) ); + + NewPeiUsbDevice->Signature = + PEI_USB_DEVICE_SIGNATURE; + NewPeiUsbDevice->DeviceAddress = 0; + NewPeiUsbDevice->MaxPacketSize0 = 8; + NewPeiUsbDevice->DataToggle = 0; + NewPeiUsbDevice->UsbIoPpi = mUsbIoPpi; + NewPeiUsbDevice->UsbIoPpiList = mUsbIoPpiList; + NewPeiUsbDevice->UsbIoPpiList.Ppi = + &NewPeiUsbDevice->UsbIoPpi; + NewPeiUsbDevice->UsbHcPpi = + PeiUsbDevice->UsbHcPpi; + NewPeiUsbDevice->DeviceSpeed = + USB_FULL_SPEED_DEVICE; + NewPeiUsbDevice->IsHub = 0x0; + NewPeiUsbDevice->DownStreamPortNo = 0x0; + NewPeiUsbDevice->TransactionTranslator = + (UINT16)(Port << 7) + PeiUsbDevice->DeviceAddress; + NewPeiUsbDevice->HubDepth = 0x0; + //(EIP28255+)> + if ( (PeiUsbDevice->DeviceSpeed == USB_SLOW_SPEED_DEVICE) || + (PeiUsbDevice->DeviceSpeed == USB_FULL_SPEED_DEVICE) ) + { + NewPeiUsbDevice->TransactionTranslator = PeiUsbDevice->TransactionTranslator; + } + //<(EIP28255+) + if ( IsPortLowSpeedDeviceAttached( PortStatus.PortStatus ) ) + { + NewPeiUsbDevice->DeviceSpeed = USB_SLOW_SPEED_DEVICE; + } + + if ( IsPortHighSpeedDeviceAttached( PortStatus.PortStatus ) ) + { + NewPeiUsbDevice->DeviceSpeed = USB_HIGH_SPEED_DEVICE; + } + + if ( IsPortSuperSpeedDeviceAttached( PortStatus.PortStatus ) ) + { + NewPeiUsbDevice->DeviceSpeed = USB_SUPER_SPEED_DEVICE; + } + + // + // Configure that Usb Device + // + Status = PeiConfigureUsbDevice( PeiServices, + NewPeiUsbDevice, Port, CurrentAddress ); + + if ( EFI_ERROR( Status ) ) { + PeiHubClearPortFeature( PeiServices, UsbIoPpi, + Port, EfiUsbPortEnable ); + continue; + } + + Status = (**PeiServices).InstallPpi( PeiServices, + &NewPeiUsbDevice->UsbIoPpiList ); + + if (NewPeiUsbDevice->InterfaceDesc->InterfaceClass + == BASE_CLASS_HUB) + { + NewPeiUsbDevice->IsHub = 0x1; + NewPeiUsbDevice->HubDepth = PeiUsbDevice->HubDepth + 1; + + Status = PeiDoHubConfig( PeiServices, + NewPeiUsbDevice ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + PeiHubEnumeration( PeiServices, NewPeiUsbDevice, + CurrentAddress ); + } + } + + } + } + + if (PortChanged) { + break; + } + StallPpi->Stall( PeiServices, StallPpi, 50000 ); + + } while (Delay--); + + return EFI_SUCCESS; +} + + +STATIC +EFI_STATUS PeiUsbEnumeration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi ) +{ + UINT8 NumOfRootPort; + EFI_STATUS Status; + UINT8 Port; + EFI_USB_PORT_STATUS PortStatus; + PEI_USB_DEVICE *PeiUsbDevice; + UINT8 *AllocateAddress; + UINT8 CurrentAddress; + PEI_STALL_PPI *PeiStall; + + (**PeiServices).LocatePpi( + PeiServices, + &gPeiStallPpiGuid, + 0, + NULL, + &PeiStall + ); + + CurrentAddress = 0; + UsbHcPpi->GetRootHubPortNumber( + PeiServices, + UsbHcPpi, + (UINT8 *) &NumOfRootPort + ); + + + for (Port = 1; Port <= NumOfRootPort; Port++) { + // + // First get root port status to detect changes happen + // + UsbHcPpi->GetRootHubPortStatus( + PeiServices, + UsbHcPpi, + Port, + &PortStatus + ); + + if ( IsPortConnectChange( PortStatus.PortChangeStatus ) ) { + + // + // Changes happen, first clear this change status + // + UsbHcPpi->ClearRootHubPortFeature( + PeiServices, + UsbHcPpi, + Port, + EfiUsbPortConnectChange + ); + + if ( IsPortConnect( PortStatus.PortStatus ) ) { + + if (IsPortEnable(PortStatus.PortStatus) == FALSE) { + // + // First reset and enable this port + // + ResetRootPort( PeiServices, UsbHcPpi, Port ); + + UsbHcPpi->GetRootHubPortStatus( + PeiServices, + UsbHcPpi, + Port, + &PortStatus + ); + } + + // + // Connect change happen + // + Status = (*PeiServices)->AllocatePool( + PeiServices, + sizeof(PEI_USB_DEVICE), + &AllocateAddress + ); + if ( EFI_ERROR( Status ) ) { + return EFI_OUT_OF_RESOURCES; + } + + PeiUsbDevice = (PEI_USB_DEVICE *) ( (UINTN) AllocateAddress ); + ZeroMem( PeiUsbDevice, sizeof(PEI_USB_DEVICE) ); + + PeiUsbDevice->Signature = PEI_USB_DEVICE_SIGNATURE; + PeiUsbDevice->DeviceAddress = 0; + PeiUsbDevice->MaxPacketSize0 = 8; + PeiUsbDevice->DataToggle = 0; + PeiUsbDevice->UsbIoPpi = mUsbIoPpi; + PeiUsbDevice->UsbIoPpiList = mUsbIoPpiList; + PeiUsbDevice->UsbIoPpiList.Ppi = &PeiUsbDevice->UsbIoPpi; + PeiUsbDevice->UsbHcPpi = UsbHcPpi; + PeiUsbDevice->DeviceSpeed = USB_FULL_SPEED_DEVICE; + PeiUsbDevice->IsHub = 0x0; + PeiUsbDevice->DownStreamPortNo = 0x0; + PeiUsbDevice->TransactionTranslator = 0x0; + PeiUsbDevice->HubDepth = 0x0; + + if ( IsPortLowSpeedDeviceAttached( PortStatus.PortStatus ) ) + { + PeiUsbDevice->DeviceSpeed = USB_SLOW_SPEED_DEVICE; + } + + if ( IsPortHighSpeedDeviceAttached( PortStatus.PortStatus ) ) + { + PeiUsbDevice->DeviceSpeed = USB_HIGH_SPEED_DEVICE; + } + + if ( IsPortSuperSpeedDeviceAttached( PortStatus.PortStatus ) ) + { + PeiUsbDevice->DeviceSpeed = USB_SUPER_SPEED_DEVICE; + } + + // + // Delay some times to enable usb devices to initiate. + // + PeiStall->Stall( + PeiServices, + PeiStall, + 5000 + ); + + // + // Configure that Usb Device + // + Status = PeiConfigureUsbDevice( + PeiServices, + PeiUsbDevice, + Port, + &CurrentAddress + ); + + if ( EFI_ERROR( Status ) ) { + UsbHcPpi->ClearRootHubPortFeature( + PeiServices, + UsbHcPpi, + Port, + EfiUsbPortEnable + ); + continue; + } + + Status = (**PeiServices).InstallPpi( + PeiServices, + &PeiUsbDevice->UsbIoPpiList + ); + + if (PeiUsbDevice->InterfaceDesc->InterfaceClass + == BASE_CLASS_HUB) + { + PeiUsbDevice->IsHub = 0x1; + + Status = PeiDoHubConfig( PeiServices, PeiUsbDevice ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + + PeiHubEnumeration( PeiServices, PeiUsbDevice, + &CurrentAddress ); + } + } + } + } + + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS PeiConfigureUsbDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice, + IN UINT8 Port, + IN OUT UINT8 *DeviceAddress ) +{ + EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor; + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + UINT8 i; + PEI_STALL_PPI *StallPpi = NULL; + UINT8 Retry = 2; + + ( **PeiServices ).LocatePpi( PeiServices, &gPeiStallPpiGuid, + 0, NULL, &StallPpi ); + + if (PeiUsbDevice->UsbHcPpi->PreConfigureDevice != NULL) { + Status = PeiUsbDevice->UsbHcPpi->PreConfigureDevice( PeiServices, + PeiUsbDevice->UsbHcPpi, Port, PeiUsbDevice->DeviceSpeed, + PeiUsbDevice->TransactionTranslator); + if ( EFI_ERROR( Status ) ) { + return Status; + } + } + + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + + //----------------------------------------------------------------------- + // Try 5 times to read the first 8 bytes to determine the size + for (i = 0; i < 5; i++) { + Status = PeiUsbGetDescriptor( PeiServices, + UsbIoPpi, + SET_DESCRIPTOR_TYPE( USB_DT_DEVICE ), // Value = Type << 8 | Index + 0, // Index + 8, // DescriptorLength + &DeviceDescriptor ); + if ( !EFI_ERROR( Status ) ) { + break; + } + StallPpi->Stall( PeiServices, StallPpi, 100 * 1000 ); // 100msec delay + } + if ( EFI_ERROR( Status ) ) { + return Status; + } + + //----------------------------------------------------------------------- + // Set MaxPacketSize0 = 0x40 if packet size is not specified + PeiUsbDevice->MaxPacketSize0 = (DeviceDescriptor.MaxPacketSize0) + ? DeviceDescriptor.MaxPacketSize0 + : 0x40; + + + //----------------------------------------------------------------------- + // Get the entire USB device descriptor + StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay + Status = PeiUsbGetDescriptor( + PeiServices, + UsbIoPpi, + SET_DESCRIPTOR_TYPE( USB_DT_DEVICE ), // Value = Type << 8 | Index + 0, // Index + sizeof(EFI_USB_DEVICE_DESCRIPTOR), // DescriptorLength + &DeviceDescriptor ); + + if ( EFI_ERROR( Status ) ) { + return Status; + } + + //----------------------------------------------------------------------- + // Get its default configuration and its first interface + StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay + Status = PeiUsbGetAllConfiguration( + PeiServices, + PeiUsbDevice ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + + //----------------------------------------------------------------------- + // Set the device's address + StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay + (*DeviceAddress)++; + Status = PeiUsbSetDeviceAddress( + PeiServices, + UsbIoPpi, + *DeviceAddress ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + PeiUsbDevice->DeviceAddress = *DeviceAddress; + + + StallPpi->Stall( PeiServices, StallPpi, 200 * 1000 ); // 200msec delay + + Status = PeiUsbSetConfiguration( + PeiServices, + UsbIoPpi ); + + if ( EFI_ERROR( Status ) ) { + return Status; + } + + return EFI_SUCCESS; +} + + +STATIC EFI_STATUS PeiUsbGetAllConfiguration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *Device ) +{ + EFI_USB_CONFIG_DESCRIPTOR ConfigDesc = {0}; + EFI_USB_ENDPOINT_DESCRIPTOR *EndPointDesc = NULL; //(EIP32503+) + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi = &Device->UsbIoPpi; + UINTN i; + UINT8 *LastAddress = 0; + + + // Here we are parsing the descriptors for the device + // configurations where the hierarchy of descriptors + // is as follows: + // + // +----------------+ + // | Configuration1 | + // +----------------+ + // | +------------+ + // +---------| Interface1 |----+------------------+ + // | +------------+ | | + // | +-----------+ +-------------+ + // | | Endpoint1 | ... | EndpointMax | + // | +-----------+ +-------------+ + // | : + // | : + // | : + // | + // | +--------------+ + // +---------| InterfaceMax |----+------------------+ + // +--------------+ | | + // : +-----------+ +-------------+ + // : | Endpoint1 | ... | EndpointMax | + // +-----------+ +-------------+ + // +------------------+ + // | ConfigurationMax | + // +------------------+ + // | +------------+ + // +---------| Interface1 |----+------------------+ + // | +------------+ | | + // | +-----------+ +-------------+ + // | | Endpoint1 | ... | EndpointMax | + // | +-----------+ +-------------+ + // | : + // | : + // | : + // | +--------------+ + // +---------| InterfaceMax |----+------------------+ + // +--------------+ | | + // +-----------+ +-------------+ + // | Endpoint1 | ... | EndpointMax | + // +-----------+ +-------------+ + + + //------------------------------------------------------------- + // Fortunately, we are only interested in the first/default + // configuration and its first/default interface, so life is + // simple! + //------------------------------------------------------------- + + //------------------------------------------------------------- + // First get the device's 9-byte configuration descriptor to + // determine the length of all descriptors + Status = PeiUsbGetDescriptor( + PeiServices, + UsbIoPpi, + USB_DT_CONFIG << 8, + 0, + 9, + &ConfigDesc ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + + Status = (*PeiServices)->AllocatePool( PeiServices, + ConfigDesc.TotalLength, &Device->ConfigurationData ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + //------------------------------------------------------------- + // Get all the descriptors for this configuration using + // TotalLength from the first 9 bytes previously read. + // Then, save the Configuration descriptor into the + // device management structure. + Status = PeiUsbGetDescriptor( + PeiServices, + UsbIoPpi, + USB_DT_CONFIG << 8, + 0, + ConfigDesc.TotalLength, + (VOID *) Device->ConfigurationData ); + if ( EFI_ERROR( Status ) ) { + return Status; + } + Device->ConfigDesc = + (EFI_USB_CONFIG_DESCRIPTOR *) Device->ConfigurationData; + + LastAddress = Device->ConfigurationData + + Device->ConfigDesc->TotalLength - 1; + + if (Device->UsbHcPpi->EnableEndpoints != NULL) { + Status = Device->UsbHcPpi->EnableEndpoints(PeiServices, + Device->UsbHcPpi, Device->ConfigurationData); + + if ( EFI_ERROR( Status ) ) { + return Status; + } + } + + //-------------------------------------------------------------- + // Assume the Interface descriptor is directly after the + // configuration descriptor. + //-------------------------------------------------------------- + Device->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *) + ( (UINT8 *) Device->ConfigDesc + + Device->ConfigDesc->Length ); + //(EIP32503+)> + while ((UINT8 *)Device->InterfaceDesc < LastAddress && + Device->InterfaceDesc->DescriptorType != USB_DT_INTERFACE) + { + Device->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *) + ( (UINT8 *) Device->InterfaceDesc + + Device->InterfaceDesc->Length ); + } + //<(EIP32503+) + //-------------------------------------------------------------- + // Assume the first Endpoint descriptor is directly after the + // Interface descriptor. + //-------------------------------------------------------------- + //(EIP32503)> + EndPointDesc = (EFI_USB_ENDPOINT_DESCRIPTOR *) + ( (UINT8 *) Device->InterfaceDesc + + Device->InterfaceDesc->Length ); + + for (i = 0; i < Device->InterfaceDesc->NumEndpoints && + (UINT8 *)EndPointDesc < LastAddress; ) + { + if(EndPointDesc->DescriptorType == USB_DT_ENDPOINT) + { + Device->EndpointDesc[i++] = EndPointDesc; + } + EndPointDesc = (EFI_USB_ENDPOINT_DESCRIPTOR *) + ( (UINT8 *) EndPointDesc + + EndPointDesc->Length ); + } + //<(EIP32503) + return EFI_SUCCESS; +} + + +// +// Send reset signal over the given root hub port +// +VOID ResetRootPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + UINT8 PortNum ) +{ + EFI_PEI_STALL_PPI *PeiStall; + EFI_USB_PORT_STATUS PortStatus; + UINT8 i; + + ( **PeiServices ).LocatePpi( + PeiServices, + &gPeiStallPpiGuid, + 0, + NULL, + &PeiStall + ); + + + // + // reset root port + // + UsbHcPpi->SetRootHubPortFeature( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortReset + ); + + for (i = 0; i < 100; i++) { + UsbHcPpi->GetRootHubPortStatus( + PeiServices, + UsbHcPpi, + PortNum, + &PortStatus + ); + + if ((PortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) != 0) { + break; + } + + PeiStall->Stall( + PeiServices, + PeiStall, + 1 * 1000 // NVS - Changed to 10 msec (as per AMI USB Code) + ); + } + + if ((PortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0) { + return; + } + + // + // clear reset root port + // + UsbHcPpi->ClearRootHubPortFeature( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortResetChange + ); + + + UsbHcPpi->GetRootHubPortStatus( + PeiServices, + UsbHcPpi, + PortNum, + &PortStatus + ); + + if ((PortStatus.PortChangeStatus & USB_PORT_STAT_ENABLE) == 0) { + // + // Set port enable + // + UsbHcPpi->SetRootHubPortFeature( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortEnable + ); + PeiStall->Stall( + PeiServices, + PeiStall, + 100 * 1000 // NVS - Changed to 100msec as per AMI USB code + ); + } + + return; +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2008, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif new file mode 100644 index 0000000..4eca72e --- /dev/null +++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif @@ -0,0 +1,12 @@ +<component> + name = "UsbPeimSrc" + category = ModulePart + LocalRoot = "Core\EM\UsbRecovery\UsbPeimSrc\" + RefName = "UsbPeimSrc" +[files] +"HubPeim.c" +"UsbIoPeim.c" +"UsbPeim.c" +[parts] +"UsbIoPpi" +<endComponent> |