From 986d1dfb0813d6a7623531e85c2e2a7e1f956cf8 Mon Sep 17 00:00:00 2001 From: mdkinney Date: Fri, 2 Sep 2011 02:43:51 +0000 Subject: Add generic HPET Timer DXE Driver and support libraries Signed-off-by: mdkinney Reviewed-by: li-elvin git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12260 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/BaseIoApicLib/BaseIoApicLib.inf | 38 +++++ PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c | 158 +++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf create mode 100644 PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c (limited to 'PcAtChipsetPkg/Library') diff --git a/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf b/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf new file mode 100644 index 0000000000..10d3977ff3 --- /dev/null +++ b/PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf @@ -0,0 +1,38 @@ +## @file +# Library instance for I/O APIC library class +# +# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# 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 +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseIoApicLib + 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 diff --git a/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c b/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c new file mode 100644 index 0000000000..42b3f21ec1 --- /dev/null +++ b/PcAtChipsetPkg/Library/BaseIoApicLib/IoApicLib.c @@ -0,0 +1,158 @@ +/** @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, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + 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 + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +#include +#include +#include +#include + +#include + +/** + 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 currntly 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); +} -- cgit v1.2.3