From e8dcae7734395a3d29bd4cc1f2f7cdcbe8b279ac Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 12:54:58 +0800 Subject: BroxtonSiPkg: Add ScInit Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScAcpi.c | 74 ++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScHda.c | 288 +++++++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.c | 907 +++++++++++++++++++++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.h | 267 ++++++ .../SouthCluster/ScInit/Dxe/ScInitDxe.inf | 104 +++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIosf.c | 35 + .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIsh.c | 53 ++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScLpss.c | 283 +++++++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScPmc.c | 108 +++ .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScSata.c | 18 + .../BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScXdci.c | 18 + .../SouthCluster/ScInit/Smm/ScInitSmm.c | 183 +++++ .../SouthCluster/ScInit/Smm/ScInitSmm.h | 320 ++++++++ .../SouthCluster/ScInit/Smm/ScInitSmm.inf | 81 ++ .../SouthCluster/ScInit/Smm/ScPcieSmm.c | 328 ++++++++ 15 files changed, 3067 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScAcpi.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScHda.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInitDxe.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIosf.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIsh.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScLpss.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScPmc.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScSata.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScXdci.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c (limited to 'Silicon') diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScAcpi.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScAcpi.c new file mode 100644 index 0000000000..b63a18b872 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScAcpi.c @@ -0,0 +1,74 @@ +/** @file + This is the driver that initializes the Intel SC devices + + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" + +/** + Update ASL object before Boot + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_STATUS + @retval EFI_NOT_READY The Acpi protocols are not ready. + +**/ +EFI_STATUS +UpdateNvsArea ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN RpDev; + UINTN RpFun; + UINT32 Data32; + EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; + BXT_SERIES BxtSeries; + UINT8 MaxPciePortNum; + SC_PCIE_CONFIG *PcieRpConfig; + + Status = GetConfigBlock ((VOID *) ScPolicy, &gPcieRpConfigGuid, (VOID *) &PcieRpConfig); + ASSERT_EFI_ERROR (Status); + + Status = EFI_SUCCESS; + Status = gBS->LocateProtocol ( + &gEfiGlobalNvsAreaProtocolGuid, + NULL, + (VOID **) &GlobalNvsArea + ); + ASSERT_EFI_ERROR (Status); + // + // Update ASL PCIE port address according to root port device and function + // + BxtSeries = GetBxtSeries (); + if ((BxtSeries == BxtP) || (BxtSeries == Bxt1)) { + MaxPciePortNum = GetScMaxPciePortNum (); + for (Index = 0; Index < MaxPciePortNum; Index++) { + Status = GetScPcieRpDevFun (Index, &RpDev, &RpFun); + ASSERT_EFI_ERROR (Status); + + Data32 = ((UINT8) RpDev << 16) | (UINT8) RpFun; + GlobalNvsArea->Area->RpAddress[Index] = Data32; + // + // Update Maximum Snoop Latency and Maximum No-Snoop Latency values for PCIE + // + GlobalNvsArea->Area->PcieLtrMaxSnoopLatency[Index] = PcieRpConfig->RootPort[Index].LtrMaxSnoopLatency; + GlobalNvsArea->Area->PcieLtrMaxNoSnoopLatency[Index] = PcieRpConfig->RootPort[Index].LtrMaxNoSnoopLatency; + } + } + + return Status; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScHda.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScHda.c new file mode 100644 index 0000000000..16efcbe859 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScHda.c @@ -0,0 +1,288 @@ +/** @file + Initializes the HD-Audio Controller and Codec. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" +#include +#include +#include +#include +#include + +SC_HDA_NHLT_ENDPOINTS mScHdaNhltEndpoints[HdaEndpointMax] = +{ + {HdaDmicX2, FALSE}, + {HdaDmicX4, FALSE}, + {HdaBtRender, FALSE}, + {HdaBtCapture, FALSE}, + {HdaI2sRenderSKP, FALSE}, + {HdaI2sCaptureSKP, FALSE}, + {HdaI2sRenderHP, FALSE}, + {HdaI2sCaptureHP, FALSE}, + {HdaModem1Render, FALSE}, + {HdaModem1Capture, FALSE}, + {HdaModem2Render, FALSE}, + {HdaModem2Capture, FALSE} +}; + + +/** + Retrieves address of NHLT table from XSDT/RSDT. + + @retval NHLT_ACPI_TABLE* Pointer to NHLT table if found + @retval NULL NHLT could not be found + +**/ +NHLT_ACPI_TABLE * +LocateNhltAcpiTable ( + VOID + ) +{ + EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt; + NHLT_ACPI_TABLE *Nhlt; + UINTN Index; + UINT32 Data32; + EFI_STATUS Status; + Rsdp = NULL; + Xsdt = NULL; + Nhlt = NULL; + + // + // Find the AcpiSupport protocol returns RSDP (or RSD PTR) address. + // + DEBUG ((DEBUG_INFO, "LocateNhltAcpiTable () Start\n")); + + Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID *) &Rsdp); + if (EFI_ERROR (Status) || (Rsdp == NULL)) { + DEBUG ((DEBUG_ERROR, "EFI_ERROR or Rsdp == NULL\n")); + return NULL; + } + + Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress; + if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { + // + // If XSDT has not been found, check RSDT + // + Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress; + if (Xsdt == NULL || Xsdt->Signature != EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "XSDT/RSDT == NULL or wrong signature\n")); + return NULL; + } + } + + for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Xsdt->Length; Index = Index + sizeof (UINT32)) { + Data32 = *(UINT32 *) ((UINT8 *) Xsdt + Index); + Nhlt = (NHLT_ACPI_TABLE *) (UINT32 *) (UINTN) Data32; + if (Nhlt->Header.Signature == NHLT_ACPI_TABLE_SIGNATURE) { + break; + } + } + + if (Nhlt == NULL || Nhlt->Header.Signature != NHLT_ACPI_TABLE_SIGNATURE) { + DEBUG ((DEBUG_ERROR, "Nhlt == NULL or wrong signature\n")); + return NULL; + } + + DEBUG ((DEBUG_INFO, "Found NhltTable, Address = 0x%x\n", Nhlt)); + + return Nhlt; +} + + +/** + Constructs and installs NHLT table. + + @retval EFI_SUCCESS ACPI Table installed successfully + @retval EFI_UNSUPPORTED ACPI Table protocol not found + +**/ +EFI_STATUS +PublishNhltAcpiTable ( + VOID + ) +{ + UINTN AcpiTableKey; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + NHLT_ACPI_TABLE *NhltTable; + UINT32 TableLength; + EFI_STATUS Status; + + AcpiTable = NULL; + NhltTable = NULL; + AcpiTableKey = 0; + + DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() Start\n")); + + // + // Locate ACPI support protocol + // + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable); + if (EFI_ERROR (Status) || AcpiTable == NULL) { + return EFI_UNSUPPORTED; + } + + NhltConstructor (mScHdaNhltEndpoints, &NhltTable, &TableLength); + NhltAcpiHeaderConstructor (NhltTable, TableLength); + + Status = AcpiTable->InstallAcpiTable (AcpiTable, NhltTable, NhltTable->Header.Length, &AcpiTableKey); + + DEBUG ((DEBUG_INFO, "PublishNhltAcpiTable() End\n")); + return Status; +} + + +/** + Sets NVS ACPI variables for _DSM accordingly to policy. + + @param[in] NhltAcpiTableAddress NHLT ACPI Table address + @param[in] NhltAcpiTableLength NHLT ACPI Table length + @param[in] DspFeatureMask Dsp feature mask + @param[in] DspPpModuleMask Dsp post process module mask + +**/ +VOID +UpdateHdaAcpiData ( + IN UINT32 NhltAcpiTableAddress, + IN UINT32 NhltAcpiTableLength, + IN UINT32 DspFeatureMask, + IN UINT32 DspPpModuleMask + ) +{ + EFI_STATUS Status; + EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; + + Status = gBS->LocateProtocol ( + &gEfiGlobalNvsAreaProtocolGuid, + NULL, + (VOID **) &GlobalNvsArea + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "UpdateHdaAcpiData():\n NHLT Address = 0x%08x, Length = 0x%08x\n", NhltAcpiTableAddress, NhltAcpiTableLength)); + DEBUG ((DEBUG_INFO, " FeatureMask = 0x%08x\n PostProcessingModuleMask = 0x%08x\n", DspFeatureMask, DspPpModuleMask)); + + GlobalNvsArea->Area->HdaNhltAcpiAddr = NhltAcpiTableAddress; + GlobalNvsArea->Area->HdaNhltAcpiLength = NhltAcpiTableLength; + GlobalNvsArea->Area->HdaDspFeatureMask = DspFeatureMask; + GlobalNvsArea->Area->HdaDspModMask = DspPpModuleMask; +} + + +/** + Initialize and publish NHLT (Non-HDA Link Table), update NVS variables. + + @param[in] *HdaConfig Pointer to SC_HDAUDIO_CONFIG + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED No NHLT ACPI Table available + +**/ +EFI_STATUS +SetHdaAcpiTable ( + IN CONST SC_HDAUDIO_CONFIG *HdaConfig + ) +{ + NHLT_ACPI_TABLE *NhltTable; + EFI_STATUS Status; + NhltTable = NULL; + + // + // DMIC X2 + // + switch (HdaConfig->DspEndpointDmic) { + case ScHdaDmic2chArray: + mScHdaNhltEndpoints[HdaDmicX2].Enable = TRUE; + break; + + case ScHdaDmic4chArray: + mScHdaNhltEndpoints[HdaDmicX4].Enable = TRUE; + break; + + case ScHdaDmicDisabled: + default: + mScHdaNhltEndpoints[HdaDmicX2].Enable = FALSE; + mScHdaNhltEndpoints[HdaDmicX4].Enable = FALSE; + } + + if (HdaConfig->DspEndpointBluetooth) { + mScHdaNhltEndpoints[HdaBtRender].Enable = TRUE; + mScHdaNhltEndpoints[HdaBtCapture].Enable = TRUE; + } + + if (HdaConfig->DspEndpointI2sSkp) { + mScHdaNhltEndpoints[HdaI2sRenderSKP].Enable = TRUE; + mScHdaNhltEndpoints[HdaI2sCaptureSKP].Enable = TRUE; + } + + if (HdaConfig->DspEndpointI2sHp) { + mScHdaNhltEndpoints[HdaI2sRenderHP].Enable = TRUE; + mScHdaNhltEndpoints[HdaI2sCaptureHP].Enable = TRUE; + } + + Status = PublishNhltAcpiTable (); + NhltTable = LocateNhltAcpiTable (); + if (NhltTable == NULL) { + return EFI_LOAD_ERROR; + } + + UpdateHdaAcpiData ((UINT32) (UINTN) NhltTable, (UINT32) (NhltTable->Header.Length), HdaConfig->DspFeatureMask, HdaConfig->DspPpModuleMask); + + NhltAcpiTableDump (NhltTable); + return Status; +} + + +/** + Hide PCI config space of HD-Audio device and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Device non-exist or Dsp is disabled + +**/ +EFI_STATUS +ConfigureHdaAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + EFI_STATUS Status; + UINTN HdaPciBase; + SC_HDAUDIO_CONFIG *HdaConfig; + + DEBUG ((DEBUG_INFO, "ConfigureHdaAtBoot() Start\n")); + Status = GetConfigBlock ((VOID *) ScPolicy, &gHdAudioConfigGuid, (VOID *) &HdaConfig); + ASSERT_EFI_ERROR (Status); + + HdaPciBase = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_HDA, + PCI_FUNCTION_NUMBER_HDA + ); + + if ((MmioRead32 (HdaPciBase) == 0xFFFFFFFF) || (HdaConfig->DspEnable == FALSE)) { + // + // Do not set ACPI tables if HD-Audio or audio DSP is function disabled. + // + DEBUG ((DEBUG_INFO, "HD-Audio ACPI table is not set!\n")); + + return EFI_UNSUPPORTED; + } + Status = SetHdaAcpiTable (HdaConfig); + DEBUG ((DEBUG_INFO, "ConfigureHdaAtBoot() End\n")); + + return Status; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.c new file mode 100644 index 0000000000..6fb6c8df48 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.c @@ -0,0 +1,907 @@ +/** @file + This is the driver that initializes the Intel SC devices + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FUNC_ACPI_ENUM_1 0x74 + +// +// Global Variables +// +EFI_HANDLE mImageHandle; +GLOBAL_REMOVE_IF_UNREFERENCED SC_POLICY_HOB *mScPolicy; + +/** + SC initialization before booting to OS + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScOnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + BXT_SERIES BxtSeries; + SC_LOCK_DOWN_CONFIG *LockDownConfig; + + DEBUG ((DEBUG_INFO, "ScOnReadyToBoot() Start\n")); + + if (Event != NULL) { + gBS->CloseEvent (Event); + } + + BxtSeries = GetBxtSeries (); + Status = GetConfigBlock ((VOID *) mScPolicy, &gLockDownConfigGuid, (VOID *) &LockDownConfig); + ASSERT_EFI_ERROR (Status); + + // + // Trigger an SW SMI to config PCIE power management setting after PCI enumeration is done + // + if (BxtSeries == BxtP || (BxtSeries == Bxt1)) { + IoWrite8 (R_APM_CNT, SW_SMI_PCIE_ASPM_OVERRIDE); + } + + // + // Trigger an SW SMI to do BiosWriteProtect + // + if ((BxtSeries == BxtP) && (LockDownConfig->BiosLock == TRUE)) { + IoWrite8 (R_APM_CNT, (UINT8) LockDownConfig->BiosLockSwSmiNumber); + } + DEBUG ((DEBUG_INFO, "ScOnReadyToBoot() End\n")); +} + + +/** + This is the callback function for PCI Enumeration Complete. + +**/ +VOID +EFIAPI +ScOnPciEnumComplete ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + VOID *ProtocolPointer; + UINT8 Reset; + EFI_PEI_HOB_POINTERS HobPtr; + SC_PMC_FUNCTION_DISABLE_RESET_HOB *FuncDisHob; + EFI_HOB_GUID_TYPE *FdoEnabledGuidHob = NULL; + + DEBUG ((DEBUG_INFO, "ScOnPciEnumComplete ()\n")); + + // + // Check if this is first time called by EfiCreateProtocolNotifyEvent() or not, + // if it is, we will skip it until real event is triggered + // + Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer); + if (EFI_SUCCESS != Status) { + return; + } + gBS->CloseEvent (Event); + + // + // Get SC PMC fuction disable reset HOB. + // + HobPtr.Guid = GetFirstGuidHob (&gScPmcFunctionDisableResetHobGuid); + if (HobPtr.Guid != NULL) { + FuncDisHob = GET_GUID_HOB_DATA (HobPtr.Guid); + // + // CSE status. When CSE is in recovery mode. CSE convert the cold reset to the Global reset + // so function disable register is not preserved + // + FdoEnabledGuidHob = GetFirstGuidHob (&gFdoModeEnabledHobGuid); + if (FdoEnabledGuidHob == NULL) { + // + // Do not change the order of Global reset and Cold reset. + // Global reset clears the PMC function disable register. + // If done after cold reset, it will end up in a dead loop. + // + if (FuncDisHob->ResetType == SC_PMC_FUNCTION_DISABLE_GLOBAL_RESET) { + DEBUG ((DEBUG_INFO, "PMC function disable updated, do global reset. \n")); + HeciSendResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET); + CpuDeadLoop(); // Should not continue execution after global reset + } + if (FuncDisHob->ResetType == SC_PMC_FUNCTION_DISABLE_COLD_RESET) { + DEBUG ((DEBUG_INFO, "PMC function disable updated, do cold reset. \n")); + Reset = IoRead8 (R_RST_CNT); + Reset &= 0xF1; + Reset |= 0xE; + IoWrite8 (R_RST_CNT, Reset); + CpuDeadLoop (); // Should not continue execution after cold reset + } + } + } + return; +} + + +/** + Register EndOfDXE, ReadyToBoot, ExitBootService event functions + for SC configuration in different stages + +**/ +VOID +ScRegisterNotifications ( + VOID + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBoot; + EFI_EVENT LegacyBootEvent; + EFI_EVENT ExitBootServicesEvent; + VOID *Registration; + + // + // Create PCI Enumeration Completed callback + // + EfiCreateProtocolNotifyEvent ( + &gEfiPciEnumerationCompleteProtocolGuid, + TPL_CALLBACK, + ScOnPciEnumComplete, + NULL, + &Registration + ); + + // + // Register an end of DXE event for PCH to do tasks before invoking any UEFI drivers, + // applications, or connecting consoles,... + // + // + // Create an ExitPmAuth protocol call back event. + // + EfiCreateProtocolNotifyEvent ( + &gExitPmAuthProtocolGuid, + TPL_CALLBACK, + ScOnEndOfDxe, + NULL, + &Registration + ); + + // + // Register a Ready to boot event to config PCIE power management setting after OPROM executed + // + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + ScOnReadyToBoot, + NULL, + &ReadyToBoot + ); + ASSERT_EFI_ERROR (Status); + + // + // Create events for SC to do the task before ExitBootServices/LegacyBoot. + // It is guaranteed that only one of two events below will be signalled + // + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, + ScExitBootServicesEvent, + NULL, + &ExitBootServicesEvent + ); + Status = gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + ScLpssExitBootServicesEvent, + NULL, + &ExitBootServicesEvent + ); + + ASSERT_EFI_ERROR (Status); + + Status = EfiCreateEventLegacyBootEx ( + TPL_CALLBACK, + ScExitBootServicesEvent, + NULL, + &LegacyBootEvent + ); + Status = EfiCreateEventLegacyBootEx ( + TPL_NOTIFY, + ScLpssExitBootServicesEvent, + NULL, + &LegacyBootEvent + ); + ASSERT_EFI_ERROR (Status); +} + + +/** + South cluster initialization entry point + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +EFIAPI +ScInitEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + UINT32 PmcBase; + EFI_PEI_HOB_POINTERS HobPtr; + SC_INSTANCE_PRIVATE_DATA *ScInstance; + UINT16 AcpiBaseAddr; + EFI_HANDLE Handle; + + DEBUG ((DEBUG_INFO, "ScInitEntryPoint() Start\n")); + + ScInstance = NULL; + mScPolicy = NULL; + AcpiBaseAddr = 0; + + Handle = NULL; + mImageHandle = ImageHandle; + + // + // Get SC Policy HOB. + // + Status = EFI_NOT_FOUND; + HobPtr.Guid = GetFirstGuidHob (&gScPolicyHobGuid); + ASSERT (HobPtr.Guid != NULL); + mScPolicy = GET_GUID_HOB_DATA (HobPtr.Guid); + + // + // Allocate and install the SC Info protocol + // + PmcBase = PMC_BASE_ADDRESS; + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + DEBUG ((DEBUG_INFO, "SC Base Addresses:\n-------------------\n")); + DEBUG ((DEBUG_INFO, " PmcBase 0x%X\n", PmcBase)); + DEBUG ((DEBUG_INFO, " AcpiBase 0x%X\n", AcpiBaseAddr)); + DEBUG ((DEBUG_INFO, "-------------------\n")); + ASSERT (PmcBase != 0); + ASSERT (AcpiBaseAddr != 0); + DEBUG ((DEBUG_INFO, "SC Base Addresses:\n----START---------------\n")); + DEBUG ((DEBUG_INFO, " AcpiBase 0x%X\n", AcpiBaseAddr)); +#if (ENBDT_PF_ENABLE == 1) + DEBUG ((DEBUG_INFO, "CAUTION Broxton P ACPI offsets\n")); +#else + DEBUG ((DEBUG_INFO, "Broxton M ACPI offsets\n")); +#endif + DEBUG ((DEBUG_INFO, " PM1_STS_EN 0x%X 0x%X\n", R_ACPI_PM1_STS, IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_PM1_STS))));; + DEBUG ((DEBUG_INFO, " PM1_CNT 0x%X 0x%X\n", R_ACPI_PM1_CNT, IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_PM1_CNT))));; + DEBUG ((DEBUG_INFO, " PM1_TMR 0x%X 0x%X\n", R_ACPI_PM1_TMR, IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_PM1_TMR))));; + DEBUG ((DEBUG_INFO, " GPE0a_STS 0x%X 0x%X\n", R_ACPI_GPE0a_STS, IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_GPE0a_STS))));; + DEBUG ((DEBUG_INFO, " GPE0a_EN 0x%X 0x%X\n", R_ACPI_GPE0a_EN, IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_GPE0a_EN))));; + DEBUG ((DEBUG_INFO, " SMI_EN 0x%X 0x%X\n", R_SMI_EN, IoRead32 ((UINTN) (AcpiBaseAddr + R_SMI_EN))));; + DEBUG ((DEBUG_INFO, " SMI_STS 0x%X 0x%X\n", R_SMI_STS, IoRead32 ((UINTN) (AcpiBaseAddr + R_SMI_STS))));; + DEBUG ((DEBUG_INFO, " GPE_CTRL 0x%X 0x%X\n", R_ACPI_GPE_CNTL, IoRead32 ((UINTN) (AcpiBaseAddr + R_ACPI_GPE_CNTL))));; + DEBUG ((DEBUG_INFO, " TCO_RLD 0x%X 0x%X\n", R_TCO_RLD, IoRead32 ((UINTN) (AcpiBaseAddr + R_TCO_RLD))));; + DEBUG ((DEBUG_INFO, " TCO_STS 0x%X 0x%X\n", R_TCO_STS, IoRead32 ((UINTN) (AcpiBaseAddr + R_TCO_STS))));; + DEBUG ((DEBUG_INFO, " TCO1_CNT 0x%X 0x%X\n", R_TCO_CNT, IoRead32 ((UINTN) (AcpiBaseAddr + R_TCO_CNT))));; + DEBUG ((DEBUG_INFO, " TCO_TMR 0x%X 0x%X\n", R_TCO_TMR, IoRead32 ((UINTN) (AcpiBaseAddr + R_TCO_TMR))));; + DEBUG ((DEBUG_INFO, "SC Base Addresses:\n----END---------------\n")); + + // + // Initialize the SC device + // + InitializeScDevice (ScInstance, mScPolicy, PmcBase, AcpiBaseAddr); + + ScRegisterNotifications (); + + ScInstance = AllocateZeroPool (sizeof (SC_INSTANCE_PRIVATE_DATA)); + if (ScInstance == NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + ScInstance->ScInfo.Revision = INFO_PROTOCOL_REVISION_1; + ScInstance->ScInfo.BusNumber = DEFAULT_PCI_BUS_NUMBER_SC; + ScInstance->ScInfo.RCVersion = SC_POLICY_REVISION; + + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiInfoProtocolGuid, + EFI_NATIVE_INTERFACE, + &(ScInstance->ScInfo) + ); + + DEBUG ((DEBUG_INFO, "ScInitEntryPoint() End\n")); + + return EFI_SUCCESS; +} + + +/** + Initialize the SC device according to the SC Platform Policy + + @param[in, out] ScInstance SC instance private data. May get updated by this function + @param[in] ScPolicy The SC Platform Policy protocol instance + @param[in] PmcBase PMC base address of this SC device + @param[in] AcpiBaseAddr ACPI IO base address of this SC device + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +InitializeScDevice ( + IN OUT SC_INSTANCE_PRIVATE_DATA *ScInstance, + IN SC_POLICY_HOB *ScPolicy, + IN UINT32 PmcBase, + IN UINT16 AcpiBaseAddr + ) +{ + EFI_STATUS Status; + UINT32 FuncDisableReg; + BXT_SERIES BxtSeries; + + DEBUG ((DEBUG_INFO, "InitializeScDevice() Start\n")); + FuncDisableReg = MmioRead32 (PmcBase + R_PMC_FUNC_DIS); + BxtSeries = GetBxtSeries (); + + // + // VT-d Initialization + // + DEBUG ((DEBUG_INFO, "Initializing VT-d in Dxe to update DMAR table\n")); + VtdInit (); + + // + // Configure PMC Devices + // + Status = ConfigurePmcAfterPciEnum (ScPolicy); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "InitializeScDevice() End\n")); + + return Status; +} + + +/** + Program Sc devices dedicated IRQ#. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigureIrqAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + UINTN Index; + UINTN TblIndex; + UINTN Segment; + UINTN BusNum; + UINTN DevNum; + UINTN FunNum; + UINTN HandleCount; + EFI_STATUS Status; + EFI_HANDLE *Handles; + EFI_PCI_IO_PROTOCOL *PciIo; + STATIC SC_IRQ_INIT_ENTRY IrqInitTable[] = { + // + // Bus Dev Fun Irq + // + {0, 0, 1, 24}, // PUINT + {0, 0, 3, 23}, // gmm + {0, 3, 0, 21}, // iunit + + + {0, 0xE, 0, 25}, // HD-Audio + + {0, 0x11, 0, 26}, // ISH + + {0, 0x15, 0, 17}, // XHCI + {0, 0x15, 1, 13}, // xDCI + + {0, 0x16, 0, 27}, // I2C1 + {0, 0x16, 1, 28}, // I2C2 + {0, 0x16, 2, 29}, // I2C3 + {0, 0x16, 3, 30}, // I2C4 + + {0, 0x17, 0, 31}, // I2C5 + {0, 0x17, 1, 32}, // I2C6 + {0, 0x17, 2, 33}, // I2C7 + {0, 0x17, 3, 34}, // I2C8 + + {0, 0x18, 0, 4}, // UART1 + {0, 0x18, 1, 5}, // UART2 + {0, 0x18, 2, 6}, // UART3 + {0, 0x18, 3, 7}, // UART4 + + {0, 0x19, 0, 35}, // SPI1 + {0, 0x19, 1, 36}, // SPI2 + {0, 0x19, 2, 37}, // SPI3 + + {0, 0x1B, 0, 3 }, // SDCard + {0, 0x1C, 0, 39 }, // eMMC + {0, 0x1D, 0, 38 }, // UFS + {0, 0x1E, 0, 42 }, // SDIO + }; + + DEBUG ((EFI_D_INFO, "ConfigureIrqAtBoot() Start\n")); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &HandleCount, + &Handles + ); + + DEBUG ((EFI_D_INFO, "Status = %r\n", Status)); + + if (EFI_ERROR (Status)) { + return Status; + } + + for(Index = 0; Index < HandleCount; Index ++) { + Status = gBS->HandleProtocol ( + Handles[Index], + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo + ); + + if (EFI_ERROR(Status)) { + continue; + } + + Status = PciIo->GetLocation( + PciIo, + &Segment, + &BusNum, + &DevNum, + &FunNum + ); + + for (TblIndex = 0; TblIndex < (sizeof (IrqInitTable) / sizeof (SC_IRQ_INIT_ENTRY)); TblIndex++) { + if ((BusNum == IrqInitTable[TblIndex].BusNumber) && + (DevNum == IrqInitTable[TblIndex].DeviceNumber) && + (FunNum == IrqInitTable[TblIndex].FunctionNumber)) { + + Status = PciIo->Pci.Write( + PciIo, + EfiPciIoWidthUint8, + 0x3c, //Offset 0x3c :PCI Interrupt Line + 1, + &IrqInitTable[TblIndex].Irq + ); + + DEBUG ((EFI_D_INFO, "Writing IRQ#%d for B%d/D%d/F%d\n", IrqInitTable[TblIndex].Irq, BusNum, DevNum, FunNum)); + } else { + continue; + } + + } + + } + + DEBUG ((EFI_D_INFO, "ConfigureIrqAtBoot() End\n")); + return EFI_SUCCESS; +} + + +/** + SC initialization triggered by ExitBootServices events + Useful for operations which must happen later than at the end of post + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN P2SBBase; + UINT32 Buffer9; + BXT_SERIES BxtSeries; + + Buffer9 = 0; + BxtSeries = GetBxtSeries (); + + // + // Closed the event to avoid call twice + // + gBS->CloseEvent (Event); + + UpdateNvsArea (mScPolicy); + ConfigureHdaAtBoot (mScPolicy); + + ConfigureIrqAtBoot (mScPolicy); + StopLpssAtBoot (); + + if (BxtSeries != BxtP) { + SideBandAndThenOr32( + 0xC6, + 0x2338, + 0xFFFFFFFF, + BIT0 + ); + } + + // + // Hide P2SB device in OS phase + // + DEBUG ((DEBUG_INFO, "Hide P2SB on normal mode..........\n")); + P2SBBase = MmPciAddress ( + 0, + 0, + PCI_DEVICE_NUMBER_P2SB, + PCI_FUNCTION_NUMBER_P2SB, + R_P2SB_P2SBC + ); + MmioOr32 (P2SBBase, B_P2SB_P2SBC_HIDE); + + // + // Set the P2SB bit in FUNC_ACPI_ENUM_1. + // + Buffer9 = MmioRead32 (GCR_BASE_ADDRESS + FUNC_ACPI_ENUM_1); + Buffer9 = Buffer9 | BIT0; + MmioWrite32 (GCR_BASE_ADDRESS + FUNC_ACPI_ENUM_1, Buffer9); + + return; +} + + +/** + SC initialization triggered by ExitBootServices for LPSS events + This should be at a higher TPL than the callback that sets Untrusted Mode. + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScLpssExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // + // Closed the event to avoid call twice + // + gBS->CloseEvent (Event); + + ConfigureLpssAtBoot (mScPolicy); +} + + +/** + SC initialization before Boot Script Table is closed + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScOnEndOfDxe ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT32 FuncDisableReg; + UINT32 Data32; + UINT32 Data32And; + UINT32 Data32Or; + UINT16 AcpiBaseAddr; + UINT32 PmcBase; + UINT8 NumOfDevltrOverride; + UINT32 DlockValue; + UINTN PciLpcRegBase; + UINTN PciSpiRegBase; + UINTN SpiBar0; + BXT_SERIES BxtSeries; + UINT8 Data8; + SC_LOCK_DOWN_CONFIG *LockDownConfig; + SC_FLASH_PROTECTION_CONFIG *FlashProtectionConfig; + UINT16 Data16And; + UINT16 Data16Or; + SI_POLICY_HOB *SiPolicyHob; + EFI_PEI_HOB_POINTERS HobPtr; + + NumOfDevltrOverride = 0; + PciLpcRegBase = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC + ); + PciSpiRegBase = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_SPI, + PCI_FUNCTION_NUMBER_SPI + ); + + DEBUG ((DEBUG_INFO, "ScOnEndOfDxe() Start\n")); + + // + // Closed the event to avoid call twice when launch shell + // + gBS->CloseEvent (Event); + + BxtSeries = GetBxtSeries (); + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + PmcBase = PMC_BASE_ADDRESS; + FuncDisableReg = MmioRead32 (PmcBase + R_PMC_FUNC_DIS); + + MmioAnd32 ( + (UINTN) (PmcBase + R_PMC_PMIR), + (UINT32) ~(B_PMC_PMIR_CF9GR) + ); + S3BootScriptSaveMemWrite ( + EfiBootScriptWidthUint32, + (UINTN) (PmcBase + R_PMC_PMIR), + 1, + (VOID *) (UINTN) (PmcBase + R_PMC_PMIR) + ); + + if (BxtSeries == BxtP){ + SpiBar0 = MmioRead32 (PciSpiRegBase + R_SPI_BASE) & ~(B_SPI_BAR0_MASK); + Status = GetConfigBlock ((VOID *) mScPolicy, &gFlashProtectionConfigGuid, (VOID *) &FlashProtectionConfig); + ASSERT_EFI_ERROR (Status); + + // + // Program the Flash Protection Range Register based on policy + // + DlockValue = MmioRead32 (SpiBar0 + R_SPI_DLOCK); + + FlashProtectionConfig->ProtectRange[0].ProtectedRangeBase = (UINT16) ((FixedPcdGet32 (PcdFlashIbbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress)) >> 12); + FlashProtectionConfig->ProtectRange[0].ProtectedRangeLimit = (UINT16) ((FixedPcdGet32 (PcdFlashIbbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress) + FixedPcdGet32 (PcdFlashIbbRegionSize) - 1) >> 12); + FlashProtectionConfig->ProtectRange[1].ProtectedRangeBase = (UINT16) ((FixedPcdGet32 (PcdFlashObbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress)) >> 12); + FlashProtectionConfig->ProtectRange[1].ProtectedRangeLimit = (UINT16) ((FixedPcdGet32 (PcdFlashObbRegionMappedBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress) + FixedPcdGet32 (PcdFlashObbRegionSize) - 1) >> 12); + + for (Index = 0; Index < SC_FLASH_PROTECTED_RANGES; ++Index) { + if ((FlashProtectionConfig->ProtectRange[Index].WriteProtectionEnable || + FlashProtectionConfig->ProtectRange[Index].ReadProtectionEnable) != TRUE) { + continue; + } + + // + // Proceed to program the register after ensure it is enabled + // + Data32 = 0; + Data32 |= (FlashProtectionConfig->ProtectRange[Index].WriteProtectionEnable == TRUE) ? B_SPI_PRX_WPE : 0; + Data32 |= (FlashProtectionConfig->ProtectRange[Index].ReadProtectionEnable == TRUE) ? B_SPI_PRX_RPE : 0; + Data32 |= ((UINT32) FlashProtectionConfig->ProtectRange[Index].ProtectedRangeLimit << N_SPI_PRX_PRL) & B_SPI_PRX_PRL_MASK; + Data32 |= ((UINT32) FlashProtectionConfig->ProtectRange[Index].ProtectedRangeBase << N_SPI_PRX_PRB) & B_SPI_PRX_PRB_MASK; + DEBUG ((DEBUG_INFO, "Protected range %d: 0x%08x \n", Index, Data32)); + + DlockValue |= (UINT32) (B_SPI_DLOCK_PR0LOCKDN << Index); + MmioWrite32 ((UINTN) (SpiBar0 + (R_SPI_PR0 + (Index * S_SPI_PRX))), Data32); + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint32, + (UINTN) (SpiBar0 + (R_SPI_PR0 + (Index * S_SPI_PRX))), + 1, + (VOID *) (UINTN) (SpiBar0 + (R_SPI_PR0 + (Index * S_SPI_PRX))) + ); + } + + // + // Program DLOCK register + // + MmioWrite32 ((UINTN) (SpiBar0 + R_SPI_DLOCK), DlockValue); + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint32, + (UINTN) (SpiBar0 + R_SPI_DLOCK), + 1, + (VOID *) (UINTN) (SpiBar0 + R_SPI_DLOCK) + ); + + // + // In SPI controller the BIOS should set the Flash Configuration Lock-Down bit + // (SPI_BAR0 + 04[15]) at end of post. When set to 1, those Flash Program Registers + // that are locked down by this FLOCKDN bit cannot be written. + // + MmioOr32 ((UINTN) (SpiBar0 + R_SPI_HSFS), (UINT32) (B_SPI_HSFS_FLOCKDN)); + S3BootScriptSaveMemWrite ( + EfiBootScriptWidthUint32, + (UINTN) (SpiBar0 + R_SPI_HSFS), + 1, + (VOID *) (UINTN) (SpiBar0 + R_SPI_HSFS) + ); + } + + Status = GetConfigBlock ((VOID *) mScPolicy, &gLockDownConfigGuid, (VOID *) &LockDownConfig); + ASSERT_EFI_ERROR (Status); + if (LockDownConfig->GlobalSmi == TRUE) { + // + // Save Global SMI Enable bit setting before BIOS enables SMI_LOCK during S3 resume + // + Data32Or = IoRead32 ((UINTN) (AcpiBaseAddr + R_SMI_EN)); + if ((Data32Or & B_SMI_EN_GBL_SMI) != 0) { + Data32And = 0xFFFFFFFF; + Data32Or &= B_SMI_EN_GBL_SMI; + S3BootScriptSaveIoReadWrite ( + EfiBootScriptWidthUint32, + (UINTN) (AcpiBaseAddr + R_SMI_EN), + &Data32Or, // Data to be ORed + &Data32And // Data to be ANDed + ); + } + + MmioOr8 ((UINTN) (PmcBase + R_PMC_GEN_PMCON_2), B_PMC_GEN_PMCON_SMI_LOCK); + S3BootScriptSaveMemWrite ( + EfiBootScriptWidthUint8, + (UINTN) (PmcBase + R_PMC_GEN_PMCON_2), + 1, + (VOID *) (UINTN) (PmcBase + R_PMC_GEN_PMCON_2) + ); + } + + if (GetBxtSeries () == BxtP) { + if (LockDownConfig->BiosLock == TRUE) { + // + // LPC + // + if (! (MmioRead8 (PciLpcRegBase + R_PCH_LPC_BC) & B_PCH_LPC_BC_LE)) { + DEBUG ((DEBUG_INFO, "Set LPC bios lock\n")); + MmioOr8 ((UINTN) (PciLpcRegBase + R_PCH_LPC_BC), B_PCH_LPC_BC_LE); + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint8, + (UINTN) (PciLpcRegBase + R_PCH_LPC_BC), + 1, + (VOID *) (UINTN) (PciLpcRegBase + R_PCH_LPC_BC) + ); + } + + // + // SPI + // + if (! (MmioRead8 (PciSpiRegBase + R_SPI_BCR) & B_SPI_BCR_BLE)) { + DEBUG ((DEBUG_INFO, "Set SPI bios lock\n")); + MmioOr8 ((UINTN) (PciSpiRegBase + R_SPI_BCR), (UINT8) B_SPI_BCR_BLE); + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint8, + (UINTN) (PciSpiRegBase + R_SPI_BCR), + 1, + (VOID *) (UINTN) (PciSpiRegBase + R_SPI_BCR) + ); + } + } + + if (LockDownConfig->BiosInterface == TRUE) { + // + // LPC + // + MmioOr8 ((UINTN) (PciLpcRegBase + R_PCH_LPC_BC), (UINT8) B_PCH_LPC_BC_BILD); + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint8, + (UINTN) (PciLpcRegBase + R_PCH_LPC_BC), + 1, + (VOID *) (UINTN) (PciLpcRegBase + R_PCH_LPC_BC) + ); + + // + // Reads back for posted write to take effect + // + Data8 = MmioRead8 ((UINTN) (PciLpcRegBase + R_PCH_LPC_BC)); + S3BootScriptSaveMemPoll ( + S3BootScriptWidthUint8, + (UINTN) (PciLpcRegBase + R_PCH_LPC_BC), + &Data8, // BitMask + &Data8, // BitValue + 1, // Duration + 1 // LoopTimes + ); + + // + // SPI + // + MmioOr8 ((UINTN) (PciSpiRegBase + R_SPI_BCR), (UINT8) B_SPI_BCR_BILD); + S3BootScriptSaveMemWrite ( + S3BootScriptWidthUint8, + (UINTN) (PciSpiRegBase + R_SPI_BCR), + 1, + (VOID *) (UINTN) (PciSpiRegBase + R_SPI_BCR) + ); + + // + // Reads back for posted write to take effect + // + Data8 = MmioRead8 ((UINTN) (PciSpiRegBase + R_SPI_BCR)); + S3BootScriptSaveMemPoll ( + S3BootScriptWidthUint8, + (UINTN) (PciSpiRegBase + R_SPI_BCR), + &Data8, // BitMask + &Data8, // BitValue + 1, // Duration + 1 // LoopTimes + ); + } + } + + if (LockDownConfig->TcoLock) { + // + // Enable TCO and Lock Down TCO + // + DEBUG ((DEBUG_INFO, "Enable TCO and Lock Down TCO\n")); + Data16And = 0xFFFF; + Data16Or = B_SMI_EN_TCO; + IoOr16 (AcpiBaseAddr + R_SMI_EN, Data16Or); + + Data16And = 0xFFFF; + Data16Or = B_TCO_CNT_LOCK; + IoOr16 (AcpiBaseAddr + R_TCO_CNT, Data16Or); + + S3BootScriptSaveIoReadWrite ( + EfiBootScriptWidthUint16, + (UINTN) (AcpiBaseAddr + R_TCO_CNT), + &Data16Or, // Data to be ORed + &Data16And // Data to be ANDed + ); + + HobPtr.Guid = GetFirstGuidHob (&gSiPolicyHobGuid); + ASSERT (HobPtr.Guid != NULL); + SiPolicyHob = GET_GUID_HOB_DATA (HobPtr.Guid); + UsbInitBeforeBoot (SiPolicyHob, mScPolicy); + DEBUG ((DEBUG_INFO, "Enable TCO and Lock Down TCO ---- END\n")); + + } + + if (LockDownConfig->RtcLock == TRUE) { + Data32And = 0xFFFFFFFF; + Data32Or = (B_PCH_PCR_RTC_CONF_UCMOS_LOCK | B_PCH_PCR_RTC_CONF_LCMOS_LOCK | B_PCH_PCR_RTC_CONF_BILD); + PchPcrAndThenOr32 ( + 0xD1, + R_PCH_PCR_RTC_CONF, + Data32And, + Data32Or + ); + PCR_BOOT_SCRIPT_READ_WRITE ( + S3BootScriptWidthUint32, + 0xD1, + R_PCH_PCR_RTC_CONF, + &Data32Or, + &Data32And + ); + } + + if ((BxtSeries == BxtP) || (BxtSeries == Bxt1)){ + Data8 = SW_SMI_PCIE_ASPM_OVERRIDE; + S3BootScriptSaveIoWrite ( + EfiBootScriptWidthUint8, + (UINTN) (R_APM_CNT), + 1, + &Data8 + ); + } + DEBUG ((DEBUG_INFO, "ScOnEndOfDxe() End\n")); + + return; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.h new file mode 100644 index 0000000000..0fc3b59505 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInit.h @@ -0,0 +1,267 @@ +/** @file + Header file for Initialization Driver. + + Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef _SC_INITIALIZATION_DRIVER_H_ +#define _SC_INITIALIZATION_DRIVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +// Driver Consumed Protocol Prototypes +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SC_PM_ENABLE + +typedef struct { + EFI_SC_INFO_PROTOCOL ScInfo; +} SC_INSTANCE_PRIVATE_DATA; + +// +// Data definitions +// +extern EFI_HANDLE mImageHandle; + +/// +/// IRQ routing init table entry +/// +typedef struct { + UINTN BusNumber; + UINTN DeviceNumber; + UINTN FunctionNumber; + UINTN Irq; +} SC_IRQ_INIT_ENTRY; + +/** + Initialize the SC device according to the SC Platform Policy + + @param[in, out] ScInstance SC instance private data. May get updated by this function + @param[in] ScPolicy The SC Policy instance + @param[in] PmcBase PMC base address of this SC device + @param[in] AcpiBaseAddr ACPI IO base address of this SC device + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +InitializeScDevice ( + IN OUT SC_INSTANCE_PRIVATE_DATA *ScInstance, + IN SC_POLICY_HOB *ScPolicy, + IN UINT32 PmcBase, + IN UINT16 AcpiBaseAddr + ); + +/** + Program Sc devices dedicated IRQ#. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigureIrqAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + SC initialization triggered by ExitBootServices events + Useful for operations which must happen later than at the end of post + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + SC initialization triggered by ExitBootServices for LPSS events + This should be at a higher TPL than the callback that sets Untrusted Mode. + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScLpssExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + SC initialization before Boot Script Table is closed + + @param[in] Event A pointer to the Event that triggered the callback. + @param[in] Context A pointer to private data registered with the callback function. + +**/ +VOID +EFIAPI +ScOnEndOfDxe ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Hide PCI config space of HD-Audio device and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Device non-exist or Dsp is disabled + +**/ +EFI_STATUS +ConfigureHdaAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Perform the remaining configuration on SC SATA to perform device detection + at end of Dxe, then set the SATA SPD and PxE corresponding, and set the Register Lock + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigureSataDxe ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Hide PCI config space of Otg device and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_FOUND GNVS Protocol interface not found + +**/ +EFI_STATUS +ConfigureOtgAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Hide PCI config space of Lpss devices and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_FOUND GNVS Protocol interface not found + +**/ +EFI_STATUS +ConfigureLpssAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Stop Lpss devices[I2C and SPI] if any is running. + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +StopLpssAtBoot ( + VOID + ); + +/** + Register notification function for PM configuration after PCI enumeration + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigurePmcAfterPciEnum ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Dump whole SC_POLICY_HOB and serial out. + + @param[in] ScPolicy The SC Policy instance + +**/ +VOID +ScDumpPolicy ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Configures ports of the SC USB3 (xHCI) controller before entering OS. the SC USB3 (xHCI) controller + + @param[in] ScPolicy The SC Policy instance + +**/ +VOID +ConfigureXhciAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ); + +/** + Update ASL object before Boot + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_STATUS + @retval EFI_NOT_READY The Acpi protocols are not ready. + +**/ +EFI_STATUS +UpdateNvsArea ( + IN SC_POLICY_HOB *ScPolicy + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInitDxe.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInitDxe.inf new file mode 100644 index 0000000000..5b31b18fab --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScInitDxe.inf @@ -0,0 +1,104 @@ +## @file +# SC Initialization driver +# +# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ScInitDxe + FILE_GUID = 149A6B53-FAFA-44F9-8BAF-F50C68A05236 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = ScInitEntryPoint + +[Sources] + ScInit.h + ScInit.c + ScHda.c + ScLpss.c + ScIsh.c + ScPmc.c + ScIosf.c + ScSata.c + ScXdci.c + ScAcpi.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonSiPkg/BroxtonSiPrivate.dec + BroxtonPlatformPkg/PlatformPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + DxeServicesTableLib + MemoryAllocationLib + UefiDriverEntryPoint + DebugLib + PcdLib + IoLib + ScPlatformLib + UefiLib + S3BootScriptLib + ScAslUpdateLib + SteppingLib + MmPciLib + HobLib + TimerLib + ScHdaLib + SideBandLib + SteppingLib + UsbCommonLib + DxeVtdLib + GpioLib + ConfigBlockLib + HeciMsgLib + +[Protocols] + gEfiInfoProtocolGuid ## PRODUCES + gExitPmAuthProtocolGuid ## PRODUCES + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiGlobalNvsAreaProtocolGuid ## CONSUMES + gEfiPciIoProtocolGuid ## CONSUMES + gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES + +[Guids] + gScPolicyHobGuid ## UNDEFINED + gEfiAcpiTableGuid ## UNDEFINED + gSiPolicyHobGuid + gPcieRpConfigGuid + gSataConfigGuid + gHdAudioConfigGuid + gLockDownConfigGuid + gLpssConfigGuid + gFlashProtectionConfigGuid + gFdoModeEnabledHobGuid + gScPmcFunctionDisableResetHobGuid + gP2sbConfigGuid + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES + gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress ## SOMETIMES_CONSUMES + gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress ## SOMETIMES_CONSUMES + gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress + + gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize + gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress + gPlatformModuleTokenSpaceGuid.PcdFlashIbbRegionMappedBase + gPlatformModuleTokenSpaceGuid.PcdFlashIbbRegionSize + gPlatformModuleTokenSpaceGuid.PcdFlashObbRegionMappedBase + gPlatformModuleTokenSpaceGuid.PcdFlashObbRegionSize + +[Depex] + gEfiSmmControl2ProtocolGuid + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIosf.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIosf.c new file mode 100644 index 0000000000..50c554aad1 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIosf.c @@ -0,0 +1,35 @@ +/** @file + Initializes SC IOSF Devices + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" +#include +#include "SaAccess.h" + +/** + Hide PCI config space of Iosf devices and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigureIosfAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + return EFI_SUCCESS; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIsh.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIsh.c new file mode 100644 index 0000000000..91f5dd7dbe --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScIsh.c @@ -0,0 +1,53 @@ +/** @file + Initializes SC ISH Devices. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" +#include +#include +#include "SaAccess.h" + +/** + Hide PCI config space of ISH devices and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigureIshAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + UINTN IshPciMmBase; + UINT32 IshMmioBase0; + UINT32 IshMmioBase1; + UINT32 Buffer32; + + DEBUG ((DEBUG_INFO, "ConfigureIshAtBoot() Start\n")); + + // + // Initialize Variables + // + IshPciMmBase = 0; + IshMmioBase0 = 0; + IshMmioBase1 = 0; + Buffer32 = 0; + + DEBUG ((DEBUG_INFO, "ConfigureIshAtBoot() End\n")); + + return EFI_SUCCESS; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScLpss.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScLpss.c new file mode 100644 index 0000000000..593db9816f --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScLpss.c @@ -0,0 +1,283 @@ +/** @file + Initializes SC LPSS Devices. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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 +#include +#include +#include +#include +#include "ScInit.h" + +typedef struct { + UINT32 PciDeviceNum; + UINT32 PciFuncNum; + UINT16 LpssPciCfgCtrl; + UINT16 Psf3BaseAddress; + UINT32 LpssFuncDisableBit; +} SERIAL_IO_CONTROLLER_DESCRIPTOR; + +#define LPSS_IO_DEVICE_NUM 15 + +// +// Note: the devices order need to align with the order defined in SC_LPSS_CONFIG +// +SERIAL_IO_CONTROLLER_DESCRIPTOR mLpssIoDevices[LPSS_IO_DEVICE_NUM] = +{ + // + // I2C 0~7 + // + {PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C0, 0x200, 0x1900, B_PMC_FUNC_DIS_LPSS_I2C0}, + {PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C1, 0x204, 0x1800, B_PMC_FUNC_DIS_LPSS_I2C1}, + {PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C2, 0x208, 0x1700, B_PMC_FUNC_DIS_LPSS_I2C2}, + {PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTION_NUMBER_LPSS_I2C3, 0x20C, 0x1600, B_PMC_FUNC_DIS_LPSS_I2C3}, + {PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C4, 0x210, 0x1500, B_PMC_FUNC_DIS_LPSS_I2C4}, + {PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C5, 0x214, 0x1400, B_PMC_FUNC_DIS_LPSS_I2C5}, + {PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C6, 0x218, 0x1300, B_PMC_FUNC_DIS_LPSS_I2C6}, + {PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTION_NUMBER_LPSS_I2C7, 0x21C, 0x1200, B_PMC_FUNC_DIS_LPSS_I2C7}, + + // + // UART 0~3 + // + {PCI_DEVICE_NUMBER_LPSS_HSUART, PCI_FUNCTION_NUMBER_LPSS_HSUART0, 0x220, 0x1100, B_PMC_FUNC_DIS_LPSS_UART0}, + {PCI_DEVICE_NUMBER_LPSS_HSUART, PCI_FUNCTION_NUMBER_LPSS_HSUART1, 0x224, 0x1000, B_PMC_FUNC_DIS_LPSS_UART1}, + {PCI_DEVICE_NUMBER_LPSS_HSUART, PCI_FUNCTION_NUMBER_LPSS_HSUART2, 0x228, 0x0F00, B_PMC_FUNC_DIS_LPSS_UART2}, + {PCI_DEVICE_NUMBER_LPSS_HSUART, PCI_FUNCTION_NUMBER_LPSS_HSUART3, 0x22C, 0x0E00, B_PMC_FUNC_DIS_LPSS_UART3}, + + // + // SPI 0~2 + // + {PCI_DEVICE_NUMBER_LPSS_SPI, PCI_FUNCTION_NUMBER_LPSS_SPI0, 0x230, 0x0D00, B_PMC_FUNC_DIS_LPSS_SPI0}, + {PCI_DEVICE_NUMBER_LPSS_SPI, PCI_FUNCTION_NUMBER_LPSS_SPI1, 0x234, 0x0C00, B_PMC_FUNC_DIS_LPSS_SPI1}, + {PCI_DEVICE_NUMBER_LPSS_SPI, PCI_FUNCTION_NUMBER_LPSS_SPI2, 0x238, 0x0B00, B_PMC_FUNC_DIS_LPSS_SPI2} +}; + + +/** + Hide PCI config space of LPSS devices and do any final initialization. + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_NOT_FOUND GNVS Protocol interface not found + +**/ +EFI_STATUS +ConfigureLpssAtBoot ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + UINTN LpssPciMmBase; + UINT32 LpssMmioBase0; + UINT32 LpssMmioBase0_High; + UINT32 P2sbMmioBar; + UINT32 Buffer32; + EFI_STATUS AcpiTablePresent; + EFI_STATUS Status; + UINT64 Data64; + UINTN AcpiTableKey; + UINT8 Index; + SC_LPSS_CONFIG *LpssConfig; + EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; + UINT32 PciP2sbBar0RegOffset; + + DEBUG ((DEBUG_INFO, "ConfigureLpssAtBoot() Start\n")); + Status = GetConfigBlock ((VOID *) ScPolicy, &gLpssConfigGuid, (VOID *) &LpssConfig); + ASSERT_EFI_ERROR (Status); + + // + // Initialize Variables + // + LpssPciMmBase = 0; + LpssMmioBase0 = 0; + LpssMmioBase0_High = 0; + P2sbMmioBar = 0; + + Buffer32 = 0; + AcpiTablePresent = EFI_NOT_FOUND; + AcpiTableKey = 0; + Data64 = 0; + Index = 0; + Status = EFI_SUCCESS; + + // + // Locate ACPI table + // + AcpiTablePresent = InitializeScAslUpdateLib (); + + for (Index = 0; Index < LPSS_IO_DEVICE_NUM; Index++) { + LpssPciMmBase = MmPciBase( + DEFAULT_PCI_BUS_NUMBER_SC, + mLpssIoDevices[Index].PciDeviceNum, + mLpssIoDevices[Index].PciFuncNum + ); + + LpssMmioBase0 = MmioRead32 ((UINTN) (LpssPciMmBase + R_LPSS_IO_BAR)); + LpssMmioBase0 &= 0xFFFFFFF0; // Mask off the last byte read from BAR + LpssMmioBase0_High = MmioRead32 ((UINTN) (LpssPciMmBase + R_LPSS_IO_BAR_HIGH)); + + // + // Assume the MMIO address for BAR0 is always 32 bits (high DW is 0). + // + MmioWrite32 ((UINTN) (LpssMmioBase0 + R_LPSS_IO_REMAP_ADDRESS_LOW), LpssMmioBase0); + MmioWrite32 ((UINTN) (LpssMmioBase0 + R_LPSS_IO_REMAP_ADDRESS_HI), LpssMmioBase0_High); + + DEBUG ((DEBUG_INFO, "Read back LPSS REMAP Register, High DW = 0x%x, Low DW = 0x%x, Index = %d\n", + MmioRead32 ((UINTN) (LpssMmioBase0 + R_LPSS_IO_REMAP_ADDRESS_HI)), + MmioRead32 ((UINTN) (LpssMmioBase0 + R_LPSS_IO_REMAP_ADDRESS_LOW)), + Index)); + + // Hide the UART2 device if kernel debugger mode is enabled + // BXT UART2 device is hidden in OnReadyToBoot (BIOS and OS use different debug COM port) + // + if (mLpssIoDevices[Index].PciDeviceNum == PCI_DEVICE_NUMBER_LPSS_HSUART + && mLpssIoDevices[Index].PciFuncNum == PCI_FUNCTION_NUMBER_LPSS_HSUART2 + && GetBxtSeries () == BxtP + && LpssConfig->OsDbgEnable + && LpssMmioBase0 != 0xFFFFFFFF) { + + DEBUG ((DEBUG_INFO, "Kernel Debug is Enabled\n")); + DEBUG ((DEBUG_INFO, "---------------------------------------------------------------------------------\n")); + DEBUG ((DEBUG_INFO, "This concludes BIOS serial debug messages, open the kernel debugger (WinDBG) now.\n\n")); + DEBUG ((DEBUG_INFO, "To enable continued serial and console redirection:\n")); + DEBUG ((DEBUG_INFO, " 1) Open the BIOS setup menu\n")); + DEBUG ((DEBUG_INFO, " 2) Navigate to Device Manager->System Setup->Debug Configuration->Kernel Debugger Enable\n")); + DEBUG ((DEBUG_INFO, " 3) Select the \"Disabled\" option and save\n\n")); + + SideBandAndThenOr32 ( + 0xC6, + 0x0F38, + 0xFFFFFFFF, + BIT0 + ); + + DEBUG ((DEBUG_INFO, "Kernel Debugger Mode Enabled - LPSS D24 F2 CFG_DIS: 0x%08X\n", SideBandRead32 (0xC6, 0x0F38))); + } + } + + // + // Update LPSS devices ACPI variables + // + Status = gBS->LocateProtocol ( + &gEfiGlobalNvsAreaProtocolGuid, + NULL, + (VOID **) &GlobalNvsArea + ); + if (EFI_ERROR (Status)) { + return Status; + } + + PciP2sbBar0RegOffset = (UINT32) MmPciAddress ( + 0, + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_P2SB, + PCI_FUNCTION_NUMBER_P2SB, + R_P2SB_BASE + ); + + // + // Read back P2SB MMIO BAR Base Addr + // + P2sbMmioBar = MmioRead32 (PciP2sbBar0RegOffset); + if (P2sbMmioBar == 0xFFFFFFFF) { + // + // P2SB has been hidden, read it from Pcd + // + P2sbMmioBar = PcdGet32 (PcdP2SBBaseAddress); + } else { + P2sbMmioBar &= B_P2SB_BAR_BA; + } + + GlobalNvsArea->Area->GPIO0Addr = P2SB_MMIO_ADDR (P2sbMmioBar, NORTH, 0); + GlobalNvsArea->Area->GPIO0Len = GPIO_NORTH_COMMUNITY_LENGTH; + + GlobalNvsArea->Area->GPIO1Addr = P2SB_MMIO_ADDR (P2sbMmioBar, NORTHWEST, 0); + GlobalNvsArea->Area->GPIO1Len = GPIO_NORTHWEST_COMMUNITY_LENGTH; + + GlobalNvsArea->Area->GPIO2Addr = P2SB_MMIO_ADDR (P2sbMmioBar, WEST, 0); + GlobalNvsArea->Area->GPIO2Len = GPIO_WEST_COMMUNITY_LENGTH; + + GlobalNvsArea->Area->GPIO3Addr = P2SB_MMIO_ADDR (P2sbMmioBar, SOUTHWEST, 0); + GlobalNvsArea->Area->GPIO3Len = GPIO_SOUTHWEST_COMMUNITY_LENGTH; + + DEBUG ((DEBUG_INFO, "GPIOxAddr: North: 0x%X, Northwest: 0x%X, West: 0x%X, Southwest: 0x%X, South: 0x%X\n", \ + GlobalNvsArea->Area->GPIO0Addr, + GlobalNvsArea->Area->GPIO1Addr, + GlobalNvsArea->Area->GPIO2Addr, + GlobalNvsArea->Area->GPIO3Addr, + GlobalNvsArea->Area->GPIO4Addr + )); + +#ifdef SC_PM_ENABLE + DEBUG ((DEBUG_INFO, "Start SC_PM_ENABLE for GPIO\n")); + GpioWrite (NORTH, R_GPIO_MISCCFG, GpioRead (NORTH , R_GPIO_MISCCFG) | B_GPIP_MISCCFG); + GpioWrite (NORTHWEST, R_GPIO_MISCCFG, GpioRead (NORTHWEST, R_GPIO_MISCCFG) | B_GPIP_MISCCFG); + GpioWrite (WEST, R_GPIO_MISCCFG, GpioRead (WEST , R_GPIO_MISCCFG) | B_GPIP_MISCCFG); + GpioWrite (SOUTHWEST, R_GPIO_MISCCFG, GpioRead (SOUTHWEST, R_GPIO_MISCCFG) | B_GPIP_MISCCFG); + DEBUG ((DEBUG_INFO, "End SC_PM_ENABLE for GPIO\n")); +#endif + + DEBUG ((DEBUG_INFO, "ConfigureLpssAtBoot() End\n")); + return EFI_SUCCESS; +} + + +/** + Stop Lpss devices[I2C and SPI] if any is running. + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +StopLpssAtBoot ( + VOID + ) +{ + UINTN LpssPciMmBase; + UINT32 LpssMmioBase0; + UINT8 Index; + UINT32 D32 = 0; + + DEBUG ((DEBUG_INFO, "Stop LPSS controllers if any controller is running(I2C and SPI)...\n")); + for (Index = 0; Index < LPSS_IO_DEVICE_NUM; Index++) { + LpssPciMmBase = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + mLpssIoDevices[Index].PciDeviceNum, + mLpssIoDevices[Index].PciFuncNum + ); + + LpssMmioBase0 = MmioRead32 ((UINTN) (LpssPciMmBase + R_LPSS_IO_BAR)); + LpssMmioBase0 &= 0xFFFFFFF0; // Mask off the last byte read from BAR + + if ((mLpssIoDevices[Index].PciDeviceNum == PCI_DEVICE_NUMBER_LPSS_I2C0) || \ + (mLpssIoDevices[Index].PciDeviceNum == PCI_DEVICE_NUMBER_LPSS_I2C1)) { + D32 = MmioRead32 ((UINTN) (LpssMmioBase0 + R_LPSS_I2C_IC_ENABLE)); + if (D32 & B_LPSS_I2C_IC_ENABLE_ENABLE) { + DEBUG ((DEBUG_INFO, "Stop I2C controller D:%02X, F: %02X...\n", mLpssIoDevices[Index].PciDeviceNum, mLpssIoDevices[Index].PciFuncNum)); + MmioWrite32 ((UINTN) LpssMmioBase0 + R_LPSS_I2C_IC_ENABLE, \ + MmioRead32 ((UINTN) (LpssMmioBase0 + R_LPSS_I2C_IC_ENABLE)) & (~(UINT32) B_LPSS_I2C_IC_ENABLE_ENABLE)); + } + } else if (mLpssIoDevices[Index].PciDeviceNum == PCI_DEVICE_NUMBER_LPSS_SPI) { + D32 = MmioRead32 ((UINTN) (LpssMmioBase0 + R_LPSS_SPI_MEM_SSP_CONTROL0)); + if (D32 & B_LPSS_SPI_MEM_SSP_CONTROL0_SSE) { + DEBUG ((DEBUG_INFO, "Stop SPI controller D:%02X, F: %02X...\n", mLpssIoDevices[Index].PciDeviceNum, mLpssIoDevices[Index].PciFuncNum)); + MmioWrite32 ((UINTN) LpssMmioBase0 + R_LPSS_SPI_MEM_SSP_CONTROL0, \ + MmioRead32 ((UINTN) (LpssMmioBase0 + R_LPSS_SPI_MEM_SSP_CONTROL0)) & (~(UINT32) B_LPSS_SPI_MEM_SSP_CONTROL0_SSE)); + } + } + } + + return EFI_SUCCESS; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScPmc.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScPmc.c new file mode 100644 index 0000000000..209838e68b --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScPmc.c @@ -0,0 +1,108 @@ +/** @file + Initializes SC PMC Devices. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" +#include + +/** + Set PMC IO enable bit (Command register (BIT2 | BIT1 | BIT0)) after PCI enumeration + + @param[in] Event The Event that is being processed + @param[in] Context Event Context + +**/ +VOID +EFIAPI +PmcPciEnumeratedCompleteNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN PmcBaseAddr; + UINT16 AcpiBaseAddr; + UINT32 IpcBaseAddr; + + DEBUG ((DEBUG_INFO, "Override Broxton PMC (bus 0, device 13, function 1) bar2 (offset 0x20) to PcdScAcpiIoPortBaseAddress(0x400)\n")); + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + PmcBaseAddr = MmPciBase ( + DEFAULT_PCI_BUS_NUMBER_SC, + PCI_DEVICE_NUMBER_PMC_IPC1, + PCI_FUNCTION_NUMBER_PMC_IPC1 + ); + MmioWrite32 (PmcBaseAddr + R_PMC_ACPI_BASE, AcpiBaseAddr); + + DEBUG ((DEBUG_INFO, "Set PMC IO enable bit (Command register (BIT2 | BIT1 | BIT0)) after PCI enumeration\n")); + MmioOr32 (PmcBaseAddr + 0x04, (BIT2 | BIT1 | BIT0)); + + IpcBaseAddr = MmioRead32 (PmcBaseAddr + R_PMC_IPC1_BASE); + S3BootScriptSaveMemWrite ( + EfiBootScriptWidthUint32, + (UINTN) (PmcBaseAddr + R_PMC_IPC1_BASE), + 1, + &IpcBaseAddr + ); + + DEBUG ((DEBUG_INFO, "PmcPciEnumeratedCompleteNotify IpcBaseAddr = 0x%x.\n", IpcBaseAddr)); + + gBS->CloseEvent (Event); +} + + +/** + Register notification function for PM configuration after PCI enumeration + + @param[in] ScPolicy The SC Policy instance + + @retval EFI_SUCCESS The function completed successfully + +**/ +EFI_STATUS +ConfigurePmcAfterPciEnum ( + IN SC_POLICY_HOB *ScPolicy + ) +{ + EFI_EVENT PCIEnumerationCompleteEvent = NULL; + VOID *Registration; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "ConfigurePmcAfterPciEnum () Start\n")); + + // + // Register InternalIpcLibPciEnumeratedNotifyEvent() notify function + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + PmcPciEnumeratedCompleteNotify, + NULL, + NULL, + &PCIEnumerationCompleteEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for protocol notifications on this event + // + Status = gBS->RegisterProtocolNotify ( + &gEfiPciEnumerationCompleteProtocolGuid, + PCIEnumerationCompleteEvent, + &Registration + ); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "ConfigurePmcAfterPciEnum () End\n")); + + return EFI_SUCCESS; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScSata.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScSata.c new file mode 100644 index 0000000000..63c2b88d14 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScSata.c @@ -0,0 +1,18 @@ +/** @file + Perform related functions for SC Sata in DXE phase. + + Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.
+ + 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 + + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScXdci.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScXdci.c new file mode 100644 index 0000000000..d8e5b85629 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Dxe/ScXdci.c @@ -0,0 +1,18 @@ +/** @file + Initializes SC USB xDCI Device. + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInit.h" +#include + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c new file mode 100644 index 0000000000..ed8a74b1ce --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.c @@ -0,0 +1,183 @@ +/** @file + SC Init Smm module for SC specific SMI handlers. + + Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInitSmm.h" + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SW_DISPATCH2_PROTOCOL *mSwDispatch; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch; +GLOBAL_REMOVE_IF_UNREFERENCED SC_NVS_AREA *mScNvsArea; +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mAcpiBaseAddr; +GLOBAL_REMOVE_IF_UNREFERENCED SC_POLICY_HOB *mScPolicy; +GLOBAL_REMOVE_IF_UNREFERENCED SC_PCIE_CONFIG *mPcieRpConfig; + +// +// The reserved MMIO range to be used in Sx handler +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr; +GLOBAL_REMOVE_IF_UNREFERENCED UINTN mResvMmioSize; + + +/** + PCH Sx entry SMI handler. + + @param[in] Handle Handle of the callback + @param[in] Context The dispatch context + @param[in, out] CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-SMM environment into an SMM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +PchSxHandler ( + IN EFI_HANDLE Handle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + return EFI_SUCCESS; +} + + +/** + Initialize PCH Sx entry SMI handler. + + @param[in] ImageHandle Handle for the image of this driver + + @retval None + +**/ +VOID +InitializeSxHandler ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_SMM_SX_REGISTER_CONTEXT SxDispatchContext; + EFI_HANDLE SxDispatchHandle; + EFI_SLEEP_TYPE SxType; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "InitializeSxHandler() Start\n")); + + // + // Register the callback for S3/S4/S5 entry + // + SxDispatchContext.Phase = SxEntry; + for (SxType = SxS3; SxType <= SxS5; SxType++) { + SxDispatchContext.Type = SxType; + Status = mSxDispatch->Register ( + mSxDispatch, + PchSxHandler, + &SxDispatchContext, + &SxDispatchHandle + ); + ASSERT_EFI_ERROR (Status); + } + + DEBUG ((DEBUG_INFO, "InitializeSxHandler() End\n")); +} + + +/** + Initializes the PCH SMM handler for for PCIE hot plug support + PchInit SMM Module Entry Point\n + - Introduction\n + The PchInitSmm module is a SMM driver that initializes the Intel Platform Controller Hub + SMM requirements and services. It consumes the PCH_POLICY_PROTOCOL for expected + configurations per policy. + + - Details\n + This module provides SMI handlers to services PCIE HotPlug SMI, LinkActive SMI, and LinkEq SMI. + And also provides port 0x61 emulation support, GPIO Sx isolation requirement, and register BIOS WP + handler to process BIOSWP status. + + - @pre + - @link _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL @endlink + - This is to ensure that PCI MMIO and IO resource has been prepared and available for this driver to allocate. + - EFI_SMM_BASE2_PROTOCOL + - @link _EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL @endlink + - @link _EFI_SMM_SX_DISPATCH2_PROTOCOL EFI_SMM_SX_DISPATCH2_PROTOCOL @endlink + - @link _EFI_SMM_CPU_PROTOCOL EFI_SMM_CPU_PROTOCOL @endlink + - @link _PCH_SMI_DISPATCH_PROTOCOL PCH_SMI_DISPATCH_PROTOCOL @endlink + - @link _PCH_PCIE_SMI_DISPATCH_PROTOCOL PCH_PCIE_SMI_DISPATCH_PROTOCOL @endlink + - @link _PCH_TCO_SMI_DISPATCH_PROTOCOL PCH_TCO_SMI_DISPATCH_PROTOCOL @endlink + - @link _PCH_ESPI_SMI_DISPATCH_PROTOCOL PCH_ESPI_SMI_DISPATCH_PROTOCOL @endlink + - SC_NVS_AREA_PROTOCOL + - @link PeiDxeSmmPchPlatformLib.h PeiDxeSmmPchPlatformLib @endlink library + - @link PeiDxeSmmPchPciExpressHelpersLib.h PchPciExpressHelpersLib @endlink library + + - References\n + @link _PCH_POLICY PCH_POLICY_PROTOCOL @endlink. + + - Integration Checklists\n + - Verify prerequisites are met. Porting Recommendations. + - No modification of this module should be necessary + - Any modification of this module should follow the PCH BIOS Specification and EDS + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_SUCCESS PCH SMM handler was installed + +**/ +EFI_STATUS +EFIAPI +ScInitSmmEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS HobPtr; + + DEBUG ((DEBUG_INFO, "ScInitSmmEntryPoint()\n")); + + // + // Locate the SMM SW dispatch protocol + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSwDispatch2ProtocolGuid, + NULL, + (VOID **) &mSwDispatch + ); + ASSERT_EFI_ERROR (Status); + + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSxDispatch2ProtocolGuid, + NULL, + (VOID**) &mSxDispatch + ); + ASSERT_EFI_ERROR (Status); + + // + // Get Sc Policy Hob + // + HobPtr.Guid = GetFirstGuidHob (&gScPolicyHobGuid); + ASSERT (HobPtr.Guid != NULL); + mScPolicy = (SC_POLICY_HOB *) GET_GUID_HOB_DATA (HobPtr.Guid); + + Status = GetConfigBlock ((VOID *) mScPolicy, &gPcieRpConfigGuid, (VOID *) &mPcieRpConfig); + ASSERT_EFI_ERROR (Status); + InitializeSxHandler (ImageHandle); + + Status = InitializeScPcieSmm (ImageHandle, SystemTable); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h new file mode 100644 index 0000000000..81748ba1f0 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.h @@ -0,0 +1,320 @@ +/** @file + Header file for SC Init SMM Handler + + Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef _SC_INIT_SMM_H_ +#define _SC_INIT_SMM_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern EFI_SMM_SW_DISPATCH2_PROTOCOL *mSwDispatch; +extern EFI_SMM_SX_DISPATCH2_PROTOCOL *mSxDispatch; +extern SC_NVS_AREA *mScNvsArea; +extern UINT16 mAcpiBaseAddr; +extern SC_POLICY_HOB *mScPolicy; +extern SC_PCIE_CONFIG *mPcieRpConfig; +extern EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr; +extern UINTN mResvMmioSize; + +#define EFI_PCI_CAPABILITY_ID_PCIPM 0x01 + +#define DeviceD0 0x00 +#define DeviceD3 0x03 + +#define ARRAY_SIZE (data) (sizeof (data) / sizeof (data[0])) + +typedef enum { + PciCfg, + PciMmr +} SC_PCI_ACCESS_TYPE; + +typedef enum { + Acpi, + Rcrb, + Tco +} SC_ACCESS_TYPE; + +typedef struct { + SC_ACCESS_TYPE AccessType; + UINT32 Address; + UINT32 Data; + UINT32 Mask; + UINT8 Width; +} SC_SAVE_RESTORE_REG; + +typedef struct { + SC_SAVE_RESTORE_REG* ScSaveRestoreReg; + UINT8 size; +} SC_SAVE_RESTORE_REG_WRAP; + +struct _SC_SAVE_RESTORE_PCI; + +typedef struct _SC_SAVE_RESTORE_PCI{ + SC_PCI_ACCESS_TYPE AccessType; + UINT8 Device; + UINT8 Function; + UINT8 BarOffset; + UINT16 Offset; + UINT32 Data; + UINT32 Mask; + UINT8 Width; + VOID (*RestoreFunction) (struct _SC_SAVE_RESTORE_PCI *ScSaveRestorePci); +} SC_SAVE_RESTORE_PCI; + +typedef struct { + SC_SAVE_RESTORE_PCI* ScSaveRestorePci; + UINT8 size; +} Sc_SAVE_RESTORE_PCI_WRAP; + +typedef struct { + UINT8 Device; + UINT8 Function; + UINT8 PowerState; +} DEVICE_POWER_STATE; + +/** + Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling + + @param[in] ImageHandle The image handle of this module + @param[in] SystemTable The EFI System Table + + @retval EFI_SUCCESS The function completes successfully + +**/ +EFI_STATUS +EFIAPI +InitializeScPcieSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Program Common Clock and ASPM of Downstream Devices + + @param[in] PortIndex Pcie Root Port Number + @param[in] RpDevice Pcie Root Pci Device Number + @param[in] RpFunction Pcie Root Pci Function Number + + @retval EFI_SUCCESS Root port complete successfully + @retval EFI_UNSUPPORTED PMC has invalid vendor ID + +**/ +EFI_STATUS +ScPcieSmi ( + IN UINT8 PortIndex, + IN UINT8 RpDevice, + IN UINT8 RpFunction + ); + +/** + PCIE Link Active State Change Hotplug SMI call back function for all Root ports + + @param[in] DispatchHandle Handle of this dispatch function + @param[in] RpContext Rootport context, which contains RootPort Index, + and RootPort PCI BDF. + + @retval None + +**/ +VOID +EFIAPI +ScPcieLinkActiveStateChange ( + IN EFI_HANDLE DispatchHandle, + IN SC_PCIE_SMI_RP_CONTEXT *RpContext + ); + +/** + PCIE Link Equalization Request SMI call back function for all Root ports + + @param[in] DispatchHandle Handle of this dispatch function + @param[in] RpContext Rootport context, which contains RootPort Index, + and RootPort PCI BDF. + + @retval None + +**/ +VOID +EFIAPI +ScPcieLinkEqHandlerFunction ( + IN EFI_HANDLE DispatchHandle, + IN SC_PCIE_SMI_RP_CONTEXT *RpContext + ); + +/** + The SW SMI callback to config PCIE power management settings + + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] CallbackContext Pointer to the EFI_SMM_SW_REGISTER_CONTEXT + @param[in, out] CommBuffer Point to the CommBuffer structure + @param[in, out] CommBufferSize Point to the Size of CommBuffer structure + +**/ +VOID +ScPciePmSwSmiCallback ( + IN EFI_HANDLE DispatchHandle, + IN EFI_SMM_SW_REGISTER_CONTEXT *DispatchContext, + IN OUT VOID *CommBuffer, + IN OUT UINTN *CommBufferSize + ); + +/** + Initializes the PCH SMM handler for PCH save and restore + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_SUCCESS PCH SMM handler was installed + +**/ +EFI_STATUS +EFIAPI +ScInitLateSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Locate required protocol and register the 61h IO trap + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_SUCCESS PCH SMM handler was installed + +**/ +EFI_STATUS +EFIAPI +InstallIoTrapPort61h ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Initialize PCH Sx entry SMI handler. + + @param[in] ImageHandle Handle for the image of this driver + + @retval None + +**/ +VOID +InitializeSxHandler ( + IN EFI_HANDLE ImageHandle + ); + +/** + PCH Sx entry SMI handler. + + @param[in] Handle Handle of the callback + @param[in] Context The dispatch context + @param[in, out] CommBuffer A pointer to a collection of data in memory that will + be conveyed from a non-SMM environment into an SMM environment. + @param[in, out] CommBufferSize The size of the CommBuffer. + + @retval EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +ScSxHandler ( + IN EFI_HANDLE Handle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ); + +/** + GbE Sx entry handler. + + @param[in] None + + @retval None + +**/ +VOID +ScLanSxCallback ( + VOID + ); + +/** + This function performs GPIO Sx Isolation steps. + + @param[in] None + + @retval None + +**/ +VOID +ScGpioSxIsolationCallBack ( + VOID + ); + +/** + Register dispatch function to handle GPIO pads Sx isolation + + @param[in] None + + @retval None + +**/ +VOID +InitializeGpioSxIsolationSmm ( + VOID + ); + +/** + Entry point for Sc Bios Write Protect driver. + + @param[in] ImageHandle Image handle of this driver. + @param[in] SystemTable Global system service table. + + @retval EFI_SUCCESS Initialization complete. + +**/ +EFI_STATUS +EFIAPI +InstallScBiosWriteProtect ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf new file mode 100644 index 0000000000..30d01b60e1 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScInitSmm.inf @@ -0,0 +1,81 @@ +## @file +# PchInitSmm driver. +# +# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ScInitSmm + FILE_GUID = D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + ENTRY_POINT = ScInitSmmEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + ScInitSmm.c + ScPcieSmm.c + ScInitSmm.h + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + BroxtonSiPkg/BroxtonSiPrivate.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiDriverEntryPoint + DxeServicesTableLib + IoLib + DebugLib + BaseLib + BaseMemoryLib + S3BootScriptLib + PeiDxeSmmScPciExpressHelpersLib + SmmServicesTableLib + MmPciLib + HobLib + ReportStatusCodeLib + DevicePathLib + ScPlatformLib + TimerLib + ConfigBlockLib + +[Guids] + gSiPolicyHobGuid ## UNDEFINED + gScDeviceTableHobGuid ## UNDEFINED + gScPolicyHobGuid ## UNDEFINED + gPcieRpConfigGuid + +[Protocols] + gEfiSmmSwDispatch2ProtocolGuid ## CONSUMES + gEfiSmmSxDispatch2ProtocolGuid ## CONSUMES + gScSmmIoTrapControlGuid ## CONSUMES + gEfiSmmCpuProtocolGuid ## CONSUMES + gScNvsAreaProtocolGuid ## CONSUMES + gScPcieSmiDispatchProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmBase2ProtocolGuid AND + gEfiSmmSwDispatch2ProtocolGuid AND + gEfiSmmSxDispatch2ProtocolGuid AND + gEfiSmmCpuProtocolGuid + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c new file mode 100644 index 0000000000..afc455b0f7 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/ScInit/Smm/ScPcieSmm.c @@ -0,0 +1,328 @@ +/** @file + PCH Pcie SMM Driver Entry. + + Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+ + 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 "ScInitSmm.h" + +GLOBAL_REMOVE_IF_UNREFERENCED SC_PCIE_DEVICE_OVERRIDE *mDevAspmOverride; +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mNumOfDevAspmOverride; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPolicyRevision; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPchBusNumber; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBusNumMin; +GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mTempRootPortBusNumMax; +GLOBAL_REMOVE_IF_UNREFERENCED SC_PCIE_ROOT_PORT_CONFIG mPcieRootPortConfig[PCIE_MAX_ROOT_PORTS]; +GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mLtrNonSupportRpBitMap; +GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mPciePmSwSmiExecuted = FALSE; + +extern EFI_GUID gScDeviceTableHobGuid; + +/** + PCIE Link Active State Change Hotplug SMI call back function for all Root ports + + @param[in] DispatchHandle Handle of this dispatch function + @param[in] RpContext Rootport context, which contains RootPort Index, + and RootPort PCI BDF. + + @retval None + +**/ +VOID +EFIAPI +ScPcieLinkActiveStateChange ( + IN EFI_HANDLE DispatchHandle, + IN SC_PCIE_SMI_RP_CONTEXT *RpContext + ) +{ + return; +} + + +/** + PCIE Link Equalization Request SMI call back function for all Root ports + + @param[in] DispatchHandle Handle of this dispatch function + @param[in] RpContext Rootport context, which contains RootPort Index, + and RootPort PCI BDF. + + @retval None + +**/ +VOID +EFIAPI +ScPcieLinkEqHandlerFunction ( + IN EFI_HANDLE DispatchHandle, + IN SC_PCIE_SMI_RP_CONTEXT *RpContext + ) +{ + return; +} + + +/** + An IoTrap callback to config PCIE power management settings + + @param[in] None + + @retval None + +**/ +VOID +ScPciePmIoTrapSmiCallback ( + VOID + ) +{ + UINT8 PortIndex; + UINTN RpBase; + UINTN RpDevice; + UINTN RpFunction; + BOOLEAN L1SubstatesSupportedPerPort; + UINT16 AspmVal; + BOOLEAN ClkreqPerPortSupported; + BOOLEAN ClkreqSupportedInAllEnabledPorts; + BOOLEAN L1SupportedInAllEnabledPorts; + BOOLEAN FirstRPToSetPm; + BOOLEAN LtrSupported; + BOOLEAN IsAnyRootPortEnabled; + UINT8 MaxPciePortNum; + + AspmVal = 0; + L1SubstatesSupportedPerPort = FALSE; + ClkreqPerPortSupported = FALSE; + ClkreqSupportedInAllEnabledPorts = TRUE; + L1SupportedInAllEnabledPorts = TRUE; + FirstRPToSetPm = TRUE; + LtrSupported = TRUE; + IsAnyRootPortEnabled = FALSE; + MaxPciePortNum = GetScMaxPciePortNum (); + + for (PortIndex = 0; PortIndex < MaxPciePortNum; PortIndex++) { + GetScPcieRpDevFun (PortIndex, &RpDevice, &RpFunction); + RpBase = MmPciBase (DEFAULT_PCI_BUS_NUMBER_SC, (UINT32) RpDevice, (UINT32) RpFunction); + + if ((MmioRead16 (RpBase) != 0xFFFF) && + ((MmioRead16 (RpBase + R_PCH_PCIE_SLSTS) & B_PCIE_SLSTS_PDS) != 0)) { + PcieCheckPmConfig ( + DEFAULT_PCI_BUS_NUMBER_SC, + (UINT8) RpDevice, + (UINT8) RpFunction, + mNumOfDevAspmOverride, + mDevAspmOverride, + mTempRootPortBusNumMin, + mTempRootPortBusNumMax, + &mPcieRootPortConfig[PortIndex], + &L1SubstatesSupportedPerPort, + mPolicyRevision, + &AspmVal, + &ClkreqPerPortSupported, + &LtrSupported + ); + + if ((AspmVal & V_PCIE_LCTL_ASPM_L1) != V_PCIE_LCTL_ASPM_L1) { + L1SupportedInAllEnabledPorts = FALSE; + } + + if (ClkreqPerPortSupported == FALSE) { + ClkreqSupportedInAllEnabledPorts = FALSE; + } + + if (!LtrSupported) { + mLtrNonSupportRpBitMap |= 1<SwSmiInputValue == mPcieRpConfig->AspmSwSmiNumber) { + if (mPciePmSwSmiExecuted == FALSE) { + ScPciePmIoTrapSmiCallback (); + mPciePmSwSmiExecuted = TRUE; + } + } else { + ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); + } +} + + +/** + This function clear the Io trap executed flag before enter S3 + + @param[in] Handle Handle of the callback + @param[in] Context The dispatch context + @param[in, out] CommBuffer Point to the CommBuffer structure + @param[in, out] CommBufferSize Point to the Size of CommBuffer structure + + @retval EFI_SUCCESS PCH register saved + +**/ +EFI_STATUS +EFIAPI +ScPcieS3EntryCallBack ( + IN EFI_HANDLE Handle, + IN CONST VOID *Context OPTIONAL, + IN OUT VOID *CommBuffer OPTIONAL, + IN OUT UINTN *CommBufferSize OPTIONAL + ) +{ + mPciePmSwSmiExecuted = FALSE; + return EFI_SUCCESS; +} + + +/** + Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling + + @param[in] ImageHandle The image handle of this module + @param[in] SystemTable The EFI System Table + + @retval EFI_SUCCESS The function completes successfully + +**/ +EFI_STATUS +EFIAPI +InitializeScPcieSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE* Hob; + UINT32 DevTableSize; + EFI_HANDLE SwDispatchHandle; + EFI_SMM_SW_REGISTER_CONTEXT SwDispatchContext; + EFI_HANDLE SxDispatchHandle; + EFI_SMM_SX_REGISTER_CONTEXT SxDispatchContext; + UINT8 MaxPciePortNum; + SI_POLICY_HOB *SiPolicyHob; + + DEBUG ((DEBUG_INFO, "InitializeScPcieSmm () Start\n")); + + MaxPciePortNum = GetScMaxPciePortNum (); + + // + // Get Silicon Policy data HOB + // + Hob = GetFirstGuidHob (&gSiPolicyHobGuid); + if (Hob == NULL) { + ASSERT (Hob != NULL); + return EFI_NOT_FOUND; + } + + SiPolicyHob = GET_GUID_HOB_DATA (Hob); + mPolicyRevision = mScPolicy->TableHeader.Header.Revision; + mPchBusNumber = DEFAULT_PCI_BUS_NUMBER_SC; + mTempRootPortBusNumMin = SiPolicyHob->TempPciBusMin; + mTempRootPortBusNumMax = SiPolicyHob->TempPciBusMax; + + ASSERT (sizeof (mPcieRootPortConfig) == sizeof (mPcieRpConfig->RootPort)); + CopyMem ( + mPcieRootPortConfig, + &(mPcieRpConfig->RootPort), + sizeof (mPcieRootPortConfig) + ); + + mDevAspmOverride = NULL; + mNumOfDevAspmOverride = 0; + mLtrNonSupportRpBitMap = 0; + + Hob = GetFirstGuidHob (&gScDeviceTableHobGuid); + if (Hob != NULL) { + DevTableSize = GET_GUID_HOB_DATA_SIZE (Hob); + ASSERT ((DevTableSize % sizeof (SC_PCIE_DEVICE_OVERRIDE)) == 0); + mNumOfDevAspmOverride = DevTableSize / sizeof (SC_PCIE_DEVICE_OVERRIDE); + DEBUG ((DEBUG_INFO, "Found PcieDeviceTable HOB (%d entries)\n", mNumOfDevAspmOverride)); + Status = gSmst->SmmAllocatePool ( + EfiRuntimeServicesData, + DevTableSize, + (VOID **) &mDevAspmOverride + ); + CopyMem (mDevAspmOverride, GET_GUID_HOB_DATA (Hob), DevTableSize); + } + + // + // Register PCIe ASPM SW SMI handler + // + SwDispatchHandle = NULL; + SwDispatchContext.SwSmiInputValue = mPcieRpConfig->AspmSwSmiNumber; + Status = mSwDispatch->Register ( + mSwDispatch, + (EFI_SMM_HANDLER_ENTRY_POINT2) ScPciePmSwSmiCallback, + &SwDispatchContext, + &SwDispatchHandle + ); + ASSERT_EFI_ERROR (Status); + + // + // Register the callback for S3 entry + // + SxDispatchContext.Type = SxS3; + SxDispatchContext.Phase = SxEntry; + Status = mSxDispatch->Register ( + mSxDispatch, + ScPcieS3EntryCallBack, + &SxDispatchContext, + &SxDispatchHandle + ); + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "InitializeScPcieSmm () End\n")); + + return EFI_SUCCESS; +} + -- cgit v1.2.3