mirror of https://github.com/acidanthera/audk.git
281 lines
7.1 KiB
C
281 lines
7.1 KiB
C
/** @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 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;
|
|
}
|