summaryrefslogtreecommitdiff
path: root/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c')
-rw-r--r--ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c
new file mode 100644
index 0000000..4dfc8b0
--- /dev/null
+++ b/ReferenceCode/ME/FwUpdate/MeFwDowngrade/Dxe/MeFwDowngrade.c
@@ -0,0 +1,261 @@
+/** @file
+ MeFwDowngrade driver
+
+@copyright
+ Copyright (c) 2010 - 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 an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "MeLib.h"
+#include "MeAccess.h"
+#include "AmtLib.h"
+#include "HeciRegs.h"
+
+#include EFI_GUID_DEFINITION (MePlatformReadyToBoot)
+#endif
+
+#define ERROR_HANDLING_DELAY 7000000 ///< show warning msg and stay for 7 seconds.
+#define FW_MSG_DELAY 1000 ///< show warning msg and stay for 1 milisecond.
+#define FW_MSG_DELAY_TIMEOUT 10
+
+UINT8 HeciHmrfpoLockResult, HeciHmrfpoEnableResult;
+
+VOID
+EFIAPI
+MeFwDowngradeMsgEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/**
+ Tell User that we failed to lock/unlock the flash - Do this after we have graphics initialized
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] Context Pointer to the notification functions context
+
+ @retval None
+**/
+{
+ if (HeciHmrfpoLockResult != HMRFPO_LOCK_SUCCESS) {
+ MeReportError (MSG_HMRFPO_LOCK_FAILURE);
+ }
+
+ if (HeciHmrfpoEnableResult != HMRFPO_ENABLE_SUCCESS) {
+ MeReportError (MSG_HMRFPO_UNLOCK_FAILURE);
+ }
+
+ gBS->CloseEvent (Event);
+ return;
+}
+
+VOID
+EFIAPI
+MeHmrfpoDisableEvent (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+/**
+ Send the HMRFPO_DISABLE MEI message.
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] Context Pointer to the notification functions context
+
+ @retval None
+**/
+{
+ UINT32 FWstatus;
+ UINT8 WriteValue;
+ UINT8 StallCount;
+
+ FWstatus = 0;
+ WriteValue = 0;
+ StallCount = 0;
+
+ DEBUG ((EFI_D_ERROR, "(B3) Me FW Downgrade - Send the HMRFPO_DISABLE MEI message\n"));
+
+ WriteValue = HeciPciRead8 (R_GEN_STS + 3);
+ WriteValue = WriteValue & BRNGUP_HMRFPO_DISABLE_CMD_MASK;
+ WriteValue = WriteValue | BRNGUP_HMRFPO_DISABLE_CMD;
+ DEBUG ((EFI_D_ERROR, "Me FW Downgrade Writing %x to register %x of PCI space\n", WriteValue, (R_GEN_STS + 3)));
+ ///
+ /// Set the highest Byte of General Status Register (Bits 28-31)
+ ///
+ HeciPciWrite8 (R_GEN_STS + 3, WriteValue);
+ FWstatus = HeciPciRead32 (R_FWSTATE);
+ while
+ (
+ ((FWstatus & BRNGUP_HMRFPO_DISABLE_OVR_MASK) != BRNGUP_HMRFPO_DISABLE_OVR_RSP) &&
+ (StallCount < FW_MSG_DELAY_TIMEOUT)
+ ) {
+ DEBUG ((EFI_D_ERROR, "Me FW Downgrade - ME HMRFPO Disable Status = 0x%x\n", FWstatus));
+ FWstatus = HeciPciRead32 (R_FWSTATE);
+ gBS->Stall (FW_MSG_DELAY);
+ StallCount = StallCount + 1;
+ }
+
+ if ((FWstatus & BRNGUP_HMRFPO_DISABLE_OVR_MASK) == BRNGUP_HMRFPO_DISABLE_OVR_RSP) {
+ DEBUG ((EFI_D_ERROR, "Me FW Downgrade Disable Msg Received Successfully\n"));
+ } else {
+ DEBUG ((EFI_D_ERROR, "Me FW Downgrade Disable Msg ACK not Received\n"));
+
+ }
+ ///
+ /// Hide ME devices so we don't get a yellow bang in OS with disabled devices
+ ///
+ DisableAllMEDevices ();
+
+ gBS->CloseEvent (Event);
+
+ return;
+}
+
+/**
+ Entry point for the MeFwDowngrade driver
+
+ @param[in] ImageHandle Standard entry point parameter.
+ @param[in] SystemTable Standard entry point parameter.
+
+ @exception EFI_UNSUPPORTED ME policy library initization failure.
+ @retval Status code returned by CreateEventEx.
+**/
+EFI_STATUS
+MeFwDowngradeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT MeFwDowngradeEvent;
+ EFI_HECI_PROTOCOL *Heci;
+ UINT32 MeMode;
+ UINT32 MeStatus;
+ UINT64 Nonce;
+ UINT32 FactoryDefaultBase;
+ UINT32 FactoryDefaultLimit;
+ HECI_FWS_REGISTER MeFirmwareStatus;
+
+ MeFirmwareStatus.ul = HeciPciRead32 (R_FWSTATE);
+
+ Status = gBS->LocateProtocol (
+ &gEfiHeciProtocolGuid,
+ NULL,
+ (VOID **) &Heci
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = Heci->GetMeMode (&MeMode);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = Heci->GetMeStatus (&MeStatus);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// (B1) Whcih mode ?
+ ///
+ if (MeMode == ME_MODE_NORMAL) {
+ ///
+ /// (A2) Intel Me image re-flash is requested?
+ ///
+ if (MeFwDowngradeSupported ()) {
+ ///
+ /// (A4)(A5) The BIOS sends the HMRFPO ENABLE MEI message and wiat for response.
+ ///
+ HeciHmrfpoEnableResult = HMRFPO_ENABLE_UNKNOWN_FAILURE;
+ Status = HeciHmrfpoEnable (0, &HeciHmrfpoEnableResult);
+ if (Status == EFI_SUCCESS && HeciHmrfpoEnableResult == HMRFPO_ENABLE_SUCCESS) {
+ ///
+ /// (A6) The BIOS sends the GLOBAL RESET MEI message
+ ///
+ DEBUG ((EFI_D_ERROR, "Me FW Downgrade !!- Step A6\n"));
+
+ HeciSendCbmResetRequest (CBM_RR_REQ_ORIGIN_BIOS_POST, CBM_HRR_GLOBAL_RESET);
+ EFI_DEADLOOP ();
+ }
+ ///
+ /// (A8) Error Handling, HeciHmrfpoEnable include error handling.
+ ///
+ DEBUG (
+ (
+ EFI_D_ERROR, "Me FW Downgrade Error !!- Step A8, the Status is %r, The result is %x\n", Status,
+ HeciHmrfpoEnableResult
+ )
+ );
+ IoWrite8 (0x80, 0xA8);
+ } else {
+ ///
+ /// (A7) The BIOS sends the HMRFPO Lock MEI message and continues the normal boot
+ ///
+ HeciHmrfpoLockResult = HMRFPO_LOCK_SUCCESS;
+ ///
+ /// The ME firmware will ignore the HMRFPO LOCK command if ME is in ME manufacturing mode
+ ///
+ if ((MeFirmwareStatus.r.ManufacturingMode == 0) &&
+ (
+ (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_IN_RECOVERY_MODE) ||
+ (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY)
+ )
+ ) {
+
+ DEBUG (
+ (
+ EFI_D_ERROR,
+ "(A7) Me FW Downgrade - The BIOS sends the HMRFPO Lock MEI message and continues the normal boot\n"
+ )
+ );
+
+ FactoryDefaultBase = 0;
+ FactoryDefaultLimit = 0;
+ Status = HeciHmrfpoLock (&Nonce, &FactoryDefaultBase, &FactoryDefaultLimit, &HeciHmrfpoLockResult);
+ if (Status != EFI_SUCCESS) {
+ HeciHmrfpoLockResult = HMRFPO_LOCK_FAILURE;
+ }
+ }
+ }
+
+ Status = gBS->CreateEventEx (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_NOTIFY,
+ MeFwDowngradeMsgEvent,
+ (VOID *) &ImageHandle,
+ &gMePlatformReadyToBootGuid,
+ &MeFwDowngradeEvent
+ );
+
+ }
+ ///
+ /// (B3) Create an event that will call the HMRFPO_DISABLE
+ ///
+ if ((MeFirmwareStatus.r.MeOperationMode == ME_OPERATION_MODE_SECOVR_HECI_MSG) &&
+ (ME_STATUS_ME_STATE_ONLY (MeStatus) == ME_READY)
+ ) {
+ Status = gBS->CreateEventEx (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_NOTIFY,
+ MeHmrfpoDisableEvent,
+ (VOID *) &ImageHandle,
+ &gMePlatformReadyToBootGuid,
+ &MeFwDowngradeEvent
+ );
+ }
+
+ return Status;
+}