From 8b318f28649a52dc7c6028bc84a7502adef9c300 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Fri, 23 Dec 2016 12:56:23 +0800 Subject: BroxtonSiPkg: Add SmmControl Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../SouthCluster/SmmControl/Pei/SmmControl.inf | 44 +++ .../SouthCluster/SmmControl/Pei/SmmControlDriver.c | 260 +++++++++++++ .../SouthCluster/SmmControl/Pei/SmmControlDriver.h | 92 +++++ .../SmmControl/RuntimeDxe/SmmControl.inf | 56 +++ .../SmmControl/RuntimeDxe/SmmControlDriver.c | 402 +++++++++++++++++++++ .../SmmControl/RuntimeDxe/SmmControlDriver.h | 152 ++++++++ 6 files changed, 1006 insertions(+) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h (limited to 'Silicon') diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf new file mode 100644 index 0000000000..d882458328 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControl.inf @@ -0,0 +1,44 @@ +## @file +# SmmControl 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 = PeiSmmControl + FILE_GUID = FF456B9C-0DC7-4682-9E92-0DE84B6E4067 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = SmmControlPeiDriverEntryInit + +[Sources] + SmmControlDriver.h + SmmControlDriver.c + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + +[LibraryClasses] + PeimEntryPoint + IoLib + DebugLib + PcdLib + +[Pcd] + gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress ## SOMETIMES_CONSUMES + +[Protocols] + +[Depex] + TRUE diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c new file mode 100644 index 0000000000..479f9b13ed --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.c @@ -0,0 +1,260 @@ +/** @file + This is the driver that publishes the SMM Control Ppi. + + 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 "SmmControlDriver.h" + +EFI_GUID mPeiSmmControlPpiGuid = PEI_SMM_CONTROL_PPI_GUID; + +STATIC PEI_SMM_CONTROL_PPI mSmmControlPpi = { + PeiActivate, + PeiDeactivate +}; + + +STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &mPeiSmmControlPpiGuid, + &mSmmControlPpi +}; + + +/** + This is the constructor for the SMM Control ppi + + @param[in] FfsHeader FfsHeader. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_STATUS Results of the installation of the SMM Control Ppi + +**/ +EFI_STATUS +EFIAPI +SmmControlPeiDriverEntryInit ( + IN EFI_PEI_FILE_HANDLE FfsHeader, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList); + ASSERT_EFI_ERROR (Status); + + return Status; +} + + +/** + Trigger the software SMI + + @param[in] Data The value to be set on the software SMI data port + + @retval EFI_SUCCESS Function completes successfully + +**/ +EFI_STATUS +EFIAPI +SmmTrigger ( + IN UINT8 Data + ) +{ + UINT32 OutputData; + UINT32 OutputPort; + UINT16 AcpiBaseAddr; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Enable the APMC SMI + // + OutputPort = AcpiBaseAddr + R_SMI_EN; + OutputData = IoRead32 ((UINTN) OutputPort); + OutputData |= (B_SMI_EN_APMC | B_SMI_EN_GBL_SMI); + + IoWrite32 ( + (UINTN) OutputPort, + (UINT32) (OutputData) + ); + + OutputPort = R_APM_CNT; + OutputData = Data; + + // + // Generate the APMC SMI + // + IoWrite8 ( + (UINTN) OutputPort, + (UINT8) (OutputData) + ); + + return EFI_SUCCESS; +} + + +/** + Clear the SMI status + + @param[in] None + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_DEVICE_ERROR Something error occurred + +**/ +EFI_STATUS +EFIAPI +SmmClear ( + VOID + ) +{ + UINT32 OutputData; + UINT32 OutputPort; + UINT16 AcpiBaseAddr; + + // + // Read ACPI Base Address + // + AcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + + // + // Clear the Power Button Override Status Bit, it gates EOS from being set. + // + OutputPort = AcpiBaseAddr + R_ACPI_PM1_STS; + OutputData = B_ACPI_PM1_STS_PRBTNOR; + + IoWrite16 ( + (UINTN) OutputPort, + (UINT16) (OutputData) + ); + + // + // Clear the APM SMI Status Bit + // + OutputPort = AcpiBaseAddr + R_SMI_STS; + OutputData = B_SMI_STS_APM; + IoWrite32 ( + (UINTN) OutputPort, + (UINT32) (OutputData) + ); + + // + // Set the EOS Bit + // + OutputPort = AcpiBaseAddr + R_SMI_EN; + OutputData = IoRead32 ((UINTN) OutputPort); + OutputData |= B_SMI_EN_EOS; + + IoWrite32 ( + (UINTN) OutputPort, + (UINT32) (OutputData) + ); + + // + // If the EOS bit did not get set, then we've got a problem. + // + DEBUG_CODE ( + OutputData = IoRead32 ((UINTN) OutputPort); + if ((OutputData & B_SMI_EN_EOS) != B_SMI_EN_EOS) { + DEBUG ((EFI_D_ERROR, "Bugger, EOS did not get set!\n")); + return EFI_DEVICE_ERROR; + } + ); + + return EFI_SUCCESS; +} + + +/** + This routine generates an SMI + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The EFI SMM Control ppi instance + @param[in, out] ArgumentBuffer The buffer of argument + @param[in, out] ArgumentBufferSize The size of the argument buffer + @param[in] Periodic Periodic or not + @param[in] ActivationInterval Interval of periodic SMI + + @retval EFI Status Describing the result of the operation + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported + +**/ +EFI_STATUS +EFIAPI +PeiActivate ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_CONTROL_PPI *This, + IN OUT INT8 *ArgumentBuffer OPTIONAL, + IN OUT UINTN *ArgumentBufferSize OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL + ) +{ + EFI_STATUS Status; + UINT8 Data; + + if (Periodic) { + DEBUG ((EFI_D_WARN, "Invalid parameter\n")); + return EFI_INVALID_PARAMETER; + } + + if (ArgumentBuffer == NULL) { + Data = 0xFF; + } else { + if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) { + return EFI_INVALID_PARAMETER; + } + + Data = *ArgumentBuffer; + } + + // + // Clear any pending the APM SMI + // + Status = SmmClear (); + if (EFI_ERROR (Status)) { + return Status; + } + + return SmmTrigger (Data); +} + + +/** + This routine clears an SMI + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The EFI SMM Control ppi instance + @param[in] Periodic Periodic or not + + @retval EFI Status Describing the result of the operation + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported + +**/ +EFI_STATUS +EFIAPI +PeiDeactivate ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_CONTROL_PPI *This, + IN BOOLEAN Periodic OPTIONAL + ) +{ + if (Periodic) { + return EFI_INVALID_PARAMETER; + } + + return SmmClear (); +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h new file mode 100644 index 0000000000..d08b876285 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/Pei/SmmControlDriver.h @@ -0,0 +1,92 @@ +/** @file + Header file for SMM Control 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. + +**/ + +#ifndef _EFI_PEI_SMM_CONTROL_DRIVER_H_ +#define _EFI_PEI_SMM_CONTROL_DRIVER_H_ + +/// +/// Driver private data +/// +#include +#include "Ppi/SmmControl.h" +#include +#include +#include + +/// +/// Prototypes +/// +/** + This is the constructor for the SMM Control ppi + + @param[in] FfsHeader FfsHeader. + @param[in] PeiServices General purpose services available to every PEIM. + + @retval EFI_STATUS Results of the installation of the SMM Control Ppi + +**/ +EFI_STATUS +EFIAPI +SmmControlPeiDriverEntryInit ( + IN EFI_PEI_FILE_HANDLE FfsHeader, + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + This routine generates an SMI. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The EFI SMM Control ppi instance. + @param[in, out] ArgumentBuffer The buffer of argument. + @param[in, out] ArgumentBufferSize The size of the argument buffer. + @param[in] Periodic Periodic or not + @param[in] ActivationInterval Interval of periodic SMI. + + @retval EFI Status Describing the result of the operation. + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported. + +**/ +EFI_STATUS +EFIAPI +PeiActivate ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_CONTROL_PPI *This, + IN OUT INT8 *ArgumentBuffer OPTIONAL, + IN OUT UINTN *ArgumentBufferSize OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL + ); + +/** + This routine clears an SMI. + + @param[in] PeiServices General purpose services available to every PEIM. + @param[in] This The EFI SMM Control ppi instance. + @param[in] Periodic Periodic or not. + + @retval EFI Status Describing the result of the operation. + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported. + +**/ +EFI_STATUS +EFIAPI +PeiDeactivate ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_SMM_CONTROL_PPI *This, + IN BOOLEAN Periodic OPTIONAL + ); + +#endif + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf new file mode 100644 index 0000000000..af5bb1b145 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf @@ -0,0 +1,56 @@ +## @file +# Component description file for SmmControl module +# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = SmmControl + FILE_GUID = A0BAD9F7-AB78-491b-B583-C52B7F84B9E0 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_RUNTIME_DRIVER + ENTRY_POINT = SmmControlDriverEntryInit + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + +[LibraryClasses] + IoLib + UefiDriverEntryPoint + DebugLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress + +[Sources] + SmmControlDriver.h + SmmControlDriver.c + +[Protocols] + gEfiSmmControl2ProtocolGuid + +[Guids] + gEfiEventVirtualAddressChangeGuid + +[Depex] + TRUE diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c new file mode 100644 index 0000000000..83576434b5 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c @@ -0,0 +1,402 @@ +/** @file + This is the driver that publishes the SMM Control Protocol. + + 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 "SmmControlDriver.h" +#include + +STATIC SMM_CONTROL_PRIVATE_DATA mSmmControl; +GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mAcpiBaseAddr; + +VOID +EFIAPI +DisablePendingSmis ( + VOID + ); + + +/** + Fixup internal data pointers so that the services can be called in virtual mode. + + @param[in] Event The event registered. + @param[in] Context Event context. + +**/ +VOID +EFIAPI +SmmControlVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.Trigger)); + gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.Clear)); +} + + +/** + SmmControl DXE RUNTIME Module Entry Point\n + - Introduction\n + The SmmControl module is a DXE RUNTIME driver that provides a standard way + for other drivers to trigger software SMIs. + + - @pre + - SC Power Management I/O space base address has already been programmed. + If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol + is installed and there is the need to use Status code in the driver, it will + be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file. + - EFI_SMM_BASE2_PROTOCOL + - Documented in the System Management Mode Core Interface Specification. + + - @result + The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in + System Management Mode Core Interface Specification. + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_STATUS Results of the installation of the SMM Control Protocol + +**/ +EFI_STATUS +EFIAPI +SmmControlDriverEntryInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() Start\n")); + + // + // Get the Power Management I/O space base address. We assume that + // this base address has already been programmed if this driver is + // being run. + // + mAcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress); + Status = EFI_SUCCESS; + if (mAcpiBaseAddr != 0) { + // + // Install the instance of the protocol + // + mSmmControl.Signature = SMM_CONTROL_PRIVATE_DATA_SIGNATURE; + mSmmControl.Handle = ImageHandle; + + mSmmControl.SmmControl.Trigger = Activate; + mSmmControl.SmmControl.Clear = Deactivate; + mSmmControl.SmmControl.MinimumTriggerPeriod = 0; + + // + // Install our protocol interfaces on the device's handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mSmmControl.Handle, + &gEfiSmmControl2ProtocolGuid, + &mSmmControl.SmmControl, + NULL + ); + } else { + Status = EFI_DEVICE_ERROR; + return Status; + } + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + SmmControlVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &Event + ); + + // + // Disable any SC SMIs that, for whatever reason, are asserted after the boot. + // + DisablePendingSmis (); + + DEBUG ((DEBUG_INFO, "SmmControlDriverEntryInit() End\n")); + + return Status; +} + + +/** + Trigger the software SMI + + @param[in] Data The value to be set on the software SMI data port + + @retval EFI_SUCCESS Function completes successfully + +**/ +EFI_STATUS +EFIAPI +SmmTrigger ( + IN UINT8 Data + ) +{ + UINT32 OutputData; + UINT32 OutputPort; + + // + // Enable the APMC SMI + // + OutputPort = mAcpiBaseAddr + R_SMI_EN; + OutputData = IoRead32 ((UINTN) OutputPort); + OutputData |= (B_SMI_EN_APMC | B_SMI_EN_GBL_SMI); + + IoWrite32 ( + (UINTN) OutputPort, + (UINT32) (OutputData) + ); + + OutputPort = R_APM_CNT; + OutputData = Data; + + // + // Generate the APMC SMI + // + IoWrite8 ( + (UINTN) OutputPort, + (UINT8) (OutputData) + ); + + return EFI_SUCCESS; +} + + +/** + Clear the SMI status + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_DEVICE_ERROR Something error occurred + +**/ +EFI_STATUS +EFIAPI +SmmClear ( + VOID + ) +{ + EFI_STATUS Status; + UINT32 OutputData; + UINT32 OutputPort; + + Status = EFI_SUCCESS; + + // + // Clear the Power Button Override Status Bit, it gates EOS from being set. + // + OutputPort = mAcpiBaseAddr + R_ACPI_PM1_STS; + OutputData = B_ACPI_PM1_STS_PRBTNOR; + + IoWrite16 ( + (UINTN) OutputPort, + (UINT16) (OutputData) + ); + + // + // Clear the APM SMI Status Bit + // + OutputPort = mAcpiBaseAddr + R_SMI_STS; + OutputData = B_SMI_STS_APM; + + IoWrite32 ( + (UINTN) OutputPort, + (UINT32) (OutputData) + ); + + // + // Set the EOS Bit + // + OutputPort = mAcpiBaseAddr + R_SMI_EN; + OutputData = IoRead32 ((UINTN) OutputPort); + OutputData |= B_SMI_EN_EOS; + + IoWrite32 ( + (UINTN) OutputPort, + (UINT32) (OutputData) + ); + + // + // There is no need to read EOS back and check if it is set. + // This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read + // but before the data is returned to the CPU. + // SMM Dispatcher should make sure that EOS is set after all SMI sources are processed. + // + return Status; +} + + +/** + This routine generates an SMI + + @param[in] This The EFI SMM Control protocol instance + @param[in, out] ArgumentBuffer The buffer of argument + @param[in, out] ArgumentBufferSize The size of the argument buffer + @param[in] Periodic Periodic or not + @param[in] ActivationInterval Interval of periodic SMI + + @retval EFI Status Describing the result of the operation + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported + +**/ +EFI_STATUS +EFIAPI +Activate ( + IN CONST EFI_SMM_CONTROL2_PROTOCOL * This, + IN OUT UINT8 *CommandPort OPTIONAL, + IN OUT UINT8 *DataPort OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL + ) +{ + EFI_STATUS Status; + UINT8 Data; + + if (Periodic) { + return EFI_INVALID_PARAMETER; + } + + if (CommandPort == NULL) { + Data = 0xFF; + } else { + Data = *CommandPort; + } + + // + // Clear any pending the APM SMI + // + Status = SmmClear (); + if (EFI_ERROR (Status)) { + return Status; + } + + return SmmTrigger (Data); +} + + +/** + This routine clears an SMI + + @param[in] This The EFI SMM Control protocol instance + @param[in] Periodic Periodic or not + + @retval EFI Status Describing the result of the operation + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported + +**/ +EFI_STATUS +EFIAPI +Deactivate ( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL + ) +{ + if (Periodic) { + return EFI_INVALID_PARAMETER; + } + + return SmmClear (); +} + + +/** + Disable all pending SMIs + +**/ +VOID +EFIAPI +DisablePendingSmis ( + VOID + ) +{ + UINT32 Data; + UINT32 Port; + BOOLEAN SciEn; + + // + // Determine whether an ACPI OS is present (via the SCI_EN bit) + // + Port = mAcpiBaseAddr + R_ACPI_PM1_CNT; + Data = IoRead16 ((UINTN) Port); + SciEn = (BOOLEAN) ((Data & B_ACPI_PM1_CNT_SCI_EN) == B_ACPI_PM1_CNT_SCI_EN); + + if (!SciEn) { + // + // Clear any SMIs that double as SCIs (when SCI_EN==0) + // + Port = mAcpiBaseAddr + R_ACPI_PM1_STS; + Data = 0xFFFF; + IoWrite16 ((UINTN) Port, (UINT16) (Data)); + + Port = mAcpiBaseAddr + R_ACPI_PM1_EN; + Data = 0x0000; + IoWrite16 ((UINTN) Port, (UINT16) (Data)); + + Port = mAcpiBaseAddr + R_ACPI_PM1_CNT; + Data = 0x0000; + IoWrite16 ((UINTN) Port, (UINT16) (Data)); + + Port = mAcpiBaseAddr + R_ACPI_GPE0a_STS; + Data = 0xFFFFFFFF; + IoWrite32 ((UINTN) Port, (UINT32) (Data)); + + Port = mAcpiBaseAddr + R_ACPI_GPE0a_EN; + Data = 0x00000000; + IoWrite32 ((UINTN) Port, (UINT32) (Data)); + } + + // + // Clear and disable all SMIs that are unaffected by SCI_EN + // +#if (ENBDT_PF_ENABLE == 1) +#else + Port = mAcpiBaseAddr + R_ALT_GP_SMI_EN; + Data = 0x0000; + IoWrite16 ((UINTN) Port, (UINT16) (Data)); + + Port = mAcpiBaseAddr + R_ALT_GP_SMI_STS; + Data = 0xFFFF; + IoWrite16 ((UINTN) Port, (UINT16) (Data)); +#endif + + Port = mAcpiBaseAddr + R_SMI_STS; + Data = 0xFFFFFFFF; + IoWrite32 ((UINTN) Port, (UINT32) (Data)); + + // + // (Make sure to write this register last -- EOS re-enables SMIs for the SC) + // + Port = mAcpiBaseAddr + R_SMI_EN; + Data = IoRead32 ((UINTN) Port); + + // + // clear all bits except those tied to SCI_EN + // + Data &= B_SMI_EN_BIOS_RLS; + + // + // enable SMIs and specifically enable writes to APM_CNT. + // + Data |= B_SMI_EN_GBL_SMI | B_SMI_EN_APMC; + + // + // NOTE: Default value of EOS is set in SC, it will be automatically cleared Once the SC asserts SMI# low, + // we don't need to do anything to clear it + // + IoWrite32 ((UINTN) Port, (UINT32) (Data)); +} + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h new file mode 100644 index 0000000000..9cec9b2c98 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h @@ -0,0 +1,152 @@ +/** @file + Header file for SMM Control 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 _SMM_CONTROL_DRIVER_H_ +#define _SMM_CONTROL_DRIVER_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EFI_INTERNAL_POINTER 0x00000004 +#define SMM_CONTROL_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('i', '4', 's', 'c') + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_SMM_CONTROL2_PROTOCOL SmmControl; +} SMM_CONTROL_PRIVATE_DATA; + +#define SMM_CONTROL_PRIVATE_DATA_FROM_THIS(a) CR (a, SMM_CONTROL_PRIVATE_DATA, SmmControl, SMM_CONTROL_DEV_SIGNATURE) + +// +// Prototypes +// +/** + SmmControl DXE RUNTIME Module Entry Point\n + - Introduction\n + The SmmControl module is a DXE RUNTIME driver that provides a standard way + for other drivers to trigger software SMIs. + + - @pre + - SC Power Management I/O space base address has already been programmed. + If SmmControl Runtime DXE driver is run before Status Code Runtime Protocol + is installed and there is the need to use Status code in the driver, it will + be necessary to add EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID to the dependency file. + - EFI_SMM_BASE2_PROTOCOL + - Documented in the System Management Mode Core Interface Specification. + + - @result + The SmmControl driver produces the EFI_SMM_CONTROL_PROTOCOL documented in + System Management Mode Core Interface Specification. + + @param[in] ImageHandle Handle for the image of this driver + @param[in] SystemTable Pointer to the EFI System Table + + @retval EFI_STATUS Results of the installation of the SMM Control Protocol + +**/ +EFI_STATUS +EFIAPI +SmmControlDriverEntryInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Trigger the software SMI + + @param[in] Data The value to be set on the software SMI data port + + @retval EFI_SUCCESS Function completes successfully + +**/ +EFI_STATUS +EFIAPI +SmmTrigger ( + UINT8 Data + ); + +/** + Clear the SMI status + + @retval EFI_SUCCESS The function completes successfully + @retval EFI_DEVICE_ERROR Something error occurred + +**/ +EFI_STATUS +EFIAPI +SmmClear ( + VOID + ); + +/** + This routine generates an SMI + + @param[in] This The EFI SMM Control protocol instance + @param[in, out] ArgumentBuffer The buffer of argument + @param[in, out] ArgumentBufferSize The size of the argument buffer + @param[in] Periodic Periodic or not + @param[in] ActivationInterval Interval of periodic SMI + + @retval EFI Status Describing the result of the operation + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported + +**/ +EFI_STATUS +EFIAPI +Activate ( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN OUT UINT8 *ArgumentBuffer OPTIONAL, + IN OUT UINT8 *ArgumentBufferSize OPTIONAL, + IN BOOLEAN Periodic OPTIONAL, + IN UINTN ActivationInterval OPTIONAL + ); + +/** + This routine clears an SMI + + @param[in] This The EFI SMM Control protocol instance + @param[in] Periodic Periodic or not + + @retval EFI Status Describing the result of the operation + @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported + +**/ +EFI_STATUS +EFIAPI +Deactivate ( + IN CONST EFI_SMM_CONTROL2_PROTOCOL *This, + IN BOOLEAN Periodic OPTIONAL + ); + +/** + Disable all pending SMIs + +**/ +VOID +EFIAPI +DisablePendingSmis ( + VOID + ); + +#endif + -- cgit v1.2.3