Kernel : Slight refactorings regarding irq levels and such (shouldn't break anything)

This commit is contained in:
PatrickvL 2018-02-12 18:55:34 +01:00
parent 96eeeb28d8
commit 83e1aa7825
7 changed files with 48 additions and 59 deletions

View File

@ -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
// ******************************************************************

View File

@ -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();
}

View File

@ -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 {

View File

@ -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

View File

@ -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;

View File

@ -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();
}

View File

@ -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