diff --git a/sdk/xtdk/amd64/hltypes.h b/sdk/xtdk/amd64/hltypes.h index e50334b..7c800af 100644 --- a/sdk/xtdk/amd64/hltypes.h +++ b/sdk/xtdk/amd64/hltypes.h @@ -73,6 +73,28 @@ /* Initial stall factor */ #define INITIAL_STALL_FACTOR 100 +/* APIC destination short-hand enumeration list */ +typedef enum _APIC_DSH +{ + APIC_DSH_Destination, + APIC_DSH_Self, + APIC_DSH_AllIncludingSelf, + APIC_DSH_AllExclusingSelf +} APIC_DSH, *PAPIC_DSH; + +/* APIC message type enumeration list */ +typedef enum _APIC_MT +{ + APIC_MT_Fixed = 0, + APIC_MT_LowestPriority = 1, + APIC_MT_SMI = 2, + APIC_MT_RemoteRead = 3, + APIC_MT_NMI = 4, + APIC_MT_INIT = 5, + APIC_MT_Startup = 6, + APIC_MT_ExtInt = 7, +} APIC_MT, *PAPIC_MT; + /* APIC Base Register */ typedef union _APIC_BASE_REGISTER { @@ -89,6 +111,31 @@ typedef union _APIC_BASE_REGISTER }; } APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; +/* APIC Command Register */ +typedef union _APIC_COMMAND_REGISTER +{ + ULONGLONG LongLong; + struct + { + ULONG Long0; + ULONG Long1; + }; + struct + { + ULONGLONG Vector:8; + ULONGLONG MessageType:3; + ULONGLONG DestinationMode:1; + ULONGLONG DeliveryStatus:1; + ULONGLONG ReservedMBZ:1; + ULONGLONG Level:1; + ULONGLONG TriggerMode:1; + ULONGLONG RemoteReadStatus:2; + ULONGLONG DestinationShortHand:2; + ULONGLONG Reserved2MBZ:36; + ULONGLONG Destination:8; + }; +} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; + /* APIC Local Vector Table (LVT) Register */ typedef union _APIC_LVT_REGISTER { diff --git a/sdk/xtdk/i686/hltypes.h b/sdk/xtdk/i686/hltypes.h index 322e9c9..fda9d58 100644 --- a/sdk/xtdk/i686/hltypes.h +++ b/sdk/xtdk/i686/hltypes.h @@ -78,6 +78,28 @@ /* Initial stall factor */ #define INITIAL_STALL_FACTOR 100 +/* APIC destination short-hand enumeration list */ +typedef enum _APIC_DSH +{ + APIC_DSH_Destination, + APIC_DSH_Self, + APIC_DSH_AllIncludingSelf, + APIC_DSH_AllExclusingSelf +} APIC_DSH, *PAPIC_DSH; + +/* APIC message type enumeration list */ +typedef enum _APIC_MT +{ + APIC_MT_Fixed = 0, + APIC_MT_LowestPriority = 1, + APIC_MT_SMI = 2, + APIC_MT_RemoteRead = 3, + APIC_MT_NMI = 4, + APIC_MT_INIT = 5, + APIC_MT_Startup = 6, + APIC_MT_ExtInt = 7, +} APIC_MT, *PAPIC_MT; + /* APIC Base Register */ typedef union _APIC_BASE_REGISTER { @@ -94,6 +116,31 @@ typedef union _APIC_BASE_REGISTER }; } APIC_BASE_REGISTER, *PAPIC_BASE_REGISTER; +/* APIC Command Register */ +typedef union _APIC_COMMAND_REGISTER +{ + ULONGLONG LongLong; + struct + { + ULONG Long0; + ULONG Long1; + }; + struct + { + ULONGLONG Vector:8; + ULONGLONG MessageType:3; + ULONGLONG DestinationMode:1; + ULONGLONG DeliveryStatus:1; + ULONGLONG ReservedMBZ:1; + ULONGLONG Level:1; + ULONGLONG TriggerMode:1; + ULONGLONG RemoteReadStatus:2; + ULONGLONG DestinationShortHand:2; + ULONGLONG Reserved2MBZ:36; + ULONGLONG Destination:8; + }; +} APIC_COMMAND_REGISTER, *PAPIC_COMMAND_REGISTER; + /* APIC Local Vector Table (LVT) Register */ typedef union _APIC_LVT_REGISTER { diff --git a/xtoskrnl/hl/x86/pic.c b/xtoskrnl/hl/x86/pic.c index 7283ccc..4ec637f 100644 --- a/xtoskrnl/hl/x86/pic.c +++ b/xtoskrnl/hl/x86/pic.c @@ -36,6 +36,7 @@ XTAPI VOID HlDisableLegacyPic(VOID) { + /* Mask all interrupts */ HlIoPortOutByte(PIC1_DATA_PORT, 0xFF); HlIoPortOutByte(PIC2_DATA_PORT, 0xFF); } @@ -189,9 +190,10 @@ XTAPI VOID HlpInitializeApic() { + APIC_SPURIOUS_REGISTER SpuriousRegister; + APIC_COMMAND_REGISTER CommandRegister; APIC_BASE_REGISTER BaseRegister; APIC_LVT_REGISTER LvtRegister; - APIC_SPURIOUS_REGISTER SpuriousRegister; ULONG CpuNumber; /* Check if this is an x2APIC compatible machine */ @@ -216,6 +218,9 @@ HlpInitializeApic() BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0; ArWriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong); + /* Raise APIC task priority (TPR) to mask off all interrupts */ + HlWriteApicRegister(APIC_TPR, 0xFF); + /* xAPIC compatibility mode specific initialization */ if(HlpApicMode == APIC_MODE_COMPAT) { @@ -263,12 +268,23 @@ HlpInitializeApic() LvtRegister.TriggerMode = APIC_TGM_LEVEL; HlWriteApicRegister(APIC_LINT1, LvtRegister.Long); + /* Mask ICR0 */ + CommandRegister.Long0 = 0; + CommandRegister.Vector = APIC_VECTOR_ZERO; + CommandRegister.MessageType = APIC_MT_INIT; + CommandRegister.TriggerMode = APIC_TGM_LEVEL; + CommandRegister.DestinationShortHand = APIC_DSH_AllIncludingSelf; + HlWriteApicRegister(APIC_ICR0, CommandRegister.Long0); + /* Clear errors after enabling vectors */ HlWriteApicRegister(APIC_ESR, 0); /* Register interrupt handlers once the APIC initialization is done */ KeSetInterruptHandler(APIC_VECTOR_SPURIOUS, HlpHandleApicSpuriousService); KeSetInterruptHandler(PIC1_VECTOR_SPURIOUS, HlpHandlePicSpuriousService); + + /* Lower APIC TPR to re-enable interrupts */ + HlWriteApicRegister(APIC_TPR, 0x00); } /**