summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c
new file mode 100644
index 0000000..020f152
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c
@@ -0,0 +1,188 @@
+/** @file
+ PCH BIOS Write Protect Driver.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+**/
+#include "PchBiosWriteProtect.h"
+
+///
+/// Global variables
+///
+EFI_SMM_ICHN_DISPATCH_PROTOCOL *mIchnDispatch;
+EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *mPchIoTrap;
+UINTN mPciD31F0RegBase;
+
+/**
+ This hardware SMI handler will be run every time the BIOS Write Enable bit is set.
+
+ @param[in] DispatchHandle Not used
+ @param[in] DispatchContext Not used
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchBiosWpCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ ///
+ /// Disable BIOSWE bit to protect BIOS
+ ///
+ MmioAnd8 ((UINTN) (mPciD31F0RegBase + R_PCH_LPC_BIOS_CNTL), (UINT8) ~B_PCH_LPC_BIOS_CNTL_BIOSWE);
+}
+
+/**
+ Register an IchnBiosWp callback function to handle TCO BIOSWR SMI
+ SMM_BWP and BLE bits will be set here
+
+ @param[in] DispatchHandle Not used
+ @param[in] CallbackContext Information about the IO trap that occurred
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchBiosLockIoTrapCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext;
+ EFI_HANDLE IchnHandle;
+
+ ///
+ /// Do not run the callback function if it is not Write cycle trapped or the wrtie data
+ /// is not PCH_BWP_SIGNATURE,
+ ///
+ if ((CallbackContext->Type != WriteTrap) || (CallbackContext->WriteData != PCH_BWP_SIGNATURE)) {
+ return;
+ }
+
+ if (mIchnDispatch == NULL) {
+ return;
+ }
+
+ IchnHandle = NULL;
+
+ ///
+ /// Set SMM_BWP bit before registering IchnBiosWp
+ ///
+ MmioOr8 ((UINTN) (mPciD31F0RegBase + R_PCH_LPC_BIOS_CNTL), (UINT8) B_PCH_LPC_BIOS_CNTL_SMM_BWP);
+
+ ///
+ /// Register an IchnBiosWp callback function to handle TCO BIOSWR SMI
+ ///
+ IchnContext.Type = IchnBiosWp;
+ Status = mIchnDispatch->Register (
+ mIchnDispatch,
+ PchBiosWpCallback,
+ &IchnContext,
+ &IchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ 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;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+
+ ///
+ /// Locate PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateProtocol (&gDxePchPlatformPolicyProtocolGuid, NULL, (VOID **) &PchPlatformPolicy);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate PCH Policy protocol.\n"));
+ return Status;
+ }
+
+ if ((PchPlatformPolicy->LockDownConfig->BiosLock == PCH_DEVICE_ENABLE)) {
+ mPciD31F0RegBase = MmPciAddress (
+ 0,
+ 0,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+
+ ///
+ /// Get the ICHn protocol
+ ///
+ mIchnDispatch = NULL;
+ Status = gBS->LocateProtocol (&gEfiSmmIchnDispatchProtocolGuid, NULL, (VOID **) &mIchnDispatch);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate the PCH IO TRAP Dispatch protocol
+ ///
+ PchIoTrapHandle = NULL;
+ Status = gBS->LocateProtocol (&gEfiSmmIoTrapDispatchProtocolGuid, NULL, (VOID **) &mPchIoTrap);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Register BIOS Lock IO Trap SMI handler
+ ///
+ PchIoTrapContext.Type = WriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = mPchIoTrap->Register (
+ mPchIoTrap,
+ PchBiosLockIoTrapCallback,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_ERROR, "PchBiosLockIoTrapAddress = 0x%x\n", PchIoTrapContext.Address));
+
+ if ((PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress == 0) &&
+ (PchIoTrapContext.Address == 0)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Invalid PchIoTrapContext.Address!!!\n"));
+ ASSERT (FALSE);
+ } else {
+ if ((PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != 0) &&
+ (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != PchIoTrapContext.Address)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Invalid PchIoTrapContext.Address!!!\n"));
+ ASSERT (FALSE);
+ } else {
+ PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress = PchIoTrapContext.Address;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}