/** @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); | |
} |