From cfa1f3a2addf0913e02fac98509796bf21f18d8f Mon Sep 17 00:00:00 2001
From: Olivier Martin <olivier.martin@arm.com>
Date: Mon, 27 Jan 2014 19:03:53 +0000
Subject: [PATCH] MdeModulePkg/DxeCore: Fixed CoreExitBootServices - Interrupt
 disabling

Interrupts are expected to be disabled when calling CoreExitBootServices()
(see explicit call to 'gCpu->DisableInterrupt (gCpu)' in the function).

Calling ReportStatusCode functions re-enabled the interrupt through
CoreRestoreTpl():

-----
CoreRestoreTpl() {
  (...)

  //
  // If lowering below HIGH_LEVEL, make sure
  // interrupts are enabled
  //
  if (gEfiCurrentTpl < TPL_HIGH_LEVEL) {
    CoreSetInterruptState (TRUE);
  }
}
-----

The workaround is to switch the calls to always disable the CPU interrupts.
Another solution would be to change TPL Raise/Restore code to save the
state of the interrupts prior to call RaiseTpl.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
---
 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index 6d2ff82..2b2db4e 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -747,11 +747,6 @@ CoreExitBootServices (
   SaveAndSetDebugTimerInterrupt (FALSE);
 
   //
-  // Disable CPU Interrupts
-  //
-  gCpu->DisableInterrupt (gCpu);
-
-  //
   // Report that ExitBootServices() has been called
   //
   REPORT_STATUS_CODE (
@@ -760,6 +755,13 @@ CoreExitBootServices (
     );
 
   //
+  // Disable CPU Interrupts. The interrupts can only be disabled after calling
+  // ReportStatusCode. ReportStatusCode when changing TPL could re-enabled
+  // interrupts.
+  //
+  gCpu->DisableInterrupt (gCpu);
+
+  //
   // Clear the non-runtime values of the EFI System Table
   //
   gDxeCoreST->BootServices        = NULL;
-- 
1.8.5

