summaryrefslogtreecommitdiff
path: root/UefiCpuPkg/Library
diff options
context:
space:
mode:
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>2010-08-26 05:58:42 +0000
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>2010-08-26 05:58:42 +0000
commitae40aef1fb4f5f34e5273b6fd5d4103bf6c7dd2d (patch)
treeded45f7756c7ab9a95b7d06e0e374a935f6f81d7 /UefiCpuPkg/Library
parent2ca7eca448e914c5c21cac5ba3832e09b4b163e8 (diff)
downloadedk2-platforms-ae40aef1fb4f5f34e5273b6fd5d4103bf6c7dd2d.tar.xz
Improve Local APIC library class. Add new library APIs: GetApicVersion(), SendFixedIpi(), SendFixedIpiAllExcludingSelf(), GetApicTimerState(). Remove GetApicTimerDivisor (), its functionality can be covered by GetApicTimerState().
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10824 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'UefiCpuPkg/Library')
-rw-r--r--UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c131
-rw-r--r--UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c131
2 files changed, 212 insertions, 50 deletions
diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
index 16dbd4be6e..1ac3853071 100644
--- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
@@ -203,6 +203,67 @@ GetApicId (
}
/**
+ Get the value of the local APIC version register.
+
+ @return the value of the local APIC version register.
+**/
+UINT32
+EFIAPI
+GetApicVersion (
+ VOID
+ )
+{
+ return ReadLocalApicReg (XAPIC_VERSION_OFFSET);
+}
+
+/**
+ Send a Fixed IPI to a specified target processor.
+
+ This function returns after the IPI has been accepted by the target processor.
+
+ @param ApicId The local APIC ID of the target processor.
+ @param Vector The vector number of the interrupt being sent.
+**/
+VOID
+EFIAPI
+SendFixedIpi (
+ IN UINT32 ApicId,
+ IN UINT8 Vector
+ )
+{
+ LOCAL_APIC_ICR_LOW IcrLow;
+
+ IcrLow.Uint32 = 0;
+ IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
+ IcrLow.Bits.Level = 1;
+ IcrLow.Bits.Vector = Vector;
+ SendIpi (IcrLow.Uint32, ApicId);
+}
+
+/**
+ Send a Fixed IPI to all processors excluding self.
+
+ This function returns after the IPI has been accepted by the target processors.
+
+ @param Vector The vector number of the interrupt being sent.
+**/
+VOID
+EFIAPI
+SendFixedIpiAllExcludingSelf (
+ IN UINT8 Vector
+ )
+{
+ LOCAL_APIC_ICR_LOW IcrLow;
+
+ IcrLow.Uint32 = 0;
+ IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
+ IcrLow.Bits.Level = 1;
+ IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
+ IcrLow.Bits.Vector = Vector;
+ SendIpi (IcrLow.Uint32, 0);
+}
+
+/**
Send a SMI IPI to a specified target processor.
This function returns after the IPI has been accepted by the target processor.
@@ -381,43 +442,22 @@ ProgramVirtualWireMode (
//
// Program the LINT0 vector entry as ExtInt. Not masked, edge, active high.
//
- Lint.Uint32 = ReadLocalApicReg (XAPIC_LINT0_VECTOR_OFFSET);
+ Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET);
Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_EXTINT;
Lint.Bits.InputPinPolarity = 0;
Lint.Bits.TriggerMode = 0;
Lint.Bits.Mask = 0;
- WriteLocalApicReg (XAPIC_LINT0_VECTOR_OFFSET, Lint.Uint32);
+ WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, Lint.Uint32);
//
// Program the LINT0 vector entry as NMI. Not masked, edge, active high.
//
- Lint.Uint32 = ReadLocalApicReg (XAPIC_LINT1_VECTOR_OFFSET);
+ Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET);
Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_NMI;
Lint.Bits.InputPinPolarity = 0;
Lint.Bits.TriggerMode = 0;
Lint.Bits.Mask = 0;
- WriteLocalApicReg (XAPIC_LINT1_VECTOR_OFFSET, Lint.Uint32);
-}
-
-/**
- Get the divide value from the DCR (Divide Configuration Register) by which
- the processor's bus clock is divided to form the time base for the APIC timer.
-
- @return The divide value is one of 1,2,4,8,16,32,64,128.
-**/
-UINTN
-EFIAPI
-GetApicTimerDivisor (
- VOID
- )
-{
- UINT32 DivideValue;
- LOCAL_APIC_DCR Dcr;
-
- Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
- DivideValue = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2);
- DivideValue = (DivideValue + 1) & 0x7;
- return ((UINTN)1) << DivideValue;
+ WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, Lint.Uint32);
}
/**
@@ -511,6 +551,47 @@ InitializeApicTimer (
}
/**
+ Get the state of the local APIC timer.
+
+ @param DivideValue Return the divide value for the DCR. It is one of 1,2,4,8,16,32,64,128.
+ @param PeriodicMode Return the timer mode. If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot.
+ @param Vector Return the timer interrupt vector number.
+**/
+VOID
+EFIAPI
+GetApicTimerState (
+ OUT UINTN *DivideValue OPTIONAL,
+ OUT BOOLEAN *PeriodicMode OPTIONAL,
+ OUT UINT8 *Vector OPTIONAL
+ )
+{
+ UINT32 Divisor;
+ LOCAL_APIC_DCR Dcr;
+ LOCAL_APIC_LVT_TIMER LvtTimer;
+
+ if (DivideValue != NULL) {
+ Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
+ Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2);
+ Divisor = (Divisor + 1) & 0x7;
+ *DivideValue = ((UINTN)1) << Divisor;
+ }
+
+ if (PeriodicMode != NULL || Vector != NULL) {
+ LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
+ if (PeriodicMode != NULL) {
+ if (LvtTimer.Bits.TimerMode == 1) {
+ *PeriodicMode = TRUE;
+ } else {
+ *PeriodicMode = FALSE;
+ }
+ }
+ if (Vector != NULL) {
+ *Vector = (UINT8) LvtTimer.Bits.Vector;
+ }
+ }
+}
+
+/**
Enable the local APIC timer interrupt.
**/
VOID
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
index bff66eeb1b..7ee13c3ba6 100644
--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
@@ -286,6 +286,67 @@ GetApicId (
}
/**
+ Get the value of the local APIC version register.
+
+ @return the value of the local APIC version register.
+**/
+UINT32
+EFIAPI
+GetApicVersion (
+ VOID
+ )
+{
+ return ReadLocalApicReg (XAPIC_VERSION_OFFSET);
+}
+
+/**
+ Send a Fixed IPI to a specified target processor.
+
+ This function returns after the IPI has been accepted by the target processor.
+
+ @param ApicId The local APIC ID of the target processor.
+ @param Vector The vector number of the interrupt being sent.
+**/
+VOID
+EFIAPI
+SendFixedIpi (
+ IN UINT32 ApicId,
+ IN UINT8 Vector
+ )
+{
+ LOCAL_APIC_ICR_LOW IcrLow;
+
+ IcrLow.Uint32 = 0;
+ IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
+ IcrLow.Bits.Level = 1;
+ IcrLow.Bits.Vector = Vector;
+ SendIpi (IcrLow.Uint32, ApicId);
+}
+
+/**
+ Send a Fixed IPI to all processors excluding self.
+
+ This function returns after the IPI has been accepted by the target processors.
+
+ @param Vector The vector number of the interrupt being sent.
+**/
+VOID
+EFIAPI
+SendFixedIpiAllExcludingSelf (
+ IN UINT8 Vector
+ )
+{
+ LOCAL_APIC_ICR_LOW IcrLow;
+
+ IcrLow.Uint32 = 0;
+ IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
+ IcrLow.Bits.Level = 1;
+ IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
+ IcrLow.Bits.Vector = Vector;
+ SendIpi (IcrLow.Uint32, 0);
+}
+
+/**
Send a SMI IPI to a specified target processor.
This function returns after the IPI has been accepted by the target processor.
@@ -464,43 +525,22 @@ ProgramVirtualWireMode (
//
// Program the LINT0 vector entry as ExtInt. Not masked, edge, active high.
//
- Lint.Uint32 = ReadLocalApicReg (XAPIC_LINT0_VECTOR_OFFSET);
+ Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET);
Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_EXTINT;
Lint.Bits.InputPinPolarity = 0;
Lint.Bits.TriggerMode = 0;
Lint.Bits.Mask = 0;
- WriteLocalApicReg (XAPIC_LINT0_VECTOR_OFFSET, Lint.Uint32);
+ WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, Lint.Uint32);
//
// Program the LINT0 vector entry as NMI. Not masked, edge, active high.
//
- Lint.Uint32 = ReadLocalApicReg (XAPIC_LINT1_VECTOR_OFFSET);
+ Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET);
Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_NMI;
Lint.Bits.InputPinPolarity = 0;
Lint.Bits.TriggerMode = 0;
Lint.Bits.Mask = 0;
- WriteLocalApicReg (XAPIC_LINT1_VECTOR_OFFSET, Lint.Uint32);
-}
-
-/**
- Get the divide value from the DCR (Divide Configuration Register) by which
- the processor's bus clock is divided to form the time base for the APIC timer.
-
- @return The divide value is one of 1,2,4,8,16,32,64,128.
-**/
-UINTN
-EFIAPI
-GetApicTimerDivisor (
- VOID
- )
-{
- UINT32 DivideValue;
- LOCAL_APIC_DCR Dcr;
-
- Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
- DivideValue = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2);
- DivideValue = (DivideValue + 1) & 0x7;
- return ((UINTN)1) << DivideValue;
+ WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, Lint.Uint32);
}
/**
@@ -594,6 +634,47 @@ InitializeApicTimer (
}
/**
+ Get the state of the local APIC timer.
+
+ @param DivideValue Return the divide value for the DCR. It is one of 1,2,4,8,16,32,64,128.
+ @param PeriodicMode Return the timer mode. If TRUE, timer mode is peridoic. Othewise, timer mode is one-shot.
+ @param Vector Return the timer interrupt vector number.
+**/
+VOID
+EFIAPI
+GetApicTimerState (
+ OUT UINTN *DivideValue OPTIONAL,
+ OUT BOOLEAN *PeriodicMode OPTIONAL,
+ OUT UINT8 *Vector OPTIONAL
+ )
+{
+ UINT32 Divisor;
+ LOCAL_APIC_DCR Dcr;
+ LOCAL_APIC_LVT_TIMER LvtTimer;
+
+ if (DivideValue != NULL) {
+ Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
+ Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2);
+ Divisor = (Divisor + 1) & 0x7;
+ *DivideValue = ((UINTN)1) << Divisor;
+ }
+
+ if (PeriodicMode != NULL || Vector != NULL) {
+ LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
+ if (PeriodicMode != NULL) {
+ if (LvtTimer.Bits.TimerMode == 1) {
+ *PeriodicMode = TRUE;
+ } else {
+ *PeriodicMode = FALSE;
+ }
+ }
+ if (Vector != NULL) {
+ *Vector = (UINT8) LvtTimer.Bits.Vector;
+ }
+ }
+}
+
+/**
Enable the local APIC timer interrupt.
**/
VOID