mirror of https://github.com/acidanthera/audk.git
450 lines
12 KiB
C
450 lines
12 KiB
C
|
/** @file
|
||
|
Essential platform configuration.
|
||
|
|
||
|
Copyright (c) 2013 Intel Corporation.
|
||
|
|
||
|
This program and the accompanying materials
|
||
|
are licensed and made available under the terms and conditions of the BSD License
|
||
|
which accompanies this distribution. The full text of the license may be found at
|
||
|
http://opensource.org/licenses/bsd-license.php
|
||
|
|
||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||
|
|
||
|
|
||
|
**/
|
||
|
|
||
|
#include "PlatformInitDxe.h"
|
||
|
|
||
|
//
|
||
|
// The protocols, PPI and GUID defintions for this module
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// The Library classes this module consumes
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
|
||
|
// Workaround to make default SMRAM UnCachable
|
||
|
//
|
||
|
#define SMM_DEFAULT_SMBASE 0x30000 // Default SMBASE address
|
||
|
#define SMM_DEFAULT_SMBASE_SIZE_BYTES 0x10000 // Size in bytes of default SMRAM
|
||
|
|
||
|
BOOLEAN mMemCfgDone = FALSE;
|
||
|
UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
|
||
|
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
PlatformInitializeUart0MuxGalileo (
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This is the routine to initialize UART0 for DBG2 support. The hardware used in this process is a
|
||
|
Legacy Bridge (Legacy GPIO), I2C controller, a bi-directional MUX and a Cypress CY8C9540A chip.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress;
|
||
|
UINTN Length;
|
||
|
UINT8 Buffer[2];
|
||
|
|
||
|
if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
|
||
|
I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
|
||
|
} else {
|
||
|
I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set GPIO_SUS<2> as an output, raise voltage to Vdd.
|
||
|
//
|
||
|
PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, 2, TRUE);
|
||
|
|
||
|
//
|
||
|
// Select Port 3
|
||
|
//
|
||
|
Length = 2;
|
||
|
Buffer[0] = 0x18; //sub-address
|
||
|
Buffer[1] = 0x03; //data
|
||
|
|
||
|
Status = I2cWriteMultipleByte (
|
||
|
I2CSlaveAddress,
|
||
|
EfiI2CSevenBitAddrMode,
|
||
|
&Length,
|
||
|
&Buffer
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
//
|
||
|
// Set "Pin Direction" bit4 and bit5 as outputs
|
||
|
//
|
||
|
Length = 2;
|
||
|
Buffer[0] = 0x1C; //sub-address
|
||
|
Buffer[1] = 0xCF; //data
|
||
|
|
||
|
Status = I2cWriteMultipleByte (
|
||
|
I2CSlaveAddress,
|
||
|
EfiI2CSevenBitAddrMode,
|
||
|
&Length,
|
||
|
&Buffer
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
//
|
||
|
// Lower GPORT3 bit4 and bit5 to Vss
|
||
|
//
|
||
|
Length = 2;
|
||
|
Buffer[0] = 0x0B; //sub-address
|
||
|
Buffer[1] = 0xCF; //data
|
||
|
|
||
|
Status = I2cWriteMultipleByte (
|
||
|
I2CSlaveAddress,
|
||
|
EfiI2CSevenBitAddrMode,
|
||
|
&Length,
|
||
|
&Buffer
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
PlatformInitializeUart0MuxGalileoGen2 (
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This is the routine to initialize UART0 on GalileoGen2. The hardware used in this process is
|
||
|
I2C controller and the configuring the following IO Expander signal.
|
||
|
|
||
|
EXP1.P1_5 should be configured as an output & driven high.
|
||
|
EXP1.P0_0 should be configured as an output & driven high.
|
||
|
EXP0.P1_4 should be configured as an output, driven low.
|
||
|
EXP1.P0_1 pullup should be disabled.
|
||
|
EXP0.P1_5 Pullup should be disabled.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
None.
|
||
|
|
||
|
Returns:
|
||
|
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
//
|
||
|
// EXP1.P1_5 should be configured as an output & driven high.
|
||
|
//
|
||
|
PlatformPcal9555GpioSetDir (
|
||
|
GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
|
||
|
13, // P1-5.
|
||
|
TRUE
|
||
|
);
|
||
|
PlatformPcal9555GpioSetLevel (
|
||
|
GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
|
||
|
13, // P1-5.
|
||
|
TRUE
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// EXP1.P0_0 should be configured as an output & driven high.
|
||
|
//
|
||
|
PlatformPcal9555GpioSetDir (
|
||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
|
||
|
0, // P0_0.
|
||
|
TRUE
|
||
|
);
|
||
|
PlatformPcal9555GpioSetLevel (
|
||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
|
||
|
0, // P0_0.
|
||
|
TRUE
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// EXP0.P1_4 should be configured as an output, driven low.
|
||
|
//
|
||
|
PlatformPcal9555GpioSetDir (
|
||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
|
||
|
12, // P1-4.
|
||
|
FALSE
|
||
|
);
|
||
|
PlatformPcal9555GpioSetLevel ( // IO Expander 0.
|
||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // P1-4
|
||
|
12,
|
||
|
FALSE
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// EXP1.P0_1 pullup should be disabled.
|
||
|
//
|
||
|
PlatformPcal9555GpioDisablePull (
|
||
|
GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
|
||
|
1 // P0-1.
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// EXP0.P1_5 Pullup should be disabled.
|
||
|
//
|
||
|
PlatformPcal9555GpioDisablePull (
|
||
|
GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
|
||
|
13 // P1-5.
|
||
|
);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
PlatformConfigOnSmmConfigurationProtocol (
|
||
|
IN EFI_EVENT Event,
|
||
|
IN VOID *Context
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Function runs in PI-DXE to perform platform specific config when
|
||
|
SmmConfigurationProtocol is installed.
|
||
|
|
||
|
Arguments:
|
||
|
Event - The event that occured.
|
||
|
Context - For EFI compatiblity. Not used.
|
||
|
|
||
|
Returns:
|
||
|
None.
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
UINT32 NewValue;
|
||
|
UINT64 BaseAddress;
|
||
|
UINT64 SmramLength;
|
||
|
VOID *SmmCfgProt;
|
||
|
|
||
|
Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt);
|
||
|
if (Status != EFI_SUCCESS){
|
||
|
DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n"));
|
||
|
return;
|
||
|
}
|
||
|
if (mMemCfgDone) {
|
||
|
DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n"));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Disable eSram block (this will also clear/zero eSRAM)
|
||
|
// We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase
|
||
|
//
|
||
|
NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK);
|
||
|
NewValue |= BLOCK_DISABLE_PG;
|
||
|
QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue);
|
||
|
|
||
|
//
|
||
|
// Update HMBOUND to top of DDR3 memory and LOCK
|
||
|
// We disabled eSRAM so now we move HMBOUND down to top of DDR3
|
||
|
//
|
||
|
QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength);
|
||
|
NewValue = (UINT32)(BaseAddress + SmramLength);
|
||
|
DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue));
|
||
|
QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK));
|
||
|
|
||
|
//
|
||
|
// Lock IMR5 now that HMBOUND is locked (legacy S3 region)
|
||
|
//
|
||
|
NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL);
|
||
|
NewValue |= IMR_LOCK;
|
||
|
QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
|
||
|
|
||
|
//
|
||
|
// Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved)
|
||
|
//
|
||
|
NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL);
|
||
|
NewValue |= IMR_LOCK;
|
||
|
QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
|
||
|
|
||
|
//
|
||
|
// Disable IMR2 memory protection (RMU Main Binary)
|
||
|
//
|
||
|
QncImrWrite (
|
||
|
QUARK_NC_MEMORY_MANAGER_IMR2,
|
||
|
(UINT32)(IMRL_RESET & ~IMR_EN),
|
||
|
(UINT32)IMRH_RESET,
|
||
|
(UINT32)IMRX_ALL_ACCESS,
|
||
|
(UINT32)IMRX_ALL_ACCESS
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Disable IMR3 memory protection (Default SMRAM)
|
||
|
//
|
||
|
QncImrWrite (
|
||
|
QUARK_NC_MEMORY_MANAGER_IMR3,
|
||
|
(UINT32)(IMRL_RESET & ~IMR_EN),
|
||
|
(UINT32)IMRH_RESET,
|
||
|
(UINT32)IMRX_ALL_ACCESS,
|
||
|
(UINT32)IMRX_ALL_ACCESS
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Disable IMR4 memory protection (eSRAM).
|
||
|
//
|
||
|
QncImrWrite (
|
||
|
QUARK_NC_MEMORY_MANAGER_IMR4,
|
||
|
(UINT32)(IMRL_RESET & ~IMR_EN),
|
||
|
(UINT32)IMRH_RESET,
|
||
|
(UINT32)IMRX_ALL_ACCESS,
|
||
|
(UINT32)IMRX_ALL_ACCESS
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
|
||
|
// Workaround to make default SMRAM UnCachable
|
||
|
//
|
||
|
Status = gDS->SetMemorySpaceAttributes (
|
||
|
(EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE,
|
||
|
SMM_DEFAULT_SMBASE_SIZE_BYTES,
|
||
|
EFI_MEMORY_WB
|
||
|
);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
mMemCfgDone = TRUE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
PlatformConfigOnSpiReady (
|
||
|
IN EFI_EVENT Event,
|
||
|
IN VOID *Context
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Function runs in PI-DXE to perform platform specific config when SPI
|
||
|
interface is ready.
|
||
|
|
||
|
Arguments:
|
||
|
Event - The event that occured.
|
||
|
Context - For EFI compatiblity. Not used.
|
||
|
|
||
|
Returns:
|
||
|
None.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
VOID *SpiReadyProt = NULL;
|
||
|
EFI_PLATFORM_TYPE Type;
|
||
|
EFI_BOOT_MODE BootMode;
|
||
|
|
||
|
BootMode = GetBootModeHob ();
|
||
|
|
||
|
Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt);
|
||
|
if (Status != EFI_SUCCESS){
|
||
|
DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n"));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Lock regions SPI flash.
|
||
|
//
|
||
|
PlatformFlashLockPolicy (FALSE);
|
||
|
|
||
|
//
|
||
|
// Configurations and checks to be done when DXE tracing available.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Platform specific Signal routing.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Skip any signal not needed for recovery and flash update.
|
||
|
//
|
||
|
if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) {
|
||
|
|
||
|
//
|
||
|
// Galileo Platform UART0 support.
|
||
|
//
|
||
|
Type = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
|
||
|
if (Type == Galileo) {
|
||
|
//
|
||
|
// Use MUX to connect out UART0 pins.
|
||
|
//
|
||
|
PlatformInitializeUart0MuxGalileo ();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// GalileoGen2 Platform UART0 support.
|
||
|
//
|
||
|
if (Type == GalileoGen2) {
|
||
|
//
|
||
|
// Use route out UART0 pins.
|
||
|
//
|
||
|
PlatformInitializeUart0MuxGalileoGen2 ();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
CreateConfigEvents (
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Arguments:
|
||
|
None
|
||
|
|
||
|
Returns:
|
||
|
EFI_STATUS
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
EFI_EVENT EventSmmCfg;
|
||
|
EFI_EVENT EventSpiReady;
|
||
|
VOID *RegistrationSmmCfg;
|
||
|
VOID *RegistrationSpiReady;
|
||
|
|
||
|
//
|
||
|
// Schedule callback for when SmmConfigurationProtocol installed.
|
||
|
//
|
||
|
EventSmmCfg = EfiCreateProtocolNotifyEvent (
|
||
|
&gEfiSmmConfigurationProtocolGuid,
|
||
|
TPL_CALLBACK,
|
||
|
PlatformConfigOnSmmConfigurationProtocol,
|
||
|
NULL,
|
||
|
&RegistrationSmmCfg
|
||
|
);
|
||
|
ASSERT (EventSmmCfg != NULL);
|
||
|
|
||
|
//
|
||
|
// Schedule callback to setup SPI Flash Policy when SPI interface ready.
|
||
|
//
|
||
|
EventSpiReady = EfiCreateProtocolNotifyEvent (
|
||
|
&gEfiSmmSpiReadyProtocolGuid,
|
||
|
TPL_CALLBACK,
|
||
|
PlatformConfigOnSpiReady,
|
||
|
NULL,
|
||
|
&RegistrationSpiReady
|
||
|
);
|
||
|
ASSERT (EventSpiReady != NULL);
|
||
|
return EFI_SUCCESS;
|
||
|
}
|