summaryrefslogtreecommitdiffstats
path: root/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
diff options
context:
space:
mode:
Diffstat (limited to 'QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c')
-rw-r--r--QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c b/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
new file mode 100644
index 0000000000..8c82611056
--- /dev/null
+++ b/QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c
@@ -0,0 +1,282 @@
+/** @file
+This module provides an implementation of the SMM Control PPI for use with
+the QNC.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SmmControl.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+
+#include <IntelQNCPeim.h>
+#include <Library/QNCAccessLib.h>
+#include <Uefi/UefiBaseType.h>
+
+/**
+ Generates an SMI using the parameters passed in.
+
+ @param PeiServices Describes the list of possible PEI Services.
+ @param This A pointer to an instance of
+ EFI_SMM_CONTROL_PPI
+ @param ArgumentBuffer The argument buffer
+ @param ArgumentBufferSize The size of the argument buffer
+ @param Periodic TRUE to indicate a periodical SMI
+ @param ActivationInterval Interval of the periodical SMI
+
+ @retval EFI_INVALID_PARAMETER Periodic is TRUE or ArgumentBufferSize > 1
+ @retval EFI_SUCCESS SMI generated
+
+**/
+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
+ );
+
+/**
+ Clears an SMI.
+
+ @param PeiServices Describes the list of possible PEI Services.
+ @param This Pointer to an instance of EFI_SMM_CONTROL_PPI
+ @param Periodic TRUE to indicate a periodical SMI
+
+ @return Return value from SmmClear()
+
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+PEI_SMM_CONTROL_PPI mSmmControlPpi = {
+ PeiActivate,
+ PeiDeactivate
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiSmmControlPpiGuid,
+ &mSmmControlPpi
+};
+
+/**
+ Clear SMI related chipset status and re-enable SMI by setting the EOS bit.
+
+ @retval EFI_SUCCESS The requested operation has been carried out successfully
+ @retval EFI_DEVICE_ERROR The EOS bit could not be set.
+
+**/
+EFI_STATUS
+SmmClear (
+ VOID
+ )
+{
+ UINT16 PM1BLK_Base;
+ UINT16 GPE0BLK_Base;
+
+ //
+ // Get PM1BLK_Base & GPE0BLK_Base
+ //
+ PM1BLK_Base = PcdGet16 (PcdPm1blkIoBaseAddress);
+ GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+ //
+ // Clear the Power Button Override Status Bit, it gates EOS from being set.
+ // In QuarkNcSocId - Bit is read only. Handled by external SMC, do nothing.
+ //
+
+ //
+ // Clear the APM SMI Status Bit
+ //
+ IoWrite32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_APM);
+
+ //
+ // Set the EOS Bit
+ //
+ IoOr32 ((GPE0BLK_Base + R_QNC_GPE0BLK_SMIS), B_QNC_GPE0BLK_SMIS_EOS);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ IN UINT8 Data
+ )
+/*++
+
+Routine Description:
+
+ Trigger the software SMI
+
+Arguments:
+
+ Data The value to be set on the software SMI data port
+
+Returns:
+
+ EFI_SUCCESS Function completes successfully
+
+--*/
+{
+ UINT16 GPE0BLK_Base;
+ UINT32 NewValue;
+
+ //
+ // Get GPE0BLK_Base
+ //
+ GPE0BLK_Base = PcdGet16 (PcdGpe0blkIoBaseAddress);
+
+ //
+ // Enable the APMC SMI
+ //
+ IoOr32 (GPE0BLK_Base + R_QNC_GPE0BLK_SMIE, B_QNC_GPE0BLK_SMIE_APM);
+
+ //
+ // Enable SMI globally
+ //
+ NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);
+ NewValue |= SMI_EN;
+ QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);
+
+
+ //
+ // Generate the APMC SMI
+ //
+ IoWrite8 (PcdGet16 (PcdSmmActivationPort), Data);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Generates an SMI using the parameters passed in.
+
+ @param PeiServices Describes the list of possible PEI Services.
+ @param This A pointer to an instance of
+ EFI_SMM_CONTROL_PPI
+ @param ArgumentBuffer The argument buffer
+ @param ArgumentBufferSize The size of the argument buffer
+ @param Periodic TRUE to indicate a periodical SMI
+ @param ActivationInterval Interval of the periodical SMI
+
+ @retval EFI_INVALID_PARAMETER Periodic is TRUE or ArgumentBufferSize > 1
+ @retval EFI_SUCCESS SMI generated
+
+**/
+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
+ )
+{
+ INT8 Data;
+ EFI_STATUS Status;
+ //
+ // Periodic SMI not supported.
+ //
+ if (Periodic) {
+ DEBUG ((DEBUG_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);
+}
+
+/**
+ Clears an SMI.
+
+ @param PeiServices Describes the list of possible PEI Services.
+ @param This Pointer to an instance of EFI_SMM_CONTROL_PPI
+ @param Periodic TRUE to indicate a periodical SMI
+
+ @return Return value from SmmClear()
+
+**/
+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 ();
+}
+
+/**
+ This is the constructor for the SMM Control Ppi.
+
+ This function installs EFI_SMM_CONTROL_PPI.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
+ @return The status returned from InstallPpi().
+
+--*/
+EFI_STATUS
+EFIAPI
+SmmControlPeiEntry (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}