/** @file PCH BIOS Write Protect Driver. Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PchInitSmm.h" /// /// Global variables /// GLOBAL_REMOVE_IF_UNREFERENCED PCH_TCO_SMI_DISPATCH_PROTOCOL *mPchTcoSmiDispatchProtocol; GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSpiRegBase; GLOBAL_REMOVE_IF_UNREFERENCED PCH_ESPI_SMI_DISPATCH_PROTOCOL *mEspiSmmDispatchProtocol; GLOBAL_REMOVE_IF_UNREFERENCED UINTN mLpcRegBase; /** This hardware SMI handler will be run every time the BIOS Write Enable bit is set. @param[in] DispatchHandle Not used **/ VOID EFIAPI PchSpiBiosWpCallback ( IN EFI_HANDLE DispatchHandle ) { // // Disable BIOSWE bit to protect BIOS // MmioAnd8 ((UINTN) (mSpiRegBase + R_PCH_SPI_BC), (UINT8) ~B_PCH_SPI_BC_WPD); } /** This hardware SMI handler will be run every time the BIOS Write Enable bit is set. @param[in] DispatchHandle Not used **/ VOID EFIAPI PchLpcBiosWpCallback ( IN EFI_HANDLE DispatchHandle ) { // // Disable BIOSWE bit to protect BIOS // MmioAnd8 ((UINTN) (mLpcRegBase + R_PCH_LPC_BC), (UINT8) ~B_PCH_LPC_BC_WPD); } /** Entry point for Pch Bios Write Protect driver. @param[in] ImageHandle Image handle of this driver. @param[in] SystemTable Global system service table. @retval EFI_SUCCESS Initialization complete. **/ EFI_STATUS EFIAPI InstallPchBiosWriteProtect ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; DEBUG ((DEBUG_INFO, "InstallPchBiosWriteProtect()\n")); if (mPchConfigHob->LockDown.BiosLock != TRUE) { return EFI_SUCCESS; } mSpiRegBase = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SPI, PCI_FUNCTION_NUMBER_PCH_SPI ); mLpcRegBase = MmPciBase ( DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC ); DEBUG ((DEBUG_INFO, "Installing BIOS Write Protect SMI handler\n")); // // Get the PCH TCO SMM dispatch protocol // mPchTcoSmiDispatchProtocol = NULL; Status = gSmst->SmmLocateProtocol (&gPchTcoSmiDispatchProtocolGuid, NULL, (VOID **) &mPchTcoSmiDispatchProtocol); ASSERT_EFI_ERROR (Status); // // Always register an SPI BiosWp callback function to handle TCO BIOSWR SMI // NOTE: No matter the BIOS resides behind SPI or not, it needs to handle the SPI BIOS WP SMI // to avoid SMI deadloop on SPI WPD write. // Handle = NULL; Status = mPchTcoSmiDispatchProtocol->SpiBiosWpRegister ( mPchTcoSmiDispatchProtocol, PchSpiBiosWpCallback, &Handle ); ASSERT_EFI_ERROR (Status); // // Register an LPC BiosWp callback function to handle TCO BIOSWR SMI // Handle = NULL; Status = mPchTcoSmiDispatchProtocol->LpcBiosWpRegister ( mPchTcoSmiDispatchProtocol, PchLpcBiosWpCallback, &Handle ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }