summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c
diff options
context:
space:
mode:
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2010-07-27 07:40:20 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2010-07-27 07:40:20 +0000
commit74f895276abded87dd7eecd5dfda71157010aae2 (patch)
tree3c8be33a56d372107bb284496c1482223eee49c8 /EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c
parent7416f4eb3a558736c304c8da8ff035f095c8b874 (diff)
downloadedk2-platforms-74f895276abded87dd7eecd5dfda71157010aae2.tar.xz
1. Consume Debug Agent Library to support debugging AP code based on PI MP protocol.
2. Copy LVT Timer setting from old BSP to new BSP when SwitchBsp() to make sure debug timer worked after bsp switched. 3. Save and restore old BSP's TSC value to new one. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10698 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c')
-rw-r--r--EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c
index 3ff503758d..f3db9f6b7c 100644
--- a/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c
+++ b/EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.c
@@ -532,6 +532,12 @@ SwitchBSP (
CPU_DATA_BLOCK *CpuData;
UINTN CallerNumber;
UINTN BspNumber;
+ UINTN ApicBase;
+ UINT32 CurrentTimerValue;
+ UINT32 CurrentTimerRegister;
+ UINT32 CurrentTimerDivide;
+ UINT64 CurrentTscValue;
+ BOOLEAN OldInterruptState;
//
// Check whether caller processor is BSP
@@ -572,6 +578,28 @@ SwitchBSP (
return EFI_NOT_READY;
}
+ //
+ // Save and disable interrupt.
+ //
+ OldInterruptState = SaveAndDisableInterrupts ();
+
+ //
+ // Record the current local APIC timer setting of BSP
+ //
+ ApicBase = (UINTN)AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE, 12, 35) << 12;
+ CurrentTimerValue = MmioRead32 (ApicBase + APIC_REGISTER_TIMER_COUNT);
+ CurrentTimerRegister = MmioRead32 (ApicBase + APIC_REGISTER_LVT_TIMER);
+ CurrentTimerDivide = MmioRead32 (ApicBase + APIC_REGISTER_TIMER_DIVIDE);
+ //
+ // Set mask bit (BIT 16) of LVT Timer Register to disable its interrupt
+ //
+ MmioBitFieldWrite32 (ApicBase + APIC_REGISTER_LVT_TIMER, 16, 16, 1);
+
+ //
+ // Record the current TSC value
+ //
+ CurrentTscValue = AsmReadTsc ();
+
Status = mFrameworkMpService->SwitchBSP (
mFrameworkMpService,
ProcessorNumber,
@@ -579,6 +607,23 @@ SwitchBSP (
);
ASSERT_EFI_ERROR (Status);
+ //
+ // Restore TSC value
+ //
+ AsmWriteMsr64 (MSR_IA32_TIME_STAMP_COUNTER, CurrentTscValue);
+
+ //
+ // Restore local APIC timer setting to new BSP
+ //
+ MmioWrite32 (ApicBase + APIC_REGISTER_TIMER_DIVIDE, CurrentTimerDivide);
+ MmioWrite32 (ApicBase + APIC_REGISTER_TIMER_INIT_COUNT, CurrentTimerValue);
+ MmioWrite32 (ApicBase + APIC_REGISTER_LVT_TIMER, CurrentTimerRegister);
+
+ //
+ // Restore interrupt state.
+ //
+ SetInterruptState (OldInterruptState);
+
ChangeCpuState (BspNumber, EnableOldBSP);
return EFI_SUCCESS;
@@ -1091,7 +1136,7 @@ ProgramVirtualWireMode (
UINTN ApicBase;
UINT32 Value;
- ApicBase = (UINTN)AsmMsrBitFieldRead64 (27, 12, 35) << 12;
+ ApicBase = (UINTN)AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE, 12, 35) << 12;
//
// Program the Spurious Vector entry
@@ -1157,8 +1202,16 @@ ApProcWrapper (
UINTN ProcessorNumber;
CPU_DATA_BLOCK *CpuData;
+ //
+ // Program virtual wire mode for AP, since it will be lost after AP wake up
+ //
ProgramVirtualWireMode (FALSE);
+ //
+ // Initialize Debug Agent to support source level debug on AP code.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_AP, NULL, NULL);
+
WhoAmI (&mMpService, &ProcessorNumber);
CpuData = &mMPSystemData.CpuData[ProcessorNumber];
@@ -1235,7 +1288,7 @@ SendInitSipiSipi (
DeliveryMode = DELIVERY_MODE_INIT;
ICRLow |= VectorNumber | (DeliveryMode << 8);
- ApicBase = 0xfee00000;
+ ApicBase = (UINTN)AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE, 12, 35) << 12;;
//
// Write Interrupt Command Registers to send INIT IPI.