summaryrefslogtreecommitdiff
path: root/ChvRefCodePkg/CherryViewSoc
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-06-02 14:04:59 +0800
committerHao Wu <hao.a.wu@intel.com>2016-06-07 09:55:51 +0800
commit654daeafc76daa3f662b1b1cec5989544a5ee033 (patch)
treed4a8c78b16b2900bb0e02fe4caa4eabfe8bc27e7 /ChvRefCodePkg/CherryViewSoc
parent6d255d131a1ba172cc4ce3d659e574480b3a0047 (diff)
downloadedk2-platforms-654daeafc76daa3f662b1b1cec5989544a5ee033.tar.xz
ChvRefCodePkg: Add SmmControl.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'ChvRefCodePkg/CherryViewSoc')
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControl.inf48
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.c260
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.h92
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf58
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c381
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h143
6 files changed, 982 insertions, 0 deletions
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControl.inf b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControl.inf
new file mode 100644
index 0000000000..3db0d0a62b
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControl.inf
@@ -0,0 +1,48 @@
+## @file
+# Smm Control module
+#
+# It privides SMI create, trigger and clear mechanism.
+#
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = 9A9E7CF3-38F1-44F8-9057-A08B895A4620
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmControlPeiDriverEntryInit
+
+[Sources]
+ SmmControlDriver.h
+ SmmControlDriver.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ IoLib
+ DebugLib
+
+[Ppis]
+ gPeiSmmControlPpiGuid ## PRODUCES
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES
+
+[Depex]
+ TRUE
+
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.c b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.c
new file mode 100644
index 0000000000..d189e30c84
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.c
@@ -0,0 +1,260 @@
+/** @file
+ This is the driver that publishes the SMM Control Ppi.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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;
+ UINT32 AcpiBase;
+
+ AcpiBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE
+ )
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ ///
+ /// Enable the APMC SMI
+ ///
+ OutputPort = AcpiBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_PCH_SMI_EN_APMC | B_PCH_SMI_EN_GBL_SMI);
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_PCH_APM_CNT;
+ OutputData = Data;
+
+ ///
+ /// Generate the SW 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
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT32 AcpiBase;
+
+ AcpiBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE
+ )
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ ///
+ /// Clear the Power Button Override Status Bit, it gates EOS from being set.
+ ///
+ OutputPort = AcpiBase + R_PCH_ACPI_PM1_STS;
+ OutputData = B_PCH_ACPI_PM1_STS_PRBTNOR;
+
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ ///
+ /// Clear the APM SMI Status Bit
+ ///
+ OutputPort = AcpiBase + R_PCH_SMI_STS;
+ OutputData = B_PCH_SMI_STS_APM;
+
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ ///
+ /// Set the EOS Bit
+ ///
+ OutputPort = AcpiBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_PCH_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_PCH_SMI_EN_EOS) != B_PCH_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/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.h b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.h
new file mode 100644
index 0000000000..b2cb5c0f46
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/Pei/SmmControlDriver.h
@@ -0,0 +1,92 @@
+/** @file
+ Header file for SMM Control Driver.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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 <PiPei.h>
+#include "Ppi/SmmControl.h"
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <PchAccess.h>
+
+//
+// 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/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000000..798c1cb841
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,58 @@
+## @file
+# Smm Control Dxe module
+#
+# It privides SMI create, trigger and clear mechanism.
+#
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# 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 = SmmControl
+ FILE_GUID = CACC4D52-9412-49C7-BA3F-4DA439B3F3C4
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmControlDriverEntryInit
+
+[Sources]
+ SmmControlDriver.h
+ SmmControlDriver.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+
+
+[LibraryClasses]
+ IoLib
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ PchPlatformLib
+ PcdLib
+
+[Pcd]
+ ## CONSUMES
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Protocols]
+ ## PRODUCES
+ gEfiSmmControl2ProtocolGuid
+
+[Guids]
+ ## CONSUMES ## Event
+ gEfiEventVirtualAddressChangeGuid
+
+[Depex]
+ TRUE
+
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000000..d9b27064e1
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,381 @@
+/** @file
+ This is the driver that publishes the SMM Control Protocol.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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"
+
+STATIC SMM_CONTROL_PRIVATE_DATA mSmmControl;
+UINT32 AcpiBase;
+
+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));
+}
+
+/**
+ This is the constructor for the SMM Control protocol
+
+ @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;
+
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "SMM Control Protocol not supported due to no proper SoC found!\n"));
+ Status = EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((EFI_D_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.
+ ///
+ AcpiBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE
+ )
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ Status = EFI_SUCCESS;
+ if (AcpiBase != 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 PCH SMIs that, for whatever reason, are asserted after the boot.
+ ///
+ DisablePendingSmis ();
+
+ DEBUG ((EFI_D_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 SW SMI
+ ///
+ OutputPort = AcpiBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_PCH_SMI_EN_APMC | B_PCH_SMI_EN_GBL_SMI);
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_PCH_APM_CNT;
+ OutputData = Data;
+
+ ///
+ /// Generate the SW 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 = AcpiBase + R_PCH_ACPI_PM1_STS;
+ OutputData = B_PCH_ACPI_PM1_STS_PRBTNOR;
+
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ ///
+ /// Clear the APM SMI Status Bit
+ ///
+ OutputPort = AcpiBase + R_PCH_SMI_STS;
+ OutputData = B_PCH_SMI_STS_APM;
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ ///
+ /// Set the EOS Bit
+ ///
+ OutputPort = AcpiBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_PCH_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] CommandPort The buffer contains data to the command port
+ @param[in, out] DataPort The buffer contains data to the data port
+ @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) {
+ DEBUG ((EFI_D_WARN, "Invalid parameter\n"));
+ 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 = AcpiBase + R_PCH_ACPI_PM1_CNT;
+ Data = IoRead16 ((UINTN) Port);
+ SciEn = (BOOLEAN) ((Data & B_PCH_ACPI_PM1_CNT_SCI_EN) == B_PCH_ACPI_PM1_CNT_SCI_EN);
+
+ if (!SciEn) {
+ ///
+ /// Clear any SMIs that double as SCIs (when SCI_EN==0)
+ ///
+ Port = AcpiBase + R_PCH_ACPI_PM1_STS;
+ Data = 0xFFFF;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = AcpiBase + R_PCH_ACPI_PM1_EN;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = AcpiBase + R_PCH_ACPI_PM1_CNT;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = AcpiBase + R_PCH_ACPI_GPE0a_STS;
+ Data = 0xFFFFFFFF;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ Port = AcpiBase + R_PCH_ACPI_GPE0a_EN;
+ Data = 0x00000000;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+ }
+ ///
+ /// Clear and disable all SMIs that are unaffected by SCI_EN
+ ///
+ Port = AcpiBase + R_PCH_ALT_GP_SMI_EN;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = AcpiBase + R_PCH_ALT_GP_SMI_STS;
+ Data = 0xFFFF;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = AcpiBase + R_PCH_SMI_STS;
+ Data = 0xFFFFFFFF;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ ///
+ /// (Make sure to write this register last -- EOS re-enables SMIs for the PCH)
+ ///
+ Port = AcpiBase + R_PCH_SMI_EN;
+ Data = IoRead32 ((UINTN) Port);
+ ///
+ /// clear all bits except those tied to SCI_EN
+ ///
+ Data &= B_PCH_SMI_EN_BIOS_RLS;
+ ///
+ /// enable SMIs and specifically enable writes to APM_CNT.
+ ///
+ Data |= B_PCH_SMI_EN_GBL_SMI | B_PCH_SMI_EN_APMC;
+ ///
+ /// NOTE: Default value of EOS is set in PCH, it will be automatically cleared Once the PCH asserts SMI# low,
+ /// we don't need to do anything to clear it
+ ///
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+}
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000000..76fcc68baa
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,143 @@
+/** @file
+ Header file for SMM Control Driver.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ 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_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#include <PiDxe.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/EventGroup.h>
+#include <Protocol/SmmControl2.h>
+#include <IndustryStandard/Pci30.h>
+#include <PchAccess.h>
+#include <Library/PchPlatformLib.h>
+#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
+//
+
+/**
+ This is the constructor for the SMM Control protocol.
+
+ @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] CommandPort The buffer contains data to the command port
+ @param[in, out] DataPort The buffer contains data to the data port
+ @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
+ );
+
+/**
+ 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