From 83e1aa78250127b7dcd76ce6bc527a539b292fd2 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 12 Feb 2018 18:55:34 +0100 Subject: [PATCH] Kernel : Slight refactorings regarding irq levels and such (shouldn't break anything) --- import/OpenXDK/include/xboxkrnl/xboxkrnl.h | 7 ++++- src/CxbxKrnl/CxbxKrnl.cpp | 18 ++++++++----- src/CxbxKrnl/CxbxKrnl.h | 9 +++---- src/CxbxKrnl/EmuFS.cpp | 17 ++++-------- src/CxbxKrnl/EmuKrnl.cpp | 15 +++++++---- src/CxbxKrnl/EmuKrnlHal.cpp | 11 +++++--- src/CxbxKrnl/EmuKrnlKe.cpp | 30 ++++------------------ 7 files changed, 48 insertions(+), 59 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h index 7fb15edbc..0f42adab0 100644 --- a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h +++ b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h @@ -1708,12 +1708,17 @@ KINTERRUPT_MODE; // ****************************************************************** // * IRQ (Interrupt ReQuest) Priority Levels // ****************************************************************** +#define APC_LEVEL 1 #define DISPATCH_LEVEL 2 -#define PROFILE_LEVEL 27 +#define PROFILE_LEVEL 26 #define SYNC_LEVEL 28 +#define HIGH_LEVEL 31 #define DISPATCH_SIZE 22 +#define IRQL_NOT_GREATER_OR_EQUAL 0x00000009 +#define IRQL_NOT_LESS_OR_EQUAL 0x0000000A + // ****************************************************************** // * KINTERRUPR // ****************************************************************** diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index f20e62f14..730c4460a 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -498,6 +498,16 @@ void PrintCurrentConfigurationLog() printf("------------------------- END OF CONFIG LOG ------------------------\n"); } +void TriggerPendingConnectedInterrupts() +{ + for (int i = 0; i < MAX_BUS_INTERRUPT_LEVEL; i++) { + // If the interrupt is pending and connected, process it + if (HalSystemInterrupts[i].IsPending() && EmuInterruptList[i]->Connected) { + HalSystemInterrupts[i].Trigger(EmuInterruptList[i]); + } + } +} + static unsigned int WINAPI CxbxKrnlInterruptThread(PVOID param) { CxbxSetThreadName("CxbxKrnl Interrupts"); @@ -506,13 +516,7 @@ static unsigned int WINAPI CxbxKrnlInterruptThread(PVOID param) InitXboxThread(g_CPUXbox); while (true) { - for (int i = 0; i < MAX_BUS_INTERRUPT_LEVEL; i++) { - // If the interrupt is pending and connected, process it - if (HalSystemInterrupts[i].IsPending() && EmuInterruptList[i]->Connected) { - HalSystemInterrupts[i].Trigger(EmuInterruptList[i]); - } - } - + TriggerPendingConnectedInterrupts(); SwitchToThread(); } diff --git a/src/CxbxKrnl/CxbxKrnl.h b/src/CxbxKrnl/CxbxKrnl.h index 26931420b..88886ffbb 100644 --- a/src/CxbxKrnl/CxbxKrnl.h +++ b/src/CxbxKrnl/CxbxKrnl.h @@ -56,9 +56,9 @@ extern "C" { #define ONE_MB (1024 * 1024) #define X64KB 64 * ONE_KB -// Thread Information Block offsets - see https://www.microsoft.com/msj/archive/S2CE.aspx -#define TIB_ArbitraryDataSlot 0x14 -#define TIB_LinearSelfAddress 0x18 +// NT_TIB (Thread Information Block) offsets - see https://www.microsoft.com/msj/archive/S2CE.aspx +#define TIB_ArbitraryDataSlot 0x14 // = 20 = offsetof(NT_TIB, ArbitraryUserPointer) +#define TIB_LinearSelfAddress 0x18 // = 24 = offsetof(NT_TIB, Self) #define XBADDR_BITS 32 #define XBADDR_MAX UINT32_MAX @@ -141,7 +141,6 @@ extern "C" { #define CXBX_BASE_OF_CODE 0x00001000 #define MAX_BUS_INTERRUPT_LEVEL 27 -// MAX_BUS_INTERRUPT_LEVEL = PROFILE_LEVEL = 27 #define MAX_NUM_INTERRUPTS 256 #define IRQ_BASE 0x30 @@ -150,7 +149,7 @@ extern "C" { // Source : ReactOS halirq.h : https://doxygen.reactos.org/d1/da9/halppc_2include_2halirq_8h_source.html #define IRQ2VECTOR(irq) ((irq)+IRQ_BASE) #define VECTOR2IRQ(vector) ((vector)-IRQ_BASE) -#define VECTOR2IRQL(vector) (PROFILE_LEVEL - VECTOR2IRQ(vector)) +#define VECTOR2IRQL(vector) (MAX_BUS_INTERRUPT_LEVEL - VECTOR2IRQ(vector)) // Kernel boot flags enum { diff --git a/src/CxbxKrnl/EmuFS.cpp b/src/CxbxKrnl/EmuFS.cpp index 3627de099..0968e47d2 100644 --- a/src/CxbxKrnl/EmuFS.cpp +++ b/src/CxbxKrnl/EmuFS.cpp @@ -54,17 +54,10 @@ namespace xboxkrnl NT_TIB *GetNtTib() { - NT_TIB *NtTib; - - __asm - { - mov eax, fs : [TIB_LinearSelfAddress] - mov NtTib, eax - } - - return NtTib; + return (NT_TIB *)__readfsdword(TIB_LinearSelfAddress); } + void EmuKeSetPcr(xboxkrnl::KPCR *Pcr) { // Store the Xbox KPCR pointer in FS (See KeGetPcr()) @@ -478,10 +471,10 @@ void EmuGenerateFS(Xbe::TLS *pTLS, void *pTLSData) // TODO : Once we do our own thread-switching (as mentioned above), // we can also start using Prcb->DpcListHead instead of DpcQueue : InitializeListHead(&(Prcb->DpcListHead)); - Prcb->DpcRoutineActive = 0; + Prcb->DpcRoutineActive = FALSE; - // TODO : Should Irql be set? And if so, to what - PASSIVE_LEVEL, or perhaps better : APC_LEVEL? - // NewPcr->Irql = PASSIVE_LEVEL; // See KeLowerIrql; + // TODO : Should Irql be set? And if so, to what - APC_LEVEL? + // NewPcr->Irql = APC_LEVEL; // See KeLowerIrql; } // Initialize a fake PrcbData.CurrentThread diff --git a/src/CxbxKrnl/EmuKrnl.cpp b/src/CxbxKrnl/EmuKrnl.cpp index f386ee63e..9bae9f5cb 100644 --- a/src/CxbxKrnl/EmuKrnl.cpp +++ b/src/CxbxKrnl/EmuKrnl.cpp @@ -312,12 +312,14 @@ XBSYSAPI EXPORTNUM(160) xboxkrnl::KIRQL FASTCALL xboxkrnl::KfRaiseIrql PKPCR Pcr = KeGetPcr(); KIRQL OldIrql = (KIRQL)Pcr->Irql; - if (NewIrql < OldIrql) { - KeBugCheck(0x00000009); // IRQL_NOT_GREATER_OR_EQUAL - } - + // Set new before check Pcr->Irql = NewIrql; + if (NewIrql < OldIrql) { + Pcr->Irql = 0; // Probably to avoid recursion? + KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL, (PVOID)OldIrql, (PVOID)NewIrql, 0, 0); + } + RETURN(OldIrql); } @@ -336,7 +338,10 @@ XBSYSAPI EXPORTNUM(161) xboxkrnl::VOID FASTCALL xboxkrnl::KfLowerIrql KPCR* Pcr = KeGetPcr(); if (NewIrql > Pcr->Irql) { - KeBugCheck(0x0000000A); // IRQL_NOT_LESS_OR_EQUAL + KIRQL OldIrql = Pcr->Irql; + Pcr->Irql = HIGH_LEVEL; // Probably to avoid recursion? + KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL, (PVOID)OldIrql, (PVOID)NewIrql, 0, 0); + return; } Pcr->Irql = NewIrql; diff --git a/src/CxbxKrnl/EmuKrnlHal.cpp b/src/CxbxKrnl/EmuKrnlHal.cpp index 7e7f430ed..a7c99282a 100644 --- a/src/CxbxKrnl/EmuKrnlHal.cpp +++ b/src/CxbxKrnl/EmuKrnlHal.cpp @@ -67,7 +67,7 @@ namespace NtDll #include "EmuNtDll.h" }; -static DWORD EmuSoftwareInterrupRequestRegister = 0; +volatile DWORD HalInterruptRequestRegister = APC_LEVEL | DISPATCH_LEVEL; HalSystemInterrupt HalSystemInterrupts[MAX_BUS_INTERRUPT_LEVEL + 1]; // variables used by the SMC to know a reset / shutdown is pending @@ -122,7 +122,8 @@ XBSYSAPI EXPORTNUM(38) xboxkrnl::VOID FASTCALL xboxkrnl::HalClearSoftwareInterru LOG_FUNC_ONE_ARG(Request); // Mask out this interrupt request - EmuSoftwareInterrupRequestRegister &= ~(1 << Request); + DWORD InterruptMask = 1 << Request; + HalInterruptRequestRegister &= ~InterruptMask; } // ****************************************************************** @@ -433,8 +434,10 @@ XBSYSAPI EXPORTNUM(48) xboxkrnl::VOID FASTCALL xboxkrnl::HalRequestSoftwareInter { LOG_FUNC_ONE_ARG(Request); - // Set this software interrupt request : - EmuSoftwareInterrupRequestRegister |= (1 << Request); + DWORD InterruptMask = 1 << Request; + + // Set this interrupt request bit: + HalInterruptRequestRegister |= InterruptMask; LOG_INCOMPLETE(); } diff --git a/src/CxbxKrnl/EmuKrnlKe.cpp b/src/CxbxKrnl/EmuKrnlKe.cpp index 51fb5d0d2..efe18751e 100644 --- a/src/CxbxKrnl/EmuKrnlKe.cpp +++ b/src/CxbxKrnl/EmuKrnlKe.cpp @@ -1230,26 +1230,14 @@ XBSYSAPI EXPORTNUM(128) xboxkrnl::VOID NTAPI xboxkrnl::KeQuerySystemTime // ****************************************************************** XBSYSAPI EXPORTNUM(129) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToDpcLevel() { - LOG_FUNC(); + LOG_FORWARD(KfRaiseIrql); - // Inlined KeGetCurrentIrql() : - KPCR* Pcr = KeGetPcr(); - KIRQL OldIrql = (KIRQL)Pcr->Irql; - - if(OldIrql > DISPATCH_LEVEL) - CxbxKrnlCleanup("Bugcheck: Caller of KeRaiseIrqlToDpcLevel is higher than DISPATCH_LEVEL!"); - - Pcr->Irql = DISPATCH_LEVEL; - -#ifdef _DEBUG_TRACE - DbgPrintf("KRNL: Raised IRQL to DISPATCH_LEVEL (2).\n"); - DbgPrintf("Old IRQL is %d.\n", OldIrql); -#endif + KIRQL OldIrql = KfRaiseIrql(DISPATCH_LEVEL); // We reached the DISPATCH_LEVEL, so the queue can be processed now ExecuteDpcQueue(); - RETURN(OldIrql); + return OldIrql; } // ****************************************************************** @@ -1257,17 +1245,9 @@ XBSYSAPI EXPORTNUM(129) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToDpcLevel() // ****************************************************************** XBSYSAPI EXPORTNUM(130) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToSynchLevel() { - LOG_FUNC(); + LOG_FORWARD(KfRaiseIrql); - // Inlined KeGetCurrentIrql() : - KPCR* Pcr = KeGetPcr(); - KIRQL OldIrql = (KIRQL)Pcr->Irql; - - Pcr->Irql = SYNC_LEVEL; - - LOG_INCOMPLETE(); // TODO : Should we call ExecuteDpcQueue, perhaps with SYNC_LEVEL argument?? - - RETURN(OldIrql); + return KfRaiseIrql(SYNC_LEVEL); } XBSYSAPI EXPORTNUM(131) xboxkrnl::LONG NTAPI xboxkrnl::KeReleaseMutant