UefiCpuPkg: LocalApicLib: Add API to set SoftwareEnable bit

The LocalApicLib does not provide a function to manage the state of the
Local APIC SoftwareEnable bit in the Spurious Vector register.  There
are cases where this bit needs to be managed without side effects to.
other Local APIC registers.  One use case is in the DebugAgent in the
SourceLevelDebugPkg.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18711 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Michael Kinney 2015-10-30 17:53:31 +00:00 committed by mdkinney
parent 0d4c1db81a
commit 14e4ca25c6
3 changed files with 83 additions and 9 deletions

View File

@ -4,7 +4,7 @@
Local APIC library assumes local APIC is enabled. It does not Local APIC library assumes local APIC is enabled. It does not
handles cases where local APIC is disabled. handles cases where local APIC is disabled.
Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -227,6 +227,20 @@ SendInitSipiSipiAllExcludingSelf (
IN UINT32 StartupRoutine IN UINT32 StartupRoutine
); );
/**
Initialize the state of the SoftwareEnable bit in the Local APIC
Spurious Interrupt Vector register.
@param Enable If TRUE, then set SoftwareEnable to 1
If FALSE, then set SoftwareEnable to 0.
**/
VOID
EFIAPI
InitializeLocalApicSoftwareEnable (
IN BOOLEAN Enable
);
/** /**
Programming Virtual Wire Mode. Programming Virtual Wire Mode.

View File

@ -563,6 +563,39 @@ SendInitSipiSipiAllExcludingSelf (
SendIpi (IcrLow.Uint32, 0); SendIpi (IcrLow.Uint32, 0);
} }
/**
Initialize the state of the SoftwareEnable bit in the Local APIC
Spurious Interrupt Vector register.
@param Enable If TRUE, then set SoftwareEnable to 1
If FALSE, then set SoftwareEnable to 0.
**/
VOID
EFIAPI
InitializeLocalApicSoftwareEnable (
IN BOOLEAN Enable
)
{
LOCAL_APIC_SVR Svr;
//
// Set local APIC software-enabled bit.
//
Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);
if (Enable) {
if (Svr.Bits.SoftwareEnable == 0) {
Svr.Bits.SoftwareEnable = 1;
WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
}
} else {
if (Svr.Bits.SoftwareEnable == 1) {
Svr.Bits.SoftwareEnable = 0;
WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
}
}
}
/** /**
Programming Virtual Wire Mode. Programming Virtual Wire Mode.
@ -679,7 +712,6 @@ InitializeApicTimer (
IN UINT8 Vector IN UINT8 Vector
) )
{ {
LOCAL_APIC_SVR Svr;
LOCAL_APIC_DCR Dcr; LOCAL_APIC_DCR Dcr;
LOCAL_APIC_LVT_TIMER LvtTimer; LOCAL_APIC_LVT_TIMER LvtTimer;
UINT32 Divisor; UINT32 Divisor;
@ -687,9 +719,7 @@ InitializeApicTimer (
// //
// Ensure local APIC is in software-enabled state. // Ensure local APIC is in software-enabled state.
// //
Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); InitializeLocalApicSoftwareEnable (TRUE);
Svr.Bits.SoftwareEnable = 1;
WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
// //
// Program init-count register. // Program init-count register.

View File

@ -658,6 +658,39 @@ SendInitSipiSipiAllExcludingSelf (
SendIpi (IcrLow.Uint32, 0); SendIpi (IcrLow.Uint32, 0);
} }
/**
Initialize the state of the SoftwareEnable bit in the Local APIC
Spurious Interrupt Vector register.
@param Enable If TRUE, then set SoftwareEnable to 1
If FALSE, then set SoftwareEnable to 0.
**/
VOID
EFIAPI
InitializeLocalApicSoftwareEnable (
IN BOOLEAN Enable
)
{
LOCAL_APIC_SVR Svr;
//
// Set local APIC software-enabled bit.
//
Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);
if (Enable) {
if (Svr.Bits.SoftwareEnable == 0) {
Svr.Bits.SoftwareEnable = 1;
WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
}
} else {
if (Svr.Bits.SoftwareEnable == 1) {
Svr.Bits.SoftwareEnable = 0;
WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
}
}
}
/** /**
Programming Virtual Wire Mode. Programming Virtual Wire Mode.
@ -774,7 +807,6 @@ InitializeApicTimer (
IN UINT8 Vector IN UINT8 Vector
) )
{ {
LOCAL_APIC_SVR Svr;
LOCAL_APIC_DCR Dcr; LOCAL_APIC_DCR Dcr;
LOCAL_APIC_LVT_TIMER LvtTimer; LOCAL_APIC_LVT_TIMER LvtTimer;
UINT32 Divisor; UINT32 Divisor;
@ -782,9 +814,7 @@ InitializeApicTimer (
// //
// Ensure local APIC is in software-enabled state. // Ensure local APIC is in software-enabled state.
// //
Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET); InitializeLocalApicSoftwareEnable (TRUE);
Svr.Bits.SoftwareEnable = 1;
WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
// //
// Program init-count register. // Program init-count register.