diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib')
3 files changed, 202 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf b/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf new file mode 100644 index 00000000..441af96f --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf @@ -0,0 +1,34 @@ +## @file +# Library instance for I/O APIC library class +# +# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseIoApicLib + MODULE_UNI_FILE = BaseIoApicLib.uni + FILE_GUID = 58ED6E5A-E36A-462a-9ED6-6E62C9A26DF8 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = IoApicLib + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + +[LibraryClasses] + DebugLib + IoLib + PcdLib + LocalApicLib + +[Sources] + IoApicLib.c + +[Pcd] + gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress ## CONSUMES + diff --git a/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.uni b/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.uni new file mode 100644 index 00000000..5931b252 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.uni @@ -0,0 +1,16 @@ +// /** @file
+// Library instance for I/O APIC library class
+//
+// Library instance for I/O APIC library class.
+//
+// Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Library instance for I/O APIC library class"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Library instance for I/O APIC library class."
+
diff --git a/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c b/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c new file mode 100644 index 00000000..61bc3bf6 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c @@ -0,0 +1,152 @@ +/** @file + I/O APIC library. + + I/O APIC library assumes I/O APIC is enabled. It does not + handles cases where I/O APIC is disabled. + + Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Base.h> + +#include <Library/IoApicLib.h> + +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/IoLib.h> +#include <Library/LocalApicLib.h> + +#include <Register/IoApic.h> + +/** + Read a 32-bit I/O APIC register. + + If Index is >= 0x100, then ASSERT(). + + @param Index Specifies the I/O APIC register to read. + + @return The 32-bit value read from the I/O APIC register specified by Index. +**/ +UINT32 +EFIAPI +IoApicRead ( + IN UINTN Index + ) +{ + ASSERT (Index < 0x100); + MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index); + return MmioRead32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET); +} + +/** + Write a 32-bit I/O APIC register. + + If Index is >= 0x100, then ASSERT(). + + @param Index Specifies the I/O APIC register to write. + @param Value Specifies the value to write to the I/O APIC register specified by Index. + + @return The 32-bit value written to I/O APIC register specified by Index. +**/ +UINT32 +EFIAPI +IoApicWrite ( + IN UINTN Index, + IN UINT32 Value + ) +{ + ASSERT (Index < 0x100); + MmioWrite8 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_INDEX_OFFSET, (UINT8)Index); + return MmioWrite32 (PcdGet32 (PcdIoApicBaseAddress) + IOAPIC_DATA_OFFSET, Value); +} + +/** + Set the interrupt mask of an I/O APIC interrupt. + + If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). + + @param Irq Specifies the I/O APIC interrupt to enable or disable. + @param Enable If TRUE, then enable the I/O APIC interrupt specified by Irq. + If FALSE, then disable the I/O APIC interrupt specified by Irq. +**/ +VOID +EFIAPI +IoApicEnableInterrupt ( + IN UINTN Irq, + IN BOOLEAN Enable + ) +{ + IO_APIC_VERSION_REGISTER Version; + IO_APIC_REDIRECTION_TABLE_ENTRY Entry; + + Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX); + ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0); + ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry); + + Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2); + Entry.Bits.Mask = Enable ? 0 : 1; + IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low); +} + +/** + Configures an I/O APIC interrupt. + + Configure an I/O APIC Redirection Table Entry to deliver an interrupt in physical + mode to the Local APIC of the currently executing CPU. The default state of the + entry is for the interrupt to be disabled (masked). IoApicEnableInterrupts() must + be used to enable(unmask) the I/O APIC Interrupt. + + If Irq is larger than the maximum number I/O APIC redirection entries, then ASSERT(). + If Vector >= 0x100, then ASSERT(). + If DeliveryMode is not supported, then ASSERT(). + + @param Irq Specifies the I/O APIC interrupt to initialize. + @param Vector The 8-bit interrupt vector associated with the I/O APIC + Interrupt. Must be in the range 0x10..0xFE. + @param DeliveryMode A 3-bit value that specifies how the recept of the I/O APIC + interrupt is handled. The only supported values are: + 0: IO_APIC_DELIVERY_MODE_FIXED + 1: IO_APIC_DELIVERY_MODE_LOWEST_PRIORITY + 2: IO_APIC_DELIVERY_MODE_SMI + 4: IO_APIC_DELIVERY_MODE_NMI + 5: IO_APIC_DELIVERY_MODE_INIT + 7: IO_APIC_DELIVERY_MODE_EXTINT + @param LevelTriggered TRUE specifies a level triggered interrupt. + FALSE specifies an edge triggered interrupt. + @param AssertionLevel TRUE specified an active high interrupt. + FALSE specifies an active low interrupt. +**/ +VOID +EFIAPI +IoApicConfigureInterrupt ( + IN UINTN Irq, + IN UINTN Vector, + IN UINTN DeliveryMode, + IN BOOLEAN LevelTriggered, + IN BOOLEAN AssertionLevel + ) +{ + IO_APIC_VERSION_REGISTER Version; + IO_APIC_REDIRECTION_TABLE_ENTRY Entry; + + Version.Uint32 = IoApicRead (IO_APIC_VERSION_REGISTER_INDEX); + ASSERT (Version.Bits.MaximumRedirectionEntry < 0xF0); + ASSERT (Irq <= Version.Bits.MaximumRedirectionEntry); + ASSERT (Vector <= 0xFF); + ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3); + + Entry.Uint32.Low = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2); + Entry.Bits.Vector = (UINT8)Vector; + Entry.Bits.DeliveryMode = (UINT32)DeliveryMode; + Entry.Bits.DestinationMode = 0; + Entry.Bits.Polarity = AssertionLevel ? 0 : 1; + Entry.Bits.TriggerMode = LevelTriggered ? 1 : 0; + Entry.Bits.Mask = 1; + IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2, Entry.Uint32.Low); + + Entry.Uint32.High = IoApicRead (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1); + Entry.Bits.DestinationID = GetApicId (); + IoApicWrite (IO_APIC_REDIRECTION_TABLE_ENTRY_INDEX + Irq * 2 + 1, Entry.Uint32.High); +} |