/** @file
|
This module provides an implementation of the SMM Control PPI for use with
|
the QNC.
|
|
Copyright (c) 2013-2015 Intel Corporation.
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#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 GPE0BLK_Base;
|
|
//
|
// Get GPE0BLK_Base
|
//
|
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;
|
}
|