Add support for I/O APIC controllers and interrupt override handling
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#ifndef __XTDK_AMD64_HLTYPES_H
|
#ifndef __XTDK_AMD64_HLTYPES_H
|
||||||
#define __XTDK_AMD64_HLTYPES_H
|
#define __XTDK_AMD64_HLTYPES_H
|
||||||
|
|
||||||
|
#include <xtbase.h>
|
||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
@@ -53,6 +54,27 @@
|
|||||||
/* Maximum number of I/O APICs */
|
/* Maximum number of I/O APICs */
|
||||||
#define APIC_MAX_IOAPICS 64
|
#define APIC_MAX_IOAPICS 64
|
||||||
|
|
||||||
|
/* I/O APIC base address */
|
||||||
|
#define IOAPIC_DEFAULT_BASE 0xFEC00000
|
||||||
|
|
||||||
|
/* I/O APIC definitions */
|
||||||
|
#define IOAPIC_MAX_CONTROLLERS 128
|
||||||
|
#define IOAPIC_MAX_OVERRIDES 16
|
||||||
|
#define IOAPIC_RTE_MASKED 0x100FF
|
||||||
|
#define IOAPIC_RTE_SIZE 2
|
||||||
|
#define IOAPIC_VECTOR_FREE 0xFF
|
||||||
|
#define IOAPIC_VECTOR_RESERVED 0xFE
|
||||||
|
|
||||||
|
/* IOAPIC offsets */
|
||||||
|
#define IOAPIC_IOREGSEL 0x00
|
||||||
|
#define IOAPIC_IOWIN 0x10
|
||||||
|
|
||||||
|
/* IOAPIC registers */
|
||||||
|
#define IOAPIC_ID 0x00
|
||||||
|
#define IOAPIC_VER 0x01
|
||||||
|
#define IOAPIC_ARB 0x02
|
||||||
|
#define IOAPIC_REDTBL 0x10
|
||||||
|
|
||||||
/* 8259/ISP PIC ports definitions */
|
/* 8259/ISP PIC ports definitions */
|
||||||
#define PIC1_CONTROL_PORT 0x20
|
#define PIC1_CONTROL_PORT 0x20
|
||||||
#define PIC1_DATA_PORT 0x21
|
#define PIC1_DATA_PORT 0x21
|
||||||
@@ -77,6 +99,13 @@
|
|||||||
/* C/C++ specific code */
|
/* C/C++ specific code */
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
#ifndef __XTOS_ASSEMBLER__
|
||||||
|
|
||||||
|
/* APIC destination mode enumeration list */
|
||||||
|
typedef enum _APIC_DEST_MODE
|
||||||
|
{
|
||||||
|
APIC_DM_Physical,
|
||||||
|
APIC_DM_Logical
|
||||||
|
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
||||||
|
|
||||||
/* APIC delivery mode enumeration list */
|
/* APIC delivery mode enumeration list */
|
||||||
typedef enum _APIC_DM
|
typedef enum _APIC_DM
|
||||||
{
|
{
|
||||||
@@ -274,6 +303,40 @@ typedef union _APIC_SPURIOUS_REGISTER
|
|||||||
};
|
};
|
||||||
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
|
|
||||||
|
/* I/O APIC Controller information */
|
||||||
|
typedef struct _IOAPIC_DATA
|
||||||
|
{
|
||||||
|
ULONG GsiBase;
|
||||||
|
ULONG Identifier;
|
||||||
|
ULONG LineCount;
|
||||||
|
PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
|
ULONG_PTR VirtualAddress;
|
||||||
|
} IOAPIC_DATA, *PIOAPIC_DATA;
|
||||||
|
|
||||||
|
/* I/O APIC Redirection Register */
|
||||||
|
typedef union _IOAPIC_REDIRECTION_REGISTER
|
||||||
|
{
|
||||||
|
ULONGLONG LongLong;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UINT Base;
|
||||||
|
UINT Extended;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONGLONG Vector:8;
|
||||||
|
ULONGLONG DeliveryMode:3;
|
||||||
|
ULONGLONG DestinationMode:1;
|
||||||
|
ULONGLONG DeliveryStatus:1;
|
||||||
|
ULONGLONG PinPolarity:1;
|
||||||
|
ULONGLONG RemoteIRR:1;
|
||||||
|
ULONGLONG TriggerMode:1;
|
||||||
|
ULONGLONG Mask:1;
|
||||||
|
ULONGLONG Reserved:39;
|
||||||
|
ULONGLONG Destination:8;
|
||||||
|
};
|
||||||
|
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
||||||
|
|
||||||
/* I8259 PIC register structure */
|
/* I8259 PIC register structure */
|
||||||
typedef union _PIC_I8259_ICW1
|
typedef union _PIC_I8259_ICW1
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#ifndef __XTOS_ASSEMBLER__
|
#ifndef __XTOS_ASSEMBLER__
|
||||||
|
|
||||||
/* Architecture-specific enumeration lists forward references */
|
/* Architecture-specific enumeration lists forward references */
|
||||||
|
typedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
||||||
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
||||||
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
||||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||||
@@ -45,6 +46,7 @@ typedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;
|
|||||||
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
||||||
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
||||||
typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
typedef struct _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
||||||
|
typedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;
|
||||||
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
||||||
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||||
@@ -76,6 +78,7 @@ typedef union _APIC_BASE_REGISTER APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER;
|
|||||||
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
|
typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER;
|
||||||
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
||||||
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
|
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
||||||
typedef union _MMPTE MMP5E, *PMMP5E;
|
typedef union _MMPTE MMP5E, *PMMP5E;
|
||||||
typedef union _MMPTE MMPDE, *PMMPDE;
|
typedef union _MMPTE MMPDE, *PMMPDE;
|
||||||
typedef union _MMPTE MMPPE, *PMMPPE;
|
typedef union _MMPTE MMPPE, *PMMPPE;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#ifndef __XTDK_I686_HLTYPES_H
|
#ifndef __XTDK_I686_HLTYPES_H
|
||||||
#define __XTDK_I686_HLTYPES_H
|
#define __XTDK_I686_HLTYPES_H
|
||||||
|
|
||||||
|
#include <xtbase.h>
|
||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
@@ -58,6 +59,27 @@
|
|||||||
/* Maximum number of I/O APICs */
|
/* Maximum number of I/O APICs */
|
||||||
#define APIC_MAX_IOAPICS 64
|
#define APIC_MAX_IOAPICS 64
|
||||||
|
|
||||||
|
/* I/O APIC base address */
|
||||||
|
#define IOAPIC_DEFAULT_BASE 0xFEC00000
|
||||||
|
|
||||||
|
/* I/O APIC definitions */
|
||||||
|
#define IOAPIC_MAX_CONTROLLERS 64
|
||||||
|
#define IOAPIC_MAX_OVERRIDES 16
|
||||||
|
#define IOAPIC_RTE_MASKED 0x100FF
|
||||||
|
#define IOAPIC_RTE_SIZE 2
|
||||||
|
#define IOAPIC_VECTOR_FREE 0xFF
|
||||||
|
#define IOAPIC_VECTOR_RESERVED 0xFE
|
||||||
|
|
||||||
|
/* IOAPIC offsets */
|
||||||
|
#define IOAPIC_IOREGSEL 0x00
|
||||||
|
#define IOAPIC_IOWIN 0x10
|
||||||
|
|
||||||
|
/* IOAPIC registers */
|
||||||
|
#define IOAPIC_ID 0x00
|
||||||
|
#define IOAPIC_VER 0x01
|
||||||
|
#define IOAPIC_ARB 0x02
|
||||||
|
#define IOAPIC_REDTBL 0x10
|
||||||
|
|
||||||
/* 8259/ISP PIC ports definitions */
|
/* 8259/ISP PIC ports definitions */
|
||||||
#define PIC1_CONTROL_PORT 0x20
|
#define PIC1_CONTROL_PORT 0x20
|
||||||
#define PIC1_DATA_PORT 0x21
|
#define PIC1_DATA_PORT 0x21
|
||||||
@@ -84,6 +106,13 @@
|
|||||||
/* C/C++ specific code */
|
/* C/C++ specific code */
|
||||||
#ifndef __XTOS_ASSEMBLER__
|
#ifndef __XTOS_ASSEMBLER__
|
||||||
|
|
||||||
|
/* APIC destination mode enumeration list */
|
||||||
|
typedef enum _APIC_DEST_MODE
|
||||||
|
{
|
||||||
|
APIC_DM_Physical,
|
||||||
|
APIC_DM_Logical
|
||||||
|
} APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
||||||
|
|
||||||
/* APIC delivery mode enumeration list */
|
/* APIC delivery mode enumeration list */
|
||||||
typedef enum _APIC_DM
|
typedef enum _APIC_DM
|
||||||
{
|
{
|
||||||
@@ -281,6 +310,40 @@ typedef union _APIC_SPURIOUS_REGISTER
|
|||||||
};
|
};
|
||||||
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
} APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
|
|
||||||
|
/* I/O APIC Controller information */
|
||||||
|
typedef struct _IOAPIC_DATA
|
||||||
|
{
|
||||||
|
ULONG GsiBase;
|
||||||
|
ULONG Identifier;
|
||||||
|
ULONG LineCount;
|
||||||
|
PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
|
ULONG_PTR VirtualAddress;
|
||||||
|
} IOAPIC_DATA, *PIOAPIC_DATA;
|
||||||
|
|
||||||
|
/* I/O APIC Redirection Register */
|
||||||
|
typedef union _IOAPIC_REDIRECTION_REGISTER
|
||||||
|
{
|
||||||
|
ULONGLONG LongLong;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UINT Base;
|
||||||
|
UINT Extended;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONGLONG Vector:8;
|
||||||
|
ULONGLONG DeliveryMode:3;
|
||||||
|
ULONGLONG DestinationMode:1;
|
||||||
|
ULONGLONG DeliveryStatus:1;
|
||||||
|
ULONGLONG PinPolarity:1;
|
||||||
|
ULONGLONG RemoteIRR:1;
|
||||||
|
ULONGLONG TriggerMode:1;
|
||||||
|
ULONGLONG Mask:1;
|
||||||
|
ULONGLONG Reserved:39;
|
||||||
|
ULONGLONG Destination:8;
|
||||||
|
};
|
||||||
|
} IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
||||||
|
|
||||||
/* I8259 PIC register structure */
|
/* I8259 PIC register structure */
|
||||||
typedef union _PIC_I8259_ICW1
|
typedef union _PIC_I8259_ICW1
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#ifndef __XTOS_ASSEMBLER__
|
#ifndef __XTOS_ASSEMBLER__
|
||||||
|
|
||||||
/* Architecture-specific enumeration lists forward references */
|
/* Architecture-specific enumeration lists forward references */
|
||||||
|
typedef enum _APIC_DEST_MODE APIC_DEST_MODE, *PAPIC_DEST_MODE;
|
||||||
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
typedef enum _APIC_DM APIC_DM, *PAPIC_DM;
|
||||||
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
typedef enum _APIC_DSH APIC_DSH, *PAPIC_DSH;
|
||||||
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
typedef enum _APIC_MODE APIC_MODE, *PAPIC_MODE;
|
||||||
@@ -48,6 +49,7 @@ typedef struct _FX_SAVE_AREA FX_SAVE_AREA, *PFX_SAVE_AREA;
|
|||||||
typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;
|
typedef struct _FX_SAVE_FORMAT FX_SAVE_FORMAT, *PFX_SAVE_FORMAT;
|
||||||
typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
|
typedef struct _HARDWARE_LEGACY_PTE HARDWARE_LEGACY_PTE, *PHARDWARE_LEGACY_PTE;
|
||||||
typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
|
typedef struct _HARDWARE_MODERN_PTE HARDWARE_MODERN_PTE, *PHARDWARE_MODERN_PTE;
|
||||||
|
typedef struct _IOAPIC_DATA IOAPIC_DATA, *PIOAPIC_DATA;
|
||||||
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR;
|
||||||
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
|
||||||
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY;
|
||||||
@@ -86,6 +88,7 @@ typedef union _APIC_COMMAND_REGISTER APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGIS
|
|||||||
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
typedef union _APIC_LVT_REGISTER APIC_LVT_REGISTER, *PAPIC_LVT_REGISTER;
|
||||||
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
typedef union _APIC_SPURIOUS_REGISTER APIC_SPURIOUS_REGISTER, *PAPIC_SPURIOUS_REGISTER;
|
||||||
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
typedef union _HARDWARE_PTE HARDWARE_PTE, *PHARDWARE_PTE;
|
||||||
|
typedef union _IOAPIC_REDIRECTION_REGISTER IOAPIC_REDIRECTION_REGISTER, *PIOAPIC_REDIRECTION_REGISTER;
|
||||||
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
|
typedef union _MMPML2_PTE MMPML2_PTE, *PMMPML2_PTE;
|
||||||
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
|
typedef union _MMPML3_PTE MMPML3_PTE, *PMMPML3_PTE;
|
||||||
typedef union _MMPTE MMPDE, *PMMPDE;
|
typedef union _MMPTE MMPDE, *PMMPDE;
|
||||||
|
|||||||
@@ -39,6 +39,21 @@ HL_SCROLL_REGION_DATA HL::FrameBuffer::ScrollRegionData;
|
|||||||
/* APIC mode */
|
/* APIC mode */
|
||||||
APIC_MODE HL::Pic::ApicMode;
|
APIC_MODE HL::Pic::ApicMode;
|
||||||
|
|
||||||
|
/* Number of I/O APIC controllers */
|
||||||
|
ULONG HL::Pic::ControllerCount;
|
||||||
|
|
||||||
|
/* I/O APIC controllers information */
|
||||||
|
IOAPIC_DATA HL::Pic::Controllers[IOAPIC_MAX_CONTROLLERS];
|
||||||
|
|
||||||
|
/* Number of I/O APIC overrides */
|
||||||
|
ULONG HL::Pic::IrqOverrideCount;
|
||||||
|
|
||||||
|
/* I/O APIC overrides information */
|
||||||
|
ACPI_MADT_INTERRUPT_OVERRIDE HL::Pic::IrqOverrides[IOAPIC_MAX_OVERRIDES];
|
||||||
|
|
||||||
|
/* Mapped interrupt vectors */
|
||||||
|
UCHAR HL::Pic::MappedVectors[256];
|
||||||
|
|
||||||
/* Kernel profiling interval */
|
/* Kernel profiling interval */
|
||||||
ULONG HL::Timer::ProfilingInterval;
|
ULONG HL::Timer::ProfilingInterval;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,62 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates, maps and commits a requested system interrupt level internally.
|
||||||
|
*
|
||||||
|
* @param RunLevel
|
||||||
|
* Supplies the actual system run level to allocate.
|
||||||
|
*
|
||||||
|
* @param Vector
|
||||||
|
* Supplies the interrupt handler vector assigned to process requests originating on the line.
|
||||||
|
*
|
||||||
|
* @return This routine returns the configured target vector.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::Pic::AllocateSystemInterrupt(IN UCHAR Irq,
|
||||||
|
IN UCHAR RunLevel,
|
||||||
|
IN UCHAR Vector)
|
||||||
|
{
|
||||||
|
IOAPIC_REDIRECTION_REGISTER Register;
|
||||||
|
PIOAPIC_DATA Controller;
|
||||||
|
ULONG EntryNumber, Gsi;
|
||||||
|
XTSTATUS Status;
|
||||||
|
USHORT Flags;
|
||||||
|
|
||||||
|
/* Determine the GSI and flags for the requested IRQ */
|
||||||
|
ResolveInterruptOverride(Irq, &Gsi, &Flags);
|
||||||
|
|
||||||
|
/* Find the APIC controller for the GSI */
|
||||||
|
Status = GetIoApicController(Gsi, &Controller, &EntryNumber);
|
||||||
|
if(Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* GSI maps to an invalid controller, return */
|
||||||
|
DebugPrint(L"ERROR: Hardware IRQ / GSI maps to an invalid controller!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Model a logical connection */
|
||||||
|
Register.DeliveryMode = APIC_DM_LOWPRIO;
|
||||||
|
Register.DeliveryStatus = 0;
|
||||||
|
Register.Destination = HL::Pic::ReadApicRegister(APIC_ID) >> 24;
|
||||||
|
Register.DestinationMode = APIC_DM_Physical;
|
||||||
|
Register.Mask = 1;
|
||||||
|
Register.PinPolarity = ((Flags & 0x03) == 0x03) ? 1 : 0;
|
||||||
|
Register.RemoteIRR = 0;
|
||||||
|
Register.Reserved = 0;
|
||||||
|
Register.TriggerMode = (((Flags >> 2) & 0x03) == 0x03) ? APIC_TGM_LEVEL : APIC_TGM_EDGE;
|
||||||
|
Register.Vector = Vector;
|
||||||
|
|
||||||
|
/* Flash logical rules back into the hardware configuration index */
|
||||||
|
WriteRedirectionEntry(Controller, EntryNumber, Register);
|
||||||
|
|
||||||
|
/* Persist the allocated slot so standard routing algorithms don't overlap it */
|
||||||
|
MappedVectors[Vector] = RunLevel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the APIC is supported by the processor.
|
* Checks whether the APIC is supported by the processor.
|
||||||
*
|
*
|
||||||
@@ -97,6 +153,105 @@ HL::Pic::ClearApicErrors(VOID)
|
|||||||
WriteApicRegister(APIC_ESR, 0);
|
WriteApicRegister(APIC_ESR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches the ACPI MADT tables for the I/O APIC controllers.
|
||||||
|
*
|
||||||
|
* @return This routine returns the status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
XTSTATUS
|
||||||
|
HL::Pic::DetectIoApicControllers(VOID)
|
||||||
|
{
|
||||||
|
PACPI_MADT_INTERRUPT_OVERRIDE OverrideDescriptor;
|
||||||
|
PACPI_MADT_IOAPIC IoApicDescriptor;
|
||||||
|
PACPI_SUBTABLE_HEADER SubTable;
|
||||||
|
ULONG_PTR MadtTable;
|
||||||
|
PACPI_MADT Madt;
|
||||||
|
XTSTATUS Status;
|
||||||
|
|
||||||
|
/* Initialize number of I/O APIC Controllers */
|
||||||
|
ControllerCount = 0;
|
||||||
|
|
||||||
|
/* Get Multiple APIC Description Table (MADT) */
|
||||||
|
Status = HL::Acpi::GetAcpiTable(ACPI_MADT_SIGNATURE, (PACPI_DESCRIPTION_HEADER*)&Madt);
|
||||||
|
if(Status == STATUS_SUCCESS && Madt != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Set APIC table traverse pointer */
|
||||||
|
MadtTable = (ULONG_PTR)Madt->ApicTables;
|
||||||
|
|
||||||
|
/* Traverse all MADT tables to discover IOAPIC configurations */
|
||||||
|
while(MadtTable < ((ULONG_PTR)Madt + Madt->Header.Length))
|
||||||
|
{
|
||||||
|
/* Extract active header element */
|
||||||
|
SubTable = (PACPI_SUBTABLE_HEADER)MadtTable;
|
||||||
|
|
||||||
|
/* Prevent infinite traversal loops on corrupted firmware definitions */
|
||||||
|
if(SubTable->Length == 0)
|
||||||
|
{
|
||||||
|
/* Invalid MADT table, break loop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test specifically for I/O APIC component identity */
|
||||||
|
if(SubTable->Type == ACPI_MADT_TYPE_IOAPIC &&
|
||||||
|
SubTable->Length >= sizeof(ACPI_MADT_IOAPIC))
|
||||||
|
{
|
||||||
|
/* Extract I/O APIC descriptor */
|
||||||
|
IoApicDescriptor = (PACPI_MADT_IOAPIC)MadtTable;
|
||||||
|
|
||||||
|
/* Set information about this I/O APIC Controller */
|
||||||
|
Controllers[ControllerCount].GsiBase = IoApicDescriptor->GlobalIrqBase;
|
||||||
|
Controllers[ControllerCount].Identifier = IoApicDescriptor->IoApicId;
|
||||||
|
Controllers[ControllerCount].PhysicalAddress.QuadPart = IoApicDescriptor->IoApicAddress;
|
||||||
|
|
||||||
|
/* Increment I/O APIC controller index */
|
||||||
|
ControllerCount++;
|
||||||
|
}
|
||||||
|
else if(SubTable->Type == ACPI_MADT_TYPE_INT_OVERRIDE &&
|
||||||
|
SubTable->Length >= sizeof(ACPI_MADT_INTERRUPT_OVERRIDE))
|
||||||
|
{
|
||||||
|
/* Check if maximum number of interrupt overrides has not been reached */
|
||||||
|
if(IrqOverrideCount < IOAPIC_MAX_OVERRIDES)
|
||||||
|
{
|
||||||
|
/* Extract interrupt override descriptor */
|
||||||
|
OverrideDescriptor = (PACPI_MADT_INTERRUPT_OVERRIDE)MadtTable;
|
||||||
|
|
||||||
|
/* Save information about this interrupt override */
|
||||||
|
IrqOverrides[IrqOverrideCount].Bus = OverrideDescriptor->Bus;
|
||||||
|
IrqOverrides[IrqOverrideCount].Flags = OverrideDescriptor->Flags;
|
||||||
|
IrqOverrides[IrqOverrideCount].GlobalSystemInterrupt = OverrideDescriptor->GlobalSystemInterrupt;
|
||||||
|
IrqOverrides[IrqOverrideCount].SourceIrq = OverrideDescriptor->SourceIrq;
|
||||||
|
|
||||||
|
/* Increment interrupt override index */
|
||||||
|
IrqOverrideCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure, maximum number of I/O APIC controllers has not been reached */
|
||||||
|
if(ControllerCount >= IOAPIC_MAX_CONTROLLERS)
|
||||||
|
{
|
||||||
|
/* No more I/O APIC controllers supported, break loop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go to the next subtable */
|
||||||
|
MadtTable += SubTable->Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if any I/O APIC controllers were found */
|
||||||
|
if(ControllerCount == 0)
|
||||||
|
{
|
||||||
|
/* No I/O APIC controllers found, return failure */
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the local APIC ID of the current processor.
|
* Gets the local APIC ID of the current processor.
|
||||||
*
|
*
|
||||||
@@ -117,6 +272,48 @@ HL::Pic::GetCpuApicId(VOID)
|
|||||||
return (ApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId;
|
return (ApicMode == APIC_MODE_COMPAT) ? ((ApicId & 0xFFFFFFFF) >> APIC_XAPIC_LDR_SHIFT) : ApicId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the I/O APIC controller information for the specified GSI.
|
||||||
|
*
|
||||||
|
* @param Gsi
|
||||||
|
* Supplies the GSI to get the I/O APIC controller information for.
|
||||||
|
*
|
||||||
|
* @param Controller
|
||||||
|
* Supplies a pointer to the memory area where the I/O APIC controller information will be stored.
|
||||||
|
*
|
||||||
|
* @param EntryNumber
|
||||||
|
* Supplies a pointer to the memory area where the entry number will be stored.
|
||||||
|
*
|
||||||
|
* @return This routine returns the status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
XTSTATUS
|
||||||
|
HL::Pic::GetIoApicController(IN ULONG Gsi,
|
||||||
|
OUT PIOAPIC_DATA *Controller,
|
||||||
|
OUT PULONG EntryNumber)
|
||||||
|
{
|
||||||
|
ULONG ControllerIndex;
|
||||||
|
|
||||||
|
/* Iterate over all available I/O APIC controllers */
|
||||||
|
for(ControllerIndex = 0; ControllerIndex < ControllerCount; ControllerIndex++)
|
||||||
|
{
|
||||||
|
/* Check if the GSI belongs to this I/O APIC controller */
|
||||||
|
if(Gsi >= Controllers[ControllerIndex].GsiBase &&
|
||||||
|
Gsi < (Controllers[ControllerIndex].GsiBase + Controllers[ControllerIndex].LineCount))
|
||||||
|
{
|
||||||
|
/* Return I/O APIC controller information */
|
||||||
|
*Controller = &Controllers[ControllerIndex];
|
||||||
|
*EntryNumber = (ULONG)(Gsi - Controllers[ControllerIndex].GsiBase);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GSI does not belong to any I/O APIC controller, return failure */
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the APIC interrupt controller.
|
* Initializes the APIC interrupt controller.
|
||||||
*
|
*
|
||||||
@@ -137,7 +334,7 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
if(!CheckApicSupport())
|
if(!CheckApicSupport())
|
||||||
{
|
{
|
||||||
/* APIC is not supported, raise kernel panic */
|
/* APIC is not supported, raise kernel panic */
|
||||||
DebugPrint(L"FATAL ERROR: Local APIC not present.\n");
|
DebugPrint(L"ERROR: Local APIC not present.\n");
|
||||||
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
|
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +430,84 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
WriteApicRegister(APIC_TPR, 0x00);
|
WriteApicRegister(APIC_TPR, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the global I/O APIC controller setup over the entire redirection span.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::Pic::InitializeIOApic(VOID)
|
||||||
|
{
|
||||||
|
ULONG ControllerIndex, LineIndex, Vector, VersionRegister;
|
||||||
|
IOAPIC_REDIRECTION_REGISTER Register;
|
||||||
|
XTSTATUS Status;
|
||||||
|
|
||||||
|
/* Detect I/O APIC controllers */
|
||||||
|
Status = DetectIoApicControllers();
|
||||||
|
if(Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
DebugPrint(L"ERROR: I/O APIC Controller not present.\n");
|
||||||
|
KE::Crash::Panic(0x5D, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate over all I/O APIC controllers */
|
||||||
|
ControllerIndex = 0;
|
||||||
|
while(ControllerIndex < ControllerCount)
|
||||||
|
{
|
||||||
|
/* Map the I/O APIC controller memory into hardware space */
|
||||||
|
MM::HardwarePool::MapHardwareMemory(Controllers[ControllerIndex].PhysicalAddress,
|
||||||
|
1,
|
||||||
|
FALSE,
|
||||||
|
(PVOID*)&Controllers[ControllerIndex].VirtualAddress);
|
||||||
|
|
||||||
|
/* Perform a memory barrier */
|
||||||
|
AR::CpuFunc::MemoryBarrier();
|
||||||
|
AR::CpuFunc::ReadWriteBarrier();
|
||||||
|
|
||||||
|
/* Read the version register and calculate the maximum number of redirection entries */
|
||||||
|
VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER);
|
||||||
|
Controllers[ControllerIndex].LineCount = ((VersionRegister >> 16) & 0xFF) + 1;
|
||||||
|
|
||||||
|
/* Set up the default redirection entry for this controller */
|
||||||
|
Register.DeliveryMode = APIC_DM_FIXED;
|
||||||
|
Register.DeliveryStatus = 0;
|
||||||
|
Register.Destination = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_ID) >> 24;
|
||||||
|
Register.DestinationMode = 0;
|
||||||
|
Register.Mask = 1;
|
||||||
|
Register.PinPolarity = 0;
|
||||||
|
Register.RemoteIRR = 0;
|
||||||
|
Register.Reserved = 0;
|
||||||
|
Register.TriggerMode = APIC_TGM_EDGE;
|
||||||
|
Register.Vector = IOAPIC_VECTOR_FREE;
|
||||||
|
|
||||||
|
/* Propagate defaults across the array of potential handlers */
|
||||||
|
for(LineIndex = 0; LineIndex < Controllers[ControllerIndex].LineCount; LineIndex++)
|
||||||
|
{
|
||||||
|
/* Write default values into the redirection table */
|
||||||
|
WriteRedirectionEntry(&Controllers[ControllerIndex], LineIndex, Register);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print information about the I/O APIC controller */
|
||||||
|
DebugPrint(L"Initialized I/O APIC Controller #%lu at 0x%llX (ID: %lu, GSI Base: %lu, Line Count: %lu)\n",
|
||||||
|
ControllerIndex, Controllers[ControllerIndex].VirtualAddress,
|
||||||
|
Controllers[ControllerIndex].Identifier, Controllers[ControllerIndex].GsiBase,
|
||||||
|
Controllers[ControllerIndex].LineCount);
|
||||||
|
|
||||||
|
/* Go to the next I/O APIC controller */
|
||||||
|
ControllerIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assign initial clean state for mapping translations */
|
||||||
|
for(Vector = 0; Vector <= 255; Vector++)
|
||||||
|
{
|
||||||
|
/* Set vector to free */
|
||||||
|
MappedVectors[Vector] = IOAPIC_VECTOR_FREE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the legacy PIC interrupt controller.
|
* Initializes the legacy PIC interrupt controller.
|
||||||
*
|
*
|
||||||
@@ -357,6 +632,104 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads from the I/O APIC register.
|
||||||
|
*
|
||||||
|
* @param Controller
|
||||||
|
* Supplies the I/O APIC controller to read from.
|
||||||
|
*
|
||||||
|
* @param Register
|
||||||
|
* Supplies the I/O APIC register to read from.
|
||||||
|
*
|
||||||
|
* @return This routine returns the value read from the given IO APIC register.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
ULONG
|
||||||
|
HL::Pic::ReadIOApicRegister(IN PIOAPIC_DATA Controller,
|
||||||
|
IN UCHAR Register)
|
||||||
|
{
|
||||||
|
/* Write the target address into the index register */
|
||||||
|
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);
|
||||||
|
|
||||||
|
/* Fetch the resultant value from the data window */
|
||||||
|
return HL::IoRegister::ReadRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a configuration entry from the I/O APIC redirection table.
|
||||||
|
*
|
||||||
|
* @param Controller
|
||||||
|
* Supplies the I/O APIC controller to read from.
|
||||||
|
*
|
||||||
|
* @param EntryNumber
|
||||||
|
* Supplies the redirection table entry number to read.
|
||||||
|
*
|
||||||
|
* @return This routine returns the populated redirection table entry.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
IOAPIC_REDIRECTION_REGISTER
|
||||||
|
HL::Pic::ReadRedirectionEntry(IN PIOAPIC_DATA Controller,
|
||||||
|
IN ULONG EntryNumber)
|
||||||
|
{
|
||||||
|
IOAPIC_REDIRECTION_REGISTER Register;
|
||||||
|
ULONG Offset;
|
||||||
|
|
||||||
|
/* Derive the offset corresponding to the index */
|
||||||
|
Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);
|
||||||
|
|
||||||
|
/* Read the low and high portions mapping to the 64-bit construct */
|
||||||
|
Register.Base = ReadIOApicRegister(Controller, Offset);
|
||||||
|
Register.Extended = ReadIOApicRegister(Controller, Offset + 1);
|
||||||
|
|
||||||
|
/* Return the redirection table entry */
|
||||||
|
return Register;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the GSI and flags for the specified IRQ.
|
||||||
|
*
|
||||||
|
* @param Irq
|
||||||
|
* Supplies the IRQ number to get the GSI and flags for.
|
||||||
|
*
|
||||||
|
* @param Gsi
|
||||||
|
* Supplies a pointer to the memory area where the GSI will be stored.
|
||||||
|
*
|
||||||
|
* @param Flags
|
||||||
|
* Supplies a pointer to the memory area where the flags will be stored.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::Pic::ResolveInterruptOverride(IN UCHAR Irq,
|
||||||
|
OUT PULONG Gsi,
|
||||||
|
OUT PUSHORT Flags)
|
||||||
|
{
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
/* Iterate over all I/O APIC overrides */
|
||||||
|
for(Index = 0; Index < IrqOverrideCount; Index++)
|
||||||
|
{
|
||||||
|
/* Check if this IRQ has been overridden */
|
||||||
|
if(IrqOverrides[Index].SourceIrq == Irq)
|
||||||
|
{
|
||||||
|
/* Return overridden GSI and flags */
|
||||||
|
*Flags = IrqOverrides[Index].Flags;
|
||||||
|
*Gsi = IrqOverrides[Index].GlobalSystemInterrupt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return original IRQ number as GSI and no flags */
|
||||||
|
*Flags = 0;
|
||||||
|
*Gsi = (ULONG)Irq;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals to the APIC that handling an interrupt is complete.
|
* Signals to the APIC that handling an interrupt is complete.
|
||||||
*
|
*
|
||||||
@@ -387,8 +760,8 @@ HL::Pic::SendEoi(VOID)
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
HL::Pic::SendIpi(ULONG ApicId,
|
HL::Pic::SendIpi(IN ULONG ApicId,
|
||||||
ULONG Vector)
|
IN ULONG Vector)
|
||||||
{
|
{
|
||||||
/* Check current APIC mode */
|
/* Check current APIC mode */
|
||||||
if(ApicMode == APIC_MODE_X2APIC)
|
if(ApicMode == APIC_MODE_X2APIC)
|
||||||
@@ -416,7 +789,7 @@ HL::Pic::SendIpi(ULONG ApicId,
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
HL::Pic::SendSelfIpi(ULONG Vector)
|
HL::Pic::SendSelfIpi(IN ULONG Vector)
|
||||||
{
|
{
|
||||||
BOOLEAN Interrupts;
|
BOOLEAN Interrupts;
|
||||||
|
|
||||||
@@ -460,6 +833,40 @@ HL::Pic::SendSelfIpi(ULONG Vector)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates a given Global System Interrupt (GSI) into an active system interrupt vector.
|
||||||
|
*
|
||||||
|
* @param Gsi
|
||||||
|
* Supplies the GSI to translate.
|
||||||
|
*
|
||||||
|
* @return This routine returns the underlying associated system vector mapping.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
UCHAR
|
||||||
|
HL::Pic::TranslateGsiToVector(IN ULONG Gsi)
|
||||||
|
{
|
||||||
|
IOAPIC_REDIRECTION_REGISTER Register;
|
||||||
|
PIOAPIC_DATA Controller;
|
||||||
|
ULONG EntryNumber;
|
||||||
|
XTSTATUS Status;
|
||||||
|
|
||||||
|
/* Find the APIC controller for the GSI */
|
||||||
|
Status = GetIoApicController(Gsi, &Controller, &EntryNumber);
|
||||||
|
if(Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
/* GSI maps to an invalid controller, return free */
|
||||||
|
return IOAPIC_VECTOR_FREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the redirection table entry */
|
||||||
|
Register.Base = ReadIOApicRegister(Controller, IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE));
|
||||||
|
|
||||||
|
/* Return the vector */
|
||||||
|
return (UCHAR)Register.Vector;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes to the APIC register.
|
* Writes to the APIC register.
|
||||||
*
|
*
|
||||||
@@ -489,3 +896,67 @@ HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
|
|||||||
HL::IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
HL::IoRegister::WriteRegister32((PULONG)(APIC_BASE + (Register << 4)), Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a value to the I/O APIC register.
|
||||||
|
*
|
||||||
|
* @param Controller
|
||||||
|
* Supplies the I/O APIC controller to write to.
|
||||||
|
*
|
||||||
|
* @param Register
|
||||||
|
* Supplies the I/O APIC register to write to.
|
||||||
|
*
|
||||||
|
* @param DataValue
|
||||||
|
* Supplies the value to write to the designated I/O APIC register.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
HL::Pic::WriteIOApicRegister(IN PIOAPIC_DATA Controller,
|
||||||
|
IN UCHAR Register,
|
||||||
|
IN ULONG DataValue)
|
||||||
|
{
|
||||||
|
/* Provide the index to the control port */
|
||||||
|
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOREGSEL), Register);
|
||||||
|
|
||||||
|
/* Commit the value via the data port */
|
||||||
|
HL::IoRegister::WriteRegister32((PULONG)(Controller->VirtualAddress + IOAPIC_IOWIN), DataValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a configuration entry into the I/O APIC redirection table.
|
||||||
|
*
|
||||||
|
* @param Controller
|
||||||
|
* Supplies the I/O APIC controller to write to.
|
||||||
|
*
|
||||||
|
* @param EntryNumber
|
||||||
|
* Supplies the redirection table entry number to write.
|
||||||
|
*
|
||||||
|
* @param EntryData
|
||||||
|
* Supplies the redirection table entry data to write.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTFASTCALL
|
||||||
|
VOID
|
||||||
|
HL::Pic::WriteRedirectionEntry(IN PIOAPIC_DATA Controller,
|
||||||
|
IN ULONG EntryNumber,
|
||||||
|
IN IOAPIC_REDIRECTION_REGISTER EntryData)
|
||||||
|
{
|
||||||
|
ULONG Offset;
|
||||||
|
|
||||||
|
/* Calculate the offset of the redirection entry */
|
||||||
|
Offset = IOAPIC_REDTBL + (EntryNumber * IOAPIC_RTE_SIZE);
|
||||||
|
|
||||||
|
/* Mask the entry to prevent spurious interrupts */
|
||||||
|
WriteIOApicRegister(Controller, Offset, IOAPIC_RTE_MASKED);
|
||||||
|
|
||||||
|
/* Write the lower and upper chunks of the entry */
|
||||||
|
WriteIOApicRegister(Controller, Offset + 1, EntryData.Extended);
|
||||||
|
WriteIOApicRegister(Controller, Offset, EntryData.Base);
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,24 +19,51 @@ namespace HL
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
STATIC APIC_MODE ApicMode;
|
STATIC APIC_MODE ApicMode;
|
||||||
|
STATIC ULONG ControllerCount;
|
||||||
|
STATIC IOAPIC_DATA Controllers[IOAPIC_MAX_CONTROLLERS];
|
||||||
|
STATIC ULONG IrqOverrideCount;
|
||||||
|
STATIC ACPI_MADT_INTERRUPT_OVERRIDE IrqOverrides[IOAPIC_MAX_OVERRIDES];
|
||||||
|
STATIC UCHAR MappedVectors[256];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI VOID ClearApicErrors(VOID);
|
STATIC XTAPI VOID ClearApicErrors(VOID);
|
||||||
STATIC XTAPI ULONG GetCpuApicId(VOID);
|
STATIC XTAPI ULONG GetCpuApicId(VOID);
|
||||||
|
STATIC XTAPI VOID InitializeIOApic(VOID);
|
||||||
STATIC XTAPI VOID InitializePic(VOID);
|
STATIC XTAPI VOID InitializePic(VOID);
|
||||||
STATIC XTFASTCALL ULONGLONG ReadApicRegister(IN APIC_REGISTER Register);
|
STATIC XTFASTCALL ULONGLONG ReadApicRegister(IN APIC_REGISTER Register);
|
||||||
STATIC XTAPI VOID SendEoi(VOID);
|
STATIC XTAPI VOID SendEoi(VOID);
|
||||||
STATIC XTAPI VOID SendIpi(ULONG ApicId,
|
STATIC XTAPI VOID SendIpi(IN ULONG ApicId,
|
||||||
ULONG Vector);
|
IN ULONG Vector);
|
||||||
STATIC XTAPI VOID SendSelfIpi(ULONG Vector);
|
STATIC XTAPI VOID SendSelfIpi(IN ULONG Vector);
|
||||||
STATIC XTFASTCALL VOID WriteApicRegister(IN APIC_REGISTER Register,
|
STATIC XTFASTCALL VOID WriteApicRegister(IN APIC_REGISTER Register,
|
||||||
IN ULONGLONG Value);
|
IN ULONGLONG Value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
STATIC XTAPI VOID AllocateSystemInterrupt(IN UCHAR Irq,
|
||||||
|
IN UCHAR RunLevel,
|
||||||
|
IN UCHAR Vector);
|
||||||
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
|
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
|
||||||
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
|
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
|
||||||
|
STATIC XTAPI XTSTATUS DetectIoApicControllers(VOID);
|
||||||
|
STATIC XTAPI VOID ResolveInterruptOverride(IN UCHAR Irq,
|
||||||
|
OUT PULONG Gsi,
|
||||||
|
OUT PUSHORT Flags);
|
||||||
|
STATIC XTAPI XTSTATUS GetIoApicController(IN ULONG Gsi,
|
||||||
|
OUT PIOAPIC_DATA *Controller,
|
||||||
|
OUT PULONG EntryNumber);
|
||||||
STATIC XTAPI VOID InitializeApic(VOID);
|
STATIC XTAPI VOID InitializeApic(VOID);
|
||||||
STATIC XTAPI VOID InitializeLegacyPic(VOID);
|
STATIC XTAPI VOID InitializeLegacyPic(VOID);
|
||||||
|
STATIC XTFASTCALL ULONG ReadIOApicRegister(IN PIOAPIC_DATA Controller,
|
||||||
|
IN UCHAR Register);
|
||||||
|
STATIC XTFASTCALL IOAPIC_REDIRECTION_REGISTER ReadRedirectionEntry(IN PIOAPIC_DATA Controller,
|
||||||
|
IN ULONG EntryNumber);
|
||||||
|
STATIC XTFASTCALL UCHAR TranslateGsiToVector(IN ULONG Gsi);
|
||||||
|
STATIC XTFASTCALL VOID WriteIOApicRegister(IN PIOAPIC_DATA Controller,
|
||||||
|
IN UCHAR Register,
|
||||||
|
IN ULONG DataValue);
|
||||||
|
STATIC XTFASTCALL VOID WriteRedirectionEntry(IN PIOAPIC_DATA Controller,
|
||||||
|
IN ULONG EntryNumber,
|
||||||
|
IN IOAPIC_REDIRECTION_REGISTER EntryData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user