]> git.proxmox.com Git - mirror_edk2.git/blobdiff - PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c
Add generic HPET Timer DXE Driver and support libraries
[mirror_edk2.git] / PcAtChipsetPkg / Library / BaseIoApicLib / IoApicLib.c
diff --git a/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c b/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c
new file mode 100644 (file)
index 0000000..42b3f21
--- /dev/null
@@ -0,0 +1,158 @@
+/** @file \r
+  I/O APIC library.\r
+\r
+  I/O APIC library assumes I/O APIC is enabled. It does not\r
+  handles cases where I/O APIC is disabled.\r
+\r
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+\r
+#include <Library/IoApicLib.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/LocalApicLib.h>\r
+\r
+#include <Register/IoApic.h>\r
+\r
+/**\r
+  Read a 32-bit I/O APIC register.\r
+\r
+  If Index is >= 0x100, then ASSERT().\r
+  \r
+  @param  Index  Specifies the I/O APIC register to read.\r
+\r
+  @return  The 32-bit value read from the I/O APIC register specified by Index.\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoApicRead (\r
+  IN UINTN  Index\r
+  )\r
+{\r
+  ASSERT (Index < 0x100);\r
+  MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);\r
+  return MmioRead32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET);\r
+}\r
+\r
+/**\r
+  Write a 32-bit I/O APIC register.\r
+\r
+  If Index is >= 0x100, then ASSERT().\r
+  \r
+  @param  Index  Specifies the I/O APIC register to write.\r
+  @param  Value  Specifies the value to write to the I/O APIC register specified by Index.\r
+\r
+  @return  The 32-bit value written to I/O APIC register specified by Index.\r
+**/\r
+UINT32\r
+EFIAPI\r
+IoApicWrite (\r
+  IN UINTN   Index,\r
+  IN UINT32  Value\r
+  )\r
+{\r
+  ASSERT (Index < 0x100);\r
+  MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index);\r
+  return MmioWrite32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET, Value);\r
+}\r
+\r
+/**\r
+  Set the interrupt mask of an I/O APIC interrupt.\r
+\r
+  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). \r
+\r
+  @param  Irq     Specifies the I/O APIC interrupt to enable or disable.\r
+  @param  Enable  If TRUE, then enable the I/O APIC interrupt specified by Irq.\r
+                  If FALSE, then disable the I/O APIC interrupt specified by Irq.\r
+**/\r
+VOID\r
+EFIAPI\r
+IoApicEnableInterrupt (\r
+  IN UINTN    Irq,\r
+  IN BOOLEAN  Enable\r
+  )\r
+{\r
+  IO_APIC_VERSION_REGISTER         Version;\r
+  IO_APIC_REDIRECTION_TABLE_ENTRY  Entry;\r
+\r
+  Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);\r
+  ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);\r
+  ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);\r
+\r
+  Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);\r
+  Entry.Bits.Mask = Enable ? 0 : 1;\r
+  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);\r
+}\r
+\r
+/**\r
+  Configures an I/O APIC interrupt.\r
+  \r
+  Configure an I/O APIC Redirection Table Entry to deliver an interrupt in physical\r
+  mode to the Local APIC of the currntly executing CPU.  The default state of the \r
+  entry is for the interrupt to be disabled (masked).  IoApicEnableInterrupts() must\r
+  be used to enable(unmask) the I/O APIC Interrupt.\r
\r
+  If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). \r
+  If Vector >= 0x100, then ASSERT().\r
+  If DeliveryMode is not supported, then ASSERT().\r
+\r
+  @param  Irq             Specifies the I/O APIC interrupt to initialize.\r
+  @param  Vector          The 8-bit interrupt vector associated with the I/O APIC\r
+                          Interrupt.  Must be in the range 0x10..0xFE.\r
+  @param  DeliveryMode    A 3-bit value that specifies how the recept of the I/O APIC\r
+                          interrupt is handled.  The only supported values are:\r
+                            0: IO_APIC_DELIVERY_MODE_FIXED\r
+                            1: IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY\r
+                            2: IO_APIC_DELIVERY_MODE_SMI\r
+                            4: IO_APIC_DELIVERY_MODE_NMI\r
+                            5: IO_APIC_DELIVERY_MODE_INIT\r
+                            7: IO_APIC_DELIVERY_MODE_EXTINT\r
+  @param  LevelTriggered  TRUE specifies a level triggered interrupt.\r
+                          FALSE specifies an edge triggered interrupt.\r
+  @param  AssertionLevel  TRUE specified an active high interrupt.\r
+                          FALSE specifies an active low interrupt.\r
+**/\r
+VOID\r
+EFIAPI\r
+IoApicConfigureInterrupt (\r
+  IN UINTN    Irq,\r
+  IN UINTN    Vector,\r
+  IN UINTN    DeliveryMode,\r
+  IN BOOLEAN  LevelTriggered,\r
+  IN BOOLEAN  AssertionLevel\r
+  )\r
+{\r
+  IO_APIC_VERSION_REGISTER         Version;\r
+  IO_APIC_REDIRECTION_TABLE_ENTRY  Entry;\r
+\r
+  Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX);\r
+  ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0);\r
+  ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry);\r
+  ASSERT (Vector <= 0xFF);\r
+  ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3);\r
+  \r
+  Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2);\r
+  Entry.Bits.Vector          = (UINT8)Vector;\r
+  Entry.Bits.DeliveryMode    = (UINT32)DeliveryMode;\r
+  Entry.Bits.DestinationMode = 0; \r
+  Entry.Bits.Polarity        = AssertionLevel ? 0 : 1;\r
+  Entry.Bits.TriggerMode     = LevelTriggered ? 1 : 0;\r
+  Entry.Bits.Mask            = 1;\r
+  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low);\r
+\r
+  Entry.Uint32.High = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1);\r
+  Entry.Bits.DestinationID = GetApicId ();\r
+  IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1, Entry.Uint32.High);\r
+}\r