summaryrefslogtreecommitdiff
path: root/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c')
-rw-r--r--Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c508
1 files changed, 508 insertions, 0 deletions
diff --git a/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c b/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c
new file mode 100644
index 0000000..4256cdf
--- /dev/null
+++ b/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c
@@ -0,0 +1,508 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/OhciPeiBoard.c 6 4/11/11 11:59p Rameshr $
+//
+// $Revision: 6 $
+//
+// $Date: 4/11/11 11:59p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/OhciPeiBoard.c $
+//
+// 6 4/11/11 11:59p Rameshr
+// [TAG]- EIP 57444
+// [Category]-IMPROVEMENT
+// [Description]- PI1.1 Support.
+// [Files]- OhciPeiboard.c,Xhcipei.c, Peiusblib.c
+//
+// 5 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.)
+//
+// 4 7/29/08 7:50p Michaela
+// cleaned-up SB700-specific code
+//
+// 3 7/29/08 5:50p 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
+//
+// 2 7/18/08 5:04p 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)
+//
+// 1 7/10/08 6:35p Michaela
+// Updated to support OHCI controllers
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: OhciPeiBoard.c
+//
+// Description: This file contains routines that are board specific for
+// initializing the OHCI controller in the USB Recovery module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <PPI/PeiGetUCtrl.h>
+#include <PPI/OhciPPI.h>
+#include <PPI/stall.h>
+#include "OhciPei.h"
+
+#ifndef PI_SPECIFICATION_VERSION //old Core
+extern EFI_STATUS PciCfgModify(
+IN CONST EFI_PEI_SERVICES **PeiServices,
+IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+IN UINT64 Address,
+IN UINTN SetBits,
+IN UINTN ClearBits
+);
+#endif
+
+//----------------------------------------------------------------------------
+// Porting Steps:
+//
+// 1) define/undefine the appropriate southbridge type
+// 2) define the OHCI_BASE register
+// 3) define registers and their set/clear bits for each register to be
+// modified in each controller's PCI configuration space
+//
+//----------------------------------------------------------------------------
+
+
+// #define AMD_8111 // define to initialize AMD 8111 SB
+
+// #define AMD_SB700 // define to initialize AMD SB700 SB
+
+#define OHCI_BASE PEI_OHCI_IOBASE // first OHCI device is defined
+ // by SDL token and others
+ // are programmatically
+ // determined
+
+#define OHCI_MMIO_SIZE 0x1000 // size of each MMIO region
+
+// For the SB700, the SMBUS PCI configuration space is used
+// to enable USB hardware in the Southbridge
+#define SMBUS_PCI_USB_ENABLE_CFG PEI_PCI_CFG_ADDRESS( 0, 0x14, 0, 0x68 )
+#define SMBUS_PCI_EHCI_BITS BIT2 | BIT6
+#define SMBUS_PCI_OHCI_BITS BIT0 | BIT1 | BIT4 | BIT5 | BIT7
+
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gOhciControllerPciTable
+//
+// Description:
+// This is an array of type: PCI_BUS_DEV_FUNCTION
+//
+// This array is initialized from the PEI_OHCI_PCI_DEVICES SDL
+// token, which specifies a {bus,device,function} entry for each OHCI
+// controller. If no OHCI controllers exist, there will be only one
+// NULL entry.
+//
+// This array is used for PCI initialization of OHCI controllers,
+// as well as access to PCI configuration registers.
+//
+// Notes:
+// gOhciControllerPciTable and gOhciControllerCount are accessed via
+// extern declarations by OHCI generic code to access PCI configuration
+// space registers.
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+PCI_BUS_DEV_FUNCTION gOhciControllerPciTable[] = {USBR_OHCI_CONTROLLER_PCI_ADDRESS};
+UINT16 gOhciControllerCount = \
+ sizeof(gOhciControllerPciTable) / sizeof(PCI_BUS_DEV_FUNCTION);
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gOhciPciRegisterTable
+//
+// Description:
+// This is an array of type: OHCI_PCI_PROGRAMMING_TABLE
+//
+// This array is initialized from the OHCI_CONTROLLER_PCI_REGISTER_VALUE
+// SDL eLink, which specifies a { RegisterSize, Register, BitsToSet,
+// BitsToClear } entry for each register in the PCI configuration space
+// that needs to be modified.
+//
+// This array is used for PCI initialization of OHCI controllers.
+//
+// Notes:
+// If no OHCI controllers exist, there will be only one
+// NULL entry.
+//
+// When this table is used, it is assumed that all OHCI controllers
+// are identically programmed for the platform.
+//
+// Other important notes are:
+//
+// 1) do not include the BAR register (the first BAR is
+// PEI_OHCI_IOBASE and subsequent BAR values are
+// calculated from there),
+// 2) the command register should be last, as it enables
+// the devices MMIO access space.
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+OHCI_PCI_PROGRAMMING_TABLE gOhciPciRegisterTable[] = {USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE};
+#define OHCI_PCI_REGISTER_TABLE_SIZE \
+ sizeof(gOhciPciRegisterTable) / sizeof(OHCI_PCI_PROGRAMMING_TABLE)
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DefaultInit
+//
+// Description:
+// This function generically initializes the PCI configuration space
+// registers for all the OHCI controllers whose PCI addresses are
+// specified by the global PCI_BUS_DEV_FUNCTION array and whose PCI
+// register programming details are specified by the global
+// OHCI_PCI_PROGRAMMING_TABLE array.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN EFI_PEI_PCI_CFG_PPI *Pci
+// -- EFI_PEI_PCI_CFG_PPI pointer
+// IN EFI_PEI_STALL_PPI *StallPpi
+// -- EFI_PEI_STALL_PPI pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+// Notes:
+// This function should not need porting. All porting is accomplished
+// in the global PCI_BUS_DEV_FUNCTION and OHCI_PCI_PROGRAMMING_TABLE
+// arrays, where the former is defined by the
+// USBR_OHCI_CONTROLLER_PCI_ADDRESS SDL eLink and the latter is defined
+// by the USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE SDL eLink.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DefaultInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *Pci,
+ IN EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status;
+ UINT32 OhciBaseAddress = OHCI_BASE;
+ UINT16 ControllerIndex;
+ UINT16 RegisterIndex;
+
+
+ //------------------------------------------------------------------------
+ // PCI configuration space programming for all OHCI controllers
+ //------------------------------------------------------------------------
+ for (ControllerIndex = 0;
+ ControllerIndex < gOhciControllerCount;
+ ControllerIndex++, OhciBaseAddress += OHCI_MMIO_SIZE)
+ {
+
+ // Program the BAR
+ //~~~~~~~~~~~~~~~~
+ ABORT_ON_ERROR(
+ Pci->Write( PeiServices, Pci,
+ EfiPeiPciCfgWidthUint32,
+ OHCI_PCI_ADDRESS( ControllerIndex, OHCI_BASE_ADDR_REG ),
+ &OhciBaseAddress );
+ )
+
+ // Program all other registers using gOhciPciRegisterTable[]
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ for (RegisterIndex = 0;
+ RegisterIndex < OHCI_PCI_REGISTER_TABLE_SIZE;
+ RegisterIndex++)
+ {
+ EFI_PEI_PCI_CFG_PPI_WIDTH Width;
+
+ switch (gOhciPciRegisterTable[RegisterIndex].Size)
+ {
+ case 8:
+ Width = EfiPeiPciCfgWidthUint8;
+ break;
+ case 16:
+ Width = EfiPeiPciCfgWidthUint16;
+ break;
+ case 32:
+ Width = EfiPeiPciCfgWidthUint32;
+ break;
+ case 64:
+ Width = EfiPeiPciCfgWidthUint64;
+ break;
+ default:
+ continue;
+ }
+
+ ABORT_ON_ERROR(
+ PciCfgModify(
+ PeiServices,
+ Width,
+ OHCI_PCI_ADDRESS( ControllerIndex,
+ gOhciPciRegisterTable[RegisterIndex].Register ),
+ gOhciPciRegisterTable[RegisterIndex].SetBits,
+ gOhciPciRegisterTable[RegisterIndex].ClearBits );
+ )
+ }
+ }
+
+ return Status = EFI_SUCCESS;
+}
+
+
+#ifdef AMD_8111
+//-----------------------------------------------------
+// This code is not tested, it is simply preserved here
+//-----------------------------------------------------
+
+#define REG_PRI_MEMBASE 0x20
+#define REG_PRI_MEMLIM 0x22
+
+EFI_STATUS Amd8111Init (
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_PCI_CFG_PPI *Pci,
+ EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status;
+ UINT32 Buffer32;
+ UINT16 Buffer16;
+ UINT16 CmdReg;
+ volatile UINT32 BaseAddress;
+
+ //
+ // OHCI is sits behind the PCI brige. So program the PCI bridge
+ // First program bus numbers so that PCI slots are available
+ //
+ Buffer32 = 0x080800;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint32,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, REG_PRI_BNUM ),
+ &Buffer32
+ );
+
+
+ // Defines the base of memory range for PCI. 15:4 this 12 bits corresponds
+ // to 31:20 of mem addr 1MB boundary
+ BaseAddress = 0xc0c00000;
+ BaseAddress >>= 16;
+ BaseAddress &= 0xfffffff0;
+ Buffer16 = (UINT16) BaseAddress;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, REG_PRI_MEMBASE ),
+ &Buffer16
+ );
+
+ //Defines the top of the memory range
+ // BaseAddress = 0xc0c00000;
+ // BaseAddress += 0x00100000;
+ // BaseAddress >>= 16;
+ // BaseAddress &= 0xfffffff0;
+ // Buffer16 = (UINT16)BaseAddress;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, REG_PRI_MEMLIM ),
+ &Buffer16
+ );
+
+ //Program the prefectable memory space also.
+ BaseAddress = 0xc0c00000;
+ BaseAddress += 0x00100000;
+ BaseAddress >>= 16;
+ BaseAddress &= 0xfffffff0;
+ Buffer16 = (UINT16) BaseAddress;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x24 ),
+ &Buffer16
+ );
+
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x26 ),
+ &Buffer16
+ );
+
+
+ //Enable memory space, bus mastering of the root bridge
+ Pci->Read(
+ PeiServices,
+ Pci,
+ EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x04 ),
+ &CmdReg
+ );
+ CmdReg = (UINT16) (CmdReg | 0x06);
+ Pci->Write(
+ PeiServices,
+ Pci,
+ EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x04 ),
+ &CmdReg
+ );
+}
+#endif // #ifdef AMD_8111
+
+
+#ifdef AMD_SB700
+EFI_STATUS AmdSb700Init (
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_PCI_CFG_PPI *Pci,
+ EFI_PEI_STALL_PPI *StallPpi )
+{
+
+ //-----------------------------------------------------------------------
+ // Enable OHCI controllers from the SMBUS PCI configuration space
+ // using the SMBUS PCI space USB enable register
+ //
+ // By default, the companion controller (OHCI) should be the owner
+ // of the root hub port, so the EHCI controller hardware block
+ // does not need to be disabled.
+ //-----------------------------------------------------------------------
+ ABORT_ON_ERROR(
+ PciCfgModify( PeiServices,
+ EfiPeiPciCfgWidthUint8,
+ SMBUS_PCI_USB_ENABLE_CFG,
+ SMBUS_PCI_OHCI_BITS + SMBUS_PCI_EHCI_BITS,
+ 0
+ )
+ )
+
+ return EFI_SUCCESS;
+}
+#endif // #ifdef AMD_SB700
+
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OhciPeiBoardInit
+//
+// Description:
+// This is a porting hook for board-specific OHCI controller
+// initialization
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices -
+// IN EFI_PEI_PCI_CFG_PPI *Pci -
+// IN EFI_PEI_STALL_PPI *StallPpi -
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciPeiBoardInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *Pci,
+ IN EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ // SB-specific programming
+ #if defined (AMD_8111)
+ Status = Amd8111Init( PeiServices, Pci, StallPpi );
+ #elif defined (AMD_SB700)
+ Status = AmdSb700Init( PeiServices, Pci, StallPpi );
+ #endif
+
+ // Generic programming for all OHCI SB, should be called
+ // for all types of southbridges after platform-specific
+ // programming has been done.
+ if (!EFI_ERROR(Status)){
+ Status = DefaultInit( PeiServices, Pci, StallPpi );
+ }
+
+ // PCI root bridge programming is done.
+ // At this stage the OHCI controller should be visible and
+ // Memory mapped IO space should be visible
+
+ 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