From 2155fde63146669d38905df81694b1002ace4795 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Wed, 1 Jun 2016 14:45:10 +0800 Subject: BraswellPlatformPkg: Add AcpiSmm Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.h | 243 ++++++++ BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf | 103 ++++ BraswellPlatformPkg/Acpi/AcpiSmm/Platform.c | 831 +++++++++++++++++++++++++++ BraswellPlatformPkg/Acpi/AcpiSmm/S3Save.c | 402 +++++++++++++ 4 files changed, 1579 insertions(+) create mode 100644 BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.h create mode 100644 BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf create mode 100644 BraswellPlatformPkg/Acpi/AcpiSmm/Platform.c create mode 100644 BraswellPlatformPkg/Acpi/AcpiSmm/S3Save.c diff --git a/BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.h b/BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.h new file mode 100644 index 0000000000..256b8d844a --- /dev/null +++ b/BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.h @@ -0,0 +1,243 @@ +/** @file + SMM handler driver implementation. + + Copyright (c) 2004 - 2015, 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 _PLATFORM_H +#define _PLATFORM_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Protocol/GlobalNvsArea.h" +#include +#include +#include +#include +#include "PchAccess.h" +#include "PlatformBaseAddresses.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + UINT8 Register; + UINT8 Function; + UINT8 Device; + UINT8 Bus; + UINT32 ExtendedRegister; +} SMM_PCI_IO_ADDRESS; + +typedef struct { + CHAR8 BoardAaNumber[7]; + UINTN BoardFabNumber; +} BOARD_AA_NUMBER_DECODE; + +// +// BugBug -- Need to get these two values from acpi.h, but right now, they are +// declared in platform-specific variants of this file, so no easy +// way to pick-up the include file and work across platforms. +// Need these definitions to go into a file like common\acpi.h. +// +#define ACPI_ENABLE 0xA0 +#define ACPI_DISABLE 0xA1 + +#define APM_12_FUNCS 0x50 +#define SMI_SET_SMMVARIABLE_PROTOCOL 0x51 // this is used in Cpu\Pentium\Smm\Base\SmmBase.c + +#define SMI_CMD_GET_MSEG_STATUS 0x70 +#define SMI_CMD_UPDATE_MSEG_SIZE 0x71 +#define SMI_CMD_LOAD_STM 0x72 +#define SMI_CMD_UNLOAD_STM 0x73 +#define SMI_CMD_GET_SMRAM_RANGES 0x74 + +#define PCAT_RTC_ADDRESS_REGISTER 0x74 +#define PCAT_RTC_DATA_REGISTER 0x75 + +#define RTC_ADDRESS_SECOND 0x00 +#define RTC_ADDRESS_SECOND_ALARM 0x01 +#define RTC_ADDRESS_MINUTE 0x02 +#define RTC_ADDRESS_MINUTE_ALARM 0x03 +#define RTC_ADDRESS_HOUR 0x04 +#define RTC_ADDRESS_HOUR_ALARM 0x05 + +#define RTC_ADDRESS_REGISTER_A 0x0A +#define RTC_ADDRESS_REGISTER_B 0x0B +#define RTC_ADDRESS_REGISTER_C 0x0C +#define RTC_ADDRESS_REGISTER_D 0x0D + +#define B_RTC_ALARM_INT_ENABLE 0x20 +#define B_RTC_ALARM_INT_STATUS 0x20 + +#define B_RTC_DATE_ALARM_MASK 0x3F + +#define PCAT_CMOS_2_ADDRESS_REGISTER 0x72 +#define PCAT_CMOS_2_DATA_REGISTER 0x73 + +#define EC_C_PORT 0x66 +#define SMC_SMI_DISABLE 0xBC +#define SMC_ENABLE_ACPI_MODE 0xAA // Enable ACPI mode + +#define IO_MISC 156 + +#define MAXIMUM_NUMBER_OF_PSTATES 12 +#define ICH_SMM_DATA_PORT 0xB3 + +#define EFI_IA32_PMG_CST_CONFIG 0x000000E2 +#define B_EFI_CST_CONTROL_LOCK BIT15 +#define B_EFI_IO_MWAIT_REDIRECTION_ENABLE BIT10 +#define EFI_IA32_PMG_IO_CAPTURE_ADDR 0x000000E4 + +extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo; + +// +// Callback function prototypes +// +EFI_STATUS +EFIAPI +PowerButtonCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +S5SleepWakeOnLanCallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +S5SleepAcLossCallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +S4S5CallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +EnableAcpiCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +DisableAcpiCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +DummyTco1Callback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +VOID +PerrSerrCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +VOID +RiCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +VOID +SetAfterG3On ( + BOOLEAN Enable + ); + +VOID +TurnOffVregUsb ( + ); + +EFI_STATUS +PStateSupportCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +PStateTransitionCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +SxSleepEntryCallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ); + +EFI_STATUS +SaveRuntimeScriptTable ( + VOID + ); + +#endif + diff --git a/BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf b/BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf new file mode 100644 index 0000000000..6f9950266d --- /dev/null +++ b/BraswellPlatformPkg/Acpi/AcpiSmm/AcpiSmm.inf @@ -0,0 +1,103 @@ +## @file +# Component description file for SMM Platform handler module +# +# Provides platform specific handlers for different SMI events. The module will +# register handlers for sleep state transitions as well as other software SMI +# events. +# +# Copyright (c) 1999 - 2015, 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 = PlatformSmm + FILE_GUID = 88802B98-ADFE-4414-A695-FB35CA8D11F2 + MODULE_TYPE = DXE_SMM_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitializePlatformSmm + PI_SPECIFICATION_VERSION = 0x0001000A + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + S3Save.c + Platform.c + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + IoLib + BaseLib + BaseMemoryLib + DevicePathLib + HobLib + S3BootScriptLib + StallSmmLib + PchPlatformLib + ReportStatusCodeLib + +[Guids] + + ## SOMETIMES_CONSUMES ## Variable:L"AcpiGlobalVariable" + gEfiAcpiVariableCompatiblityGuid + + ## SOMETIMES_CONSUMES + gEfiAcpiVariableGuid + +[Protocols] + ## CONSUMES + gEfiSmmIchnDispatchProtocolGuid + + ## CONSUMES + gEfiGlobalNvsAreaProtocolGuid + + ## CONSUMES + gEfiSmmSwDispatch2ProtocolGuid + + ## SOMETIMES_CONSUMES + gEfiSmmPowerButtonDispatch2ProtocolGuid + + ## CONSUMES + gEfiSmmSxDispatch2ProtocolGuid + + ## CONSUMES + gEfiSmmVariableProtocolGuid + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[Pcd] + ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart ## CONSUMES + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdS3AcpiReservedMemorySize ## SOMETIMES_CONSUMES + gEfiEdkIIPlatformTokenSpaceGuid.PcdSystemConfiguration + +[Depex] + gEfiSmmBase2ProtocolGuid AND + gEfiSmmAccess2ProtocolGuid AND + gEfiSmmPowerButtonDispatch2ProtocolGuid AND + gEfiSmmSxDispatch2ProtocolGuid AND + gEfiSmmIchnDispatchProtocolGuid AND + gEfiSmmSwDispatch2ProtocolGuid AND + gEfiVariableArchProtocolGuid + diff --git a/BraswellPlatformPkg/Acpi/AcpiSmm/Platform.c b/BraswellPlatformPkg/Acpi/AcpiSmm/Platform.c new file mode 100644 index 0000000000..bf58f6ca41 --- /dev/null +++ b/BraswellPlatformPkg/Acpi/AcpiSmm/Platform.c @@ -0,0 +1,831 @@ +/** @file + Generic template for a child of the IchSmm driver. + + Copyright (c) 2004 - 2015, 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 "AcpiSmm.h" +#include + +// +// Local variables +// +typedef struct { + UINT8 Device; + UINT8 Function; +} EFI_PCI_BUS_MASTER; + +EFI_PCI_BUS_MASTER mPciBm[] = { + { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 }, + { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 }, + { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 }, + { PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 }, +}; + +UINT16 mAcpiBaseAddr; +SYSTEM_CONFIGURATION mSystemConfiguration; +UINT16 mPM1_SaveState16; +UINT32 mGPE_SaveState32; + +// +// Variables. Need to initialize this from Setup +// +BOOLEAN mWakeOnLanS5Variable; +BOOLEAN mWakeOnRtcVariable; +UINT8 mWakeupDay; +UINT8 mWakeupHour; +UINT8 mWakeupMinute; +UINT8 mWakeupSecond; + +// +// Use an enum. 0 is Stay Off, 1 is Last State, 2 is Stay On +// +UINT8 mAcLossVariable; + +static +UINT8 mTco1Sources[] = { + IchnNmi +}; + +UINTN +DevicePathSize ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +VOID +S4S5ProgClock(); + +EFI_STATUS +InitRuntimeScriptTable ( + IN EFI_SYSTEM_TABLE *SystemTable + ); + +VOID +EnableS5WakeOnRtc(); + +UINT8 +HexToBcd ( + UINT8 HexValue + ); + +UINT8 +BcdToHex( + IN UINT8 BcdValue + ); + +VOID +CpuSmmSxWorkAround ( + ); + + +/*++ + Set the AC Loss to turn on or off. + + @param[in] Turn on or off. + + @retval None + +--*/ + +VOID +SetAfterG3On ( + BOOLEAN Enable + ) +{ + UINT8 PmCon1; + + // + // ICH handling portion + // + PmCon1 = MmioRead8 ( PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 ); + PmCon1 &= ~B_PCH_PMC_GEN_PMCON_AFTERG3_EN; + if (Enable) { + PmCon1 |= B_PCH_PMC_GEN_PMCON_AFTERG3_EN; + } + MmioWrite8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, PmCon1); + +} + +/** + Allocate EfiACPIMemoryNVS below 4G memory address. + + This function allocates EfiACPIMemoryNVS below 4G memory address. + + @param Size Size of memory to allocate. + + @return Allocated address for output. + +**/ +VOID* +AllocateAcpiNvsMemoryBelow4G ( + IN UINTN Size + ) +{ + UINTN Pages; + EFI_PHYSICAL_ADDRESS Address; + EFI_STATUS Status; + VOID* Buffer; + + Pages = EFI_SIZE_TO_PAGES (Size); + Address = 0xffffffff; + + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + Pages, + &Address + ); + ASSERT_EFI_ERROR (Status); + + Buffer = (VOID *) (UINTN) Address; + ZeroMem (Buffer, Size); + + return Buffer; +} + +EFI_STATUS +EFIAPI +AllocateS3AcpiReservedMemory ( + VOID +) +{ + EFI_PEI_HOB_POINTERS Hob; + UINT64 MemoryLength; + RESERVED_ACPI_S3_RANGE *AcpiS3Range; + EFI_SMRAM_DESCRIPTOR *SmramDescriptor; + VOID *GuidHob; + VOID *AcpiReservedBase; + + // + // Calculate the system memory length by memory hobs + // + MemoryLength = 0x100000; + + Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR); + if (Hob.Raw == NULL) { + return EFI_NOT_FOUND; + } + + while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) { + if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + // + // Skip the memory region below 1MB + // + if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) { + MemoryLength += Hob.ResourceDescriptor->ResourceLength; + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw); + } + + // + // Find the location of reserved page in TSEG. This was reserved by the MRC. + // + GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid); + if (GuidHob != NULL) { + SmramDescriptor = (EFI_SMRAM_DESCRIPTOR*) GET_GUID_HOB_DATA (GuidHob); + + // + // Now find the location of the data structure that is used to store the address + // of the S3 reserved memory. + // + AcpiS3Range = (RESERVED_ACPI_S3_RANGE*) (UINTN) (SmramDescriptor->PhysicalStart + + RESERVED_ACPI_S3_RANGE_OFFSET); + + // + // Allocate reserved ACPI memory for S3 resume. Pointer to this region is + // stored in SMRAM in the first page of TSEG. + // + AcpiReservedBase = AllocateAcpiNvsMemoryBelow4G ( + PcdGet32 (PcdS3AcpiReservedMemorySize) + ); + if (AcpiReservedBase != NULL) { + AcpiS3Range->AcpiReservedMemoryBase = (UINT32)(UINTN) AcpiReservedBase; + AcpiS3Range->AcpiReservedMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize); + } + + AcpiS3Range->SystemMemoryLength = (UINT32)MemoryLength; + + DEBUG ((EFI_D_ERROR, "S3 Memory Base: %08X\n", AcpiS3Range->AcpiReservedMemoryBase)); + DEBUG ((EFI_D_ERROR, "S3 Memory Size: %08X\n", AcpiS3Range->AcpiReservedMemorySize)); + DEBUG ((EFI_D_ERROR, "S3 SysMemoryLength: %08X\n", AcpiS3Range->SystemMemoryLength)); + } + + return EFI_SUCCESS; + +} + + +/** + Initializes the SMM Handler Driver + + @param[in] ImageHandle + @param[in] SystemTable + + @retval None + +**/ +EFI_STATUS +EFIAPI +InitializePlatformSmm ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PowerButtonContext; + EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *PowerButtonDispatch; + EFI_SMM_ICHN_DISPATCH_PROTOCOL *IchnDispatch; + EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch; + EFI_SMM_SX_REGISTER_CONTEXT EntryDispatchContext; + EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch; + EFI_SMM_SW_REGISTER_CONTEXT SwContext; + EFI_BOOT_MODE BootMode; + + Handle = NULL; + + // + // Get the ACPI Base Address + // + + mAcpiBaseAddr = PchLpcPciCfg16( R_PCH_LPC_ACPI_BASE ) & B_PCH_LPC_ACPI_BASE_BAR; + + CopyMem (&mSystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof (SYSTEM_CONFIGURATION)); + mAcLossVariable = mSystemConfiguration.StateAfterG3; + mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5; + + BootMode = GetBootModeHob (); + + // + // Get the Power Button protocol + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmPowerButtonDispatch2ProtocolGuid, + NULL, + (VOID **) &PowerButtonDispatch + ); + ASSERT_EFI_ERROR (Status); + + if (BootMode != BOOT_ON_FLASH_UPDATE) { + // + // Register for the power button event + // + PowerButtonContext.Phase = EfiPowerButtonEntry; + Status = PowerButtonDispatch->Register ( + PowerButtonDispatch, + PowerButtonCallback, + &PowerButtonContext, + &Handle + ); + ASSERT_EFI_ERROR (Status); + } + // + // Get the Sx dispatch protocol + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSxDispatch2ProtocolGuid, + NULL, + (VOID **) &SxDispatch + ); + ASSERT_EFI_ERROR (Status); + + // + // Register entry phase call back function + // + EntryDispatchContext.Type = SxS3; + EntryDispatchContext.Phase = SxEntry; + + Status = SxDispatch->Register ( + SxDispatch, + SxSleepEntryCallBack, + &EntryDispatchContext, + &Handle + ); + + EntryDispatchContext.Type = SxS4; + + Status = SxDispatch->Register ( + SxDispatch, + S4S5CallBack, + &EntryDispatchContext, + &Handle + ); + ASSERT_EFI_ERROR (Status); + + EntryDispatchContext.Type = SxS5; + + Status = SxDispatch->Register ( + SxDispatch, + S4S5CallBack, + &EntryDispatchContext, + &Handle + ); + ASSERT_EFI_ERROR (Status); + + Status = SxDispatch->Register ( + SxDispatch, + S5SleepAcLossCallBack, + &EntryDispatchContext, + &Handle + ); + ASSERT_EFI_ERROR (Status); + + // + // Get the Sw dispatch protocol + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmSwDispatch2ProtocolGuid, + NULL, + (VOID **) &SwDispatch + ); + ASSERT_EFI_ERROR (Status); + + // + // Register ACPI enable handler + // + SwContext.SwSmiInputValue = ACPI_ENABLE; + Status = SwDispatch->Register ( + SwDispatch, + EnableAcpiCallback, + &SwContext, + &Handle + ); + ASSERT_EFI_ERROR (Status); + + // + // Register ACPI disable handler + // + SwContext.SwSmiInputValue = ACPI_DISABLE; + Status = SwDispatch->Register ( + SwDispatch, + DisableAcpiCallback, + &SwContext, + &Handle + ); + ASSERT_EFI_ERROR (Status); + + // + // Get the ICHn protocol + // + Status = gSmst->SmmLocateProtocol ( + &gEfiSmmIchnDispatchProtocolGuid, + NULL, + (VOID **) &IchnDispatch + ); + ASSERT_EFI_ERROR (Status); + + SetAfterG3On (TRUE); + + AllocateS3AcpiReservedMemory (); + + return EFI_SUCCESS; +} + +/** + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] DispatchContext The predefined context which contained sleep type and phase + + @retval EFI_SUCCESS Operation successfully performed + +**/ +EFI_STATUS +SxSleepEntryCallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) + +{ +// +// EFI_STATUS Status; +// +// REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeS3SuspendStart)); +// Status = SaveRuntimeScriptTable (); +// if (EFI_ERROR (Status)) { +// return Status; +// } +// + return EFI_SUCCESS; +} + +/** + When a power button event happens, it shuts off the machine. + + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] DispatchContext The predefined context which contained sleep type and phase + + @retval + +**/ +EFI_STATUS +PowerButtonCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + + UINT16 data16; + + // + // Set what the state to return to after AC Loss. If Last State, then + // set it to Off. + // + SetAfterG3On (TRUE); + + if (mWakeOnRtcVariable) { + EnableS5WakeOnRtc(); + } + + data16 = (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN)); + data16 &= B_PCH_ACPI_GPE0a_EN_PCI_EXP; + + // + // Clear Sleep SMI Status + // + IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_STS, + (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_SMI_STS) | B_PCH_SMI_STS_ON_SLP_EN)); + // + // Clear Sleep Type Enable + // + IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_EN, + (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_SMI_EN) & (~B_PCH_SMI_EN_ON_SLP_EN))); + + // + // Clear Power Button Status + // + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN); + + // + // Shut it off now! + // + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5); + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, B_PCH_ACPI_PM1_CNT_SLP_EN | V_PCH_ACPI_PM1_CNT_S5); + + // + // Should not return + // + return EFI_SUCCESS; +} + +/** + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] DispatchContext The predefined context which contained sleep type and phase + +**/ +EFI_STATUS +EFIAPI +S5SleepAcLossCallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +/** + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] DispatchContext The predefined context which contained sleep type and phase + + @retval Clears the Save State bit in the clock. + +**/ +EFI_STATUS +EFIAPI +S4S5CallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +VOID +S4S5ProgClock() +{ +} + +/** + SMI handler to enable ACPI mode + + Dispatched on reads from APM port with value 0xA0 + + Disables the SW SMI Timer. + ACPI events are disabled and ACPI event status is cleared. + SCI mode is then enabled. + + Disable SW SMI Timer + + Clear all ACPI event status and disable all ACPI events + Disable PM sources except power button + Clear status bits + + Disable GPE0 sources + Clear status bits + + Disable GPE1 sources + Clear status bits + + Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm") + + Enable SCI + + @param[in] DispatchHandle EFI Handle + @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT + + @retval Nothing + +**/ +EFI_STATUS +EFIAPI +EnableAcpiCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + UINT16 Pm1Cnt; + + // + // Enable SCI + // + Pm1Cnt = IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT); + Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN; + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt); + + return EFI_SUCCESS; +} + +/** + SMI handler to disable ACPI mode + + Dispatched on reads from APM port with value 0xA1 + + ACPI events are disabled and ACPI event status is cleared. + SCI mode is then disabled. + Clear all ACPI event status and disable all ACPI events + Disable PM sources except power button + Clear status bits + Disable GPE0 sources + Clear status bits + Disable GPE1 sources + Clear status bits + Disable SCI + + @param[in] DispatchHandle EFI Handle + @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT + + @retval Nothing + +**/ +EFI_STATUS +EFIAPI +DisableAcpiCallback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + UINT16 Pm1Cnt; + + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff); + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, mPM1_SaveState16); + + IoWrite32 (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff); + IoWrite32 (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, mGPE_SaveState32); + + // + // Disable SCI + // + Pm1Cnt = IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT); + Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SCI_EN; + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt); + + return EFI_SUCCESS; +} + +/** + When an unknown event happen. + + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] DispatchContext The predefined context which contained sleep type and phase + + @retval None + +**/ +EFI_STATUS +EFIAPI +DummyTco1Callback ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +UINTN +DevicePathSize ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL *Start; + + if (DevicePath == NULL) { + return 0; + } + + // + // Search for the end of the device path structure + // + Start = DevicePath; + while (!IsDevicePathEnd (DevicePath)) { + DevicePath = NextDevicePathNode (DevicePath); + } + + // + // Compute the size and add back in the size of the end device path structure + // + return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL); +} + +/** + @param[in] DispatchHandle The handle of this callback, obtained when registering + @param[in] DispatchContext The predefined context which contained sleep type and phase + +**/ +EFI_STATUS +S5SleepWakeOnRtcCallBack ( + IN EFI_HANDLE DispatchHandle, + IN CONST VOID *DispatchContext, + IN OUT VOID *CommBuffer OPTIONAL, + IN UINTN *CommBufferSize OPTIONAL + ) +{ + EnableS5WakeOnRtc(); + + return EFI_SUCCESS; +} + +/** + @retval 1. Check Alarm interrupt is not set. + 2. Clear Alarm interrupt. + 2. Set RTC wake up date and time. + 2. Enable RTC wake up alarm. + 3. Enable ICH PM1 EN Bit 10(RTC_EN) + +**/ +VOID +EnableS5WakeOnRtc() +{ + UINT8 CmosData; + UINTN i; + + if (!mSystemConfiguration.WakeOnRtcS5) { + return; + } + mWakeupDay = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupDate); + mWakeupHour = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupTimeHour); + mWakeupMinute = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupTimeMinute); + mWakeupSecond = HexToBcd((UINT8) mSystemConfiguration.RTCWakeupTimeSecond); + + // + // Check RTC alarm interrupt is enabled. If enabled, someone already + // grabbed RTC alarm. Just return. + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B); + if (IoRead8 (PCAT_RTC_DATA_REGISTER) & B_RTC_ALARM_INT_ENABLE) { + return; + } + + // + // Set Date + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D); + CmosData = IoRead8 (PCAT_RTC_DATA_REGISTER); + CmosData &= ~(B_RTC_DATE_ALARM_MASK); + CmosData |= mWakeupDay; + for (i = 0; i < 0xffff; i++) { + IoWrite8 (PCAT_RTC_DATA_REGISTER, CmosData); + SmmStall (1); + if(((CmosData = IoRead8 (PCAT_RTC_DATA_REGISTER)) & B_RTC_DATE_ALARM_MASK) + == mWakeupDay) { + break; + } + } + + // + // Set Second + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECOND_ALARM); + for (i = 0; i < 0xffff; i++) { + IoWrite8 (PCAT_RTC_DATA_REGISTER, mWakeupSecond); + SmmStall (1); + if (IoRead8 (PCAT_RTC_DATA_REGISTER) == mWakeupSecond) { + break; + } + } + + // + // Set Minute + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTE_ALARM); + for (i = 0; i < 0xffff; i++) { + IoWrite8 (PCAT_RTC_DATA_REGISTER, mWakeupMinute); + SmmStall (1); + if (IoRead8 (PCAT_RTC_DATA_REGISTER) == mWakeupMinute) { + break; + } + } + + // + // Set Hour + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOUR_ALARM); + for (i = 0; i < 0xffff; i++) { + IoWrite8 (PCAT_RTC_DATA_REGISTER, mWakeupHour); + SmmStall (1); + if (IoRead8 (PCAT_RTC_DATA_REGISTER) == mWakeupHour) { + break; + } + } + + // + // Wait for UIP to arm RTC alarm + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A); + while (IoRead8 (PCAT_RTC_DATA_REGISTER) & 0x80); + + // + // Read RTC register 0C to clear pending RTC interrupts + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C); + IoRead8 (PCAT_RTC_DATA_REGISTER); + + // + // Enable RTC Alarm Interrupt + // + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B); + IoWrite8 (PCAT_RTC_DATA_REGISTER, IoRead8 (PCAT_RTC_DATA_REGISTER) | B_RTC_ALARM_INT_ENABLE); + + // + // Clear ICH RTC Status + // + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_RTC); + + // + // Enable ICH RTC event + // + IoWrite16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, + (UINT16) (IoRead16 (mAcpiBaseAddr + R_PCH_ACPI_PM1_EN) | B_PCH_ACPI_PM1_EN_RTC)); +} + +UINT8 +HexToBcd ( + IN UINT8 HexValue + ) +{ + UINTN HighByte; + UINTN LowByte; + + HighByte = (UINTN) HexValue / 10; + LowByte = (UINTN) HexValue % 10; + + return ((UINT8) (LowByte + (HighByte << 4))); +} + +UINT8 +BcdToHex ( + IN UINT8 BcdValue + ) +{ + UINTN HighByte; + UINTN LowByte; + + HighByte = (UINTN) ((BcdValue >> 4) * 10); + LowByte = (UINTN) (BcdValue & 0x0F); + + return ((UINT8) (LowByte + HighByte)); +} + diff --git a/BraswellPlatformPkg/Acpi/AcpiSmm/S3Save.c b/BraswellPlatformPkg/Acpi/AcpiSmm/S3Save.c new file mode 100644 index 0000000000..690cb12b88 --- /dev/null +++ b/BraswellPlatformPkg/Acpi/AcpiSmm/S3Save.c @@ -0,0 +1,402 @@ +/** @file + SMM S3 handler driver implementation. + + Copyright (c) 2004 - 2015, 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 "AcpiSmm.h" + +extern UINT16 mAcpiBaseAddr; +EFI_PHYSICAL_ADDRESS mRuntimeScriptTableBase; + +EFI_STATUS +SaveRuntimeScriptTable ( + VOID + ) +{ + SMM_PCI_IO_ADDRESS PciAddress; + UINT32 Data32; + UINT16 Data16; + UINT8 Data8; + UINT8 Mask; + UINTN Index; + UINTN Offset; + UINT8 RegTable[] = { + + //Bus , Dev, Func, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + + //Bus , Dev, Func, CUnit Device + 0x00 , 0x00, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0, + + //Bus , Dev, Func, IGD Device + 0x00 , 0x02, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x81, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, + + //Bus , Dev, Func, IUnit Device + 0x00 , 0x03, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, ISH Device + 0x00 , 0x0A, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, PUnit Device + 0x00 , 0x0B, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, eMMC Device + 0x00 , 0x10, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, SDIO Device + 0x00 , 0x11, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, SDCard Device + 0x00 , 0x12, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // + //Bus , Dev, Func, SATA Device + 0x00 , 0x13, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0xA3, 0x27, 0x30, 0xF1, 0x1D, 0x00, 0x40, + + // + //Bus , Dev, Func, xHCI Device + 0x00 , 0x14, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + + //Bus , Dev, Func, LPE Device + 0x00 , 0x15, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, USB OTG Device + 0x00 , 0x16, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 DMA Device + 0x00 , 0x18, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C0 Device + 0x00 , 0x18, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C1 Device + 0x00 , 0x18, 0x02, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C2 Device + 0x00 , 0x18, 0x03, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C3 Device + 0x00 , 0x18, 0x04, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C4 Device + 0x00 , 0x18, 0x05, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C5 Device + 0x00 , 0x18, 0x06, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO2 I2C6 Device + 0x00 , 0x18, 0x07, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, SEC Device + 0x00 , 0x1A, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + + //Bus , Dev, Func, HD Audio Device + 0x00 , 0x1B, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + // + //Bus , Dev, Func, SMBUS device + // + //Bus , Dev, Func, PCIe Root Port #1 + 0x00 , 0x1C, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, PCIe Root Port #2 + 0x00 , 0x1C, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, PCIe Root Port #3 + 0x00 , 0x1C, 0x02, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, PCIe Root Port #4 + 0x00 , 0x1C, 0x03, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xC2 , 0x8F, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + + // + //Bus , Dev, Func, VGA bus1 + // + //Bus , Dev, Func, LPIO1 DMA Device + 0x00 , 0x1E, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 PWM0 Device + 0x00 , 0x1E, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 PWM1 Device + 0x00 , 0x1E, 0x02, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 HSUART0 Device + 0x00 , 0x1E, 0x03, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 HSUART1 Device + 0x00 , 0x1E, 0x04, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 SPI Device + 0x00 , 0x1E, 0x05, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 SPI2 Device + 0x00 , 0x1E, 0x06, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, LPIO1 SPI3 Device + 0x00 , 0x1E, 0x07, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xF2 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, PCU Device + 0x00 , 0x1F, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x00 , 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, SMBUS Device + 0x00 , 0x1F, 0x03, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x32 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // + //Bus , Dev, Func, Bus 1 Function 0 + 0x01 , 0x00, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0x58 , 0x93, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 1 Function 1 + 0x01 , 0x00, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 2 Function 0 + 0x02 , 0x00, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 2 Function 1 + 0x02 , 0x00, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 3 Function 0 + 0x03 , 0x00, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 3 Function 1 + 0x03 , 0x00, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 4 Function 0 + 0x04 , 0x00, 0x00, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + //Bus , Dev, Func, Bus 4 Function 1 + 0x04 , 0x00, 0x01, + //00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF + 0xFA , 0x93, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, + + // + //0xFF indicates the end of the table + // + 0xFF + }; + + // + // These registers have to set in byte order + // + UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings + + // + // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM + // and vital to S3 resume. That's why we put save code here + // + PciAddress.Bus = 0; + PciAddress.Device = 0; + PciAddress.Function = 0; + PciAddress.ExtendedRegister = 0; + + for (Index = 0; Index < 2; Index++) { + // + // Read SRAM setting from Pci(0, 0, 0) + // + PciAddress.Register = ExtReg[Index]; + Data8 = MmioRead8 ( + MmPciAddress (0, + PciAddress.Bus, + PciAddress.Device, + PciAddress.Function, + PciAddress.Register + ) + ); + + // + // Save latest settings to runtime script table + // + S3BootScriptSavePciCfgWrite ( + S3BootScriptWidthUint8, + *(UINT64 *) &PciAddress, + 1, + &Data8 + ); + } + + // + // Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM + // and vital to S3 resume. That's why we put save code here + // + Index = 0; + while (RegTable[Index] != 0xFF) { + + PciAddress.Bus = RegTable[Index++]; + PciAddress.Device = RegTable[Index++]; + PciAddress.Function = RegTable[Index++]; + PciAddress.Register = 0; + PciAddress.ExtendedRegister = 0; + + Data16 = MmioRead16 ( + MmPciAddress (0, + PciAddress.Bus, + PciAddress.Device, + PciAddress.Function, + PciAddress.Register + ) + ); + + if (Data16 == 0xFFFF) { + Index+=8; + continue; + } + + for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) { + + if (Mask == 0x00) { + Mask = 0x01; + } + + if (RegTable[Index + Offset/32] & Mask ) { + + PciAddress.Register = (UINT8) Offset; + Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register)); + + // + // Save latest settings to runtime script table + // + S3BootScriptSavePciCfgWrite ( + S3BootScriptWidthUint32, + *(UINT64 *) &PciAddress, + 1, + &Data32 + ); + } + } + + Index += 8; + + } + + // + // Save I/O ports to S3 script table + // + + // + // Selftest KBC + // + Data8 = 0xAA; + S3BootScriptSaveIoWrite ( + S3BootScriptWidthUint8, + 0x64, + (UINTN)1, + &Data8 + ); + + Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN); + + S3BootScriptSaveIoWrite ( + S3BootScriptWidthUint32, + (mAcpiBaseAddr + R_PCH_SMI_EN), + 1, + &Data32 + ); + + // + // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path. + // + Data16 = IoRead16 (mAcpiBaseAddr + R_PCH_TCO_CNT); + + S3BootScriptSaveIoWrite ( + S3BootScriptWidthUint16, + mAcpiBaseAddr + R_PCH_TCO_CNT, + 1, + &Data16 + ); + + return EFI_SUCCESS; +} -- cgit v1.2.3