mirror of https://github.com/acidanthera/audk.git
171 lines
3.8 KiB
C
171 lines
3.8 KiB
C
/** @file
|
|
|
|
Copyright (c) 2017-2021, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
#include "SpiCommon.h"
|
|
|
|
/**
|
|
Acquire SPI MMIO BAR.
|
|
|
|
@param[in] PchSpiBase PCH SPI PCI Base Address
|
|
|
|
@retval Return SPI BAR Address
|
|
|
|
**/
|
|
UINT32
|
|
AcquireSpiBar0 (
|
|
IN UINTN PchSpiBase
|
|
)
|
|
{
|
|
return MmioRead32 (PchSpiBase + R_SPI_BASE) & ~(B_SPI_BAR0_MASK);
|
|
}
|
|
|
|
/**
|
|
Release SPI MMIO BAR. Do nothing.
|
|
|
|
@param[in] PchSpiBase PCH SPI PCI Base Address
|
|
|
|
**/
|
|
VOID
|
|
ReleaseSpiBar0 (
|
|
IN UINTN PchSpiBase
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
This function is to enable/disable BIOS Write Protect in SMM phase.
|
|
|
|
@param[in] EnableSmmSts Flag to Enable/disable Bios write protect
|
|
|
|
**/
|
|
VOID
|
|
CpuSmmDisableBiosWriteProtect (
|
|
IN BOOLEAN EnableSmmSts
|
|
)
|
|
{
|
|
UINT32 Data32;
|
|
|
|
if (EnableSmmSts) {
|
|
//
|
|
// Disable BIOS Write Protect in SMM phase.
|
|
//
|
|
Data32 = MmioRead32 ((UINTN)(0xFED30880)) | (UINT32)(BIT0);
|
|
AsmWriteMsr32 (0x000001FE, Data32);
|
|
} else {
|
|
//
|
|
// Enable BIOS Write Protect in SMM phase
|
|
//
|
|
Data32 = MmioRead32 ((UINTN)(0xFED30880)) & (UINT32)(~BIT0);
|
|
AsmWriteMsr32 (0x000001FE, Data32);
|
|
}
|
|
|
|
//
|
|
// Read FED30880h back to ensure the setting went through.
|
|
//
|
|
Data32 = MmioRead32 (0xFED30880);
|
|
}
|
|
|
|
/**
|
|
This function is a hook for Spi to disable BIOS Write Protect.
|
|
|
|
@param[in] PchSpiBase PCH SPI PCI Base Address
|
|
@param[in] CpuSmmBwp Need to disable CPU SMM Bios write protection or not
|
|
|
|
@retval EFI_SUCCESS The protocol instance was properly initialized
|
|
@retval EFI_ACCESS_DENIED The BIOS Region can only be updated in SMM phase
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DisableBiosWriteProtect (
|
|
IN UINTN PchSpiBase,
|
|
IN UINT8 CpuSmmBwp
|
|
)
|
|
{
|
|
//
|
|
// Write clear BC_SYNC_SS prior to change WPD from 0 to 1.
|
|
//
|
|
MmioOr8 (PchSpiBase + R_SPI_BCR + 1, (B_SPI_BCR_SYNC_SS >> 8));
|
|
|
|
//
|
|
// Enable the access to the BIOS space for both read and write cycles
|
|
//
|
|
MmioOr8 (PchSpiBase + R_SPI_BCR, B_SPI_BCR_BIOSWE);
|
|
|
|
if (CpuSmmBwp != 0) {
|
|
CpuSmmDisableBiosWriteProtect (TRUE);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function is a hook for Spi to enable BIOS Write Protect.
|
|
|
|
@param[in] PchSpiBase PCH SPI PCI Base Address
|
|
@param[in] CpuSmmBwp Need to disable CPU SMM Bios write protection or not
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
EnableBiosWriteProtect (
|
|
IN UINTN PchSpiBase,
|
|
IN UINT8 CpuSmmBwp
|
|
)
|
|
{
|
|
//
|
|
// Disable the access to the BIOS space for write cycles
|
|
//
|
|
MmioAnd8 (PchSpiBase + R_SPI_BCR, (UINT8)(~B_SPI_BCR_BIOSWE));
|
|
|
|
if (CpuSmmBwp != 0) {
|
|
CpuSmmDisableBiosWriteProtect (FALSE);
|
|
}
|
|
}
|
|
|
|
/**
|
|
This function disables SPI Prefetching and caching,
|
|
and returns previous BIOS Control Register value before disabling.
|
|
|
|
@param[in] PchSpiBase PCH SPI PCI Base Address
|
|
|
|
@retval Previous BIOS Control Register value
|
|
|
|
**/
|
|
UINT8
|
|
SaveAndDisableSpiPrefetchCache (
|
|
IN UINTN PchSpiBase
|
|
)
|
|
{
|
|
UINT8 BiosCtlSave;
|
|
|
|
BiosCtlSave = MmioRead8 (PchSpiBase + R_SPI_BCR) & B_SPI_BCR_SRC;
|
|
|
|
MmioAndThenOr32 (
|
|
PchSpiBase + R_SPI_BCR, \
|
|
(UINT32)(~B_SPI_BCR_SRC), \
|
|
(UINT32)(V_SPI_BCR_SRC_PREF_DIS_CACHE_DIS << B_SPI_BCR_SRC)
|
|
);
|
|
|
|
return BiosCtlSave;
|
|
}
|
|
|
|
/**
|
|
This function updates BIOS Control Register with the given value.
|
|
|
|
@param[in] PchSpiBase PCH SPI PCI Base Address
|
|
@param[in] BiosCtlValue BIOS Control Register Value to be updated
|
|
|
|
**/
|
|
VOID
|
|
SetSpiBiosControlRegister (
|
|
IN UINTN PchSpiBase,
|
|
IN UINT8 BiosCtlValue
|
|
)
|
|
{
|
|
MmioAndThenOr8 (PchSpiBase + R_SPI_BCR, (UINT8) ~B_SPI_BCR_SRC, BiosCtlValue);
|
|
}
|