From 1cbde6f7e817070883693514828c3dcd662246a7 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Tue, 7 Nov 2017 00:10:06 -0600 Subject: [PATCH] EmuKrnl Files Update --- src/CxbxKrnl/EmuKrnl.cpp | 53 +++++++--- src/CxbxKrnl/EmuKrnl.h | 2 +- src/CxbxKrnl/EmuKrnlHal.cpp | 12 ++- src/CxbxKrnl/EmuKrnlIo.cpp | 10 +- src/CxbxKrnl/EmuKrnlKe.cpp | 201 ++++++++++++++++++++---------------- src/CxbxKrnl/EmuKrnlMm.cpp | 16 ++- src/CxbxKrnl/EmuKrnlNt.cpp | 28 ++--- src/CxbxKrnl/EmuKrnlPs.cpp | 56 +++++++--- 8 files changed, 231 insertions(+), 147 deletions(-) diff --git a/src/CxbxKrnl/EmuKrnl.cpp b/src/CxbxKrnl/EmuKrnl.cpp index 28eccd26c..3fe198c33 100644 --- a/src/CxbxKrnl/EmuKrnl.cpp +++ b/src/CxbxKrnl/EmuKrnl.cpp @@ -132,6 +132,23 @@ xboxkrnl::PLIST_ENTRY RemoveTailList(xboxkrnl::PLIST_ENTRY pListHead) // ****************************************************************** xboxkrnl::KPCR* KeGetPcr(); +// ****************************************************************** +// * KiLockDispatcherDatabase() +// ****************************************************************** +// * Not exported in kernel thunk table +// * NOTE: This is a macro on the Xbox, however we implement it +// * as a function because a macro doesn't compile this: *(&OldIrql) +// ****************************************************************** +void xboxkrnl::KiLockDispatcherDatabase +( + OUT KIRQL* OldIrql +) +{ + LOG_FUNC_ONE_ARG_OUT(OldIrql); + + *(OldIrql) = KeRaiseIrqlToDpcLevel(); +} + // ****************************************************************** // * 0x0033 - InterlockedCompareExchange() // ****************************************************************** @@ -282,27 +299,28 @@ XBSYSAPI EXPORTNUM(58) xboxkrnl::PSLIST_ENTRY FASTCALL xboxkrnl::KRNL(Interlocke // ****************************************************************** // * 0x00A0 - KfRaiseIrql() // ****************************************************************** -// Raises the hardware priority (irql) -// NewIrql = Irql to raise to +// Raises the hardware priority (irq level) +// NewIrql = Irq level to raise to // RETURN VALUE previous irq level -XBSYSAPI EXPORTNUM(160) xboxkrnl::UCHAR FASTCALL xboxkrnl::KfRaiseIrql +XBSYSAPI EXPORTNUM(160) xboxkrnl::KIRQL FASTCALL xboxkrnl::KfRaiseIrql ( - IN UCHAR NewIrql + IN KIRQL NewIrql ) { LOG_FUNC_ONE_ARG(NewIrql); - UCHAR OldIrql; + // Inlined KeGetCurrentIrql() : + PKPCR Pcr = KeGetPcr(); + KIRQL OldIrql = (KIRQL)Pcr->Irql; - KPCR* Pcr = KeGetPcr(); - - if (NewIrql < Pcr->Irql) { + if (NewIrql < OldIrql) { KeBugCheck(0x00000009); // IRQL_NOT_GREATER_OR_EQUAL } - OldIrql = Pcr->Irql; Pcr->Irql = NewIrql; - + + LOG_INCOMPLETE(); + RETURN(OldIrql); } @@ -313,7 +331,7 @@ XBSYSAPI EXPORTNUM(160) xboxkrnl::UCHAR FASTCALL xboxkrnl::KfRaiseIrql // ARGUMENTS NewIrql = Irql to lower to XBSYSAPI EXPORTNUM(161) xboxkrnl::VOID FASTCALL xboxkrnl::KfLowerIrql ( - IN UCHAR NewIrql + IN KIRQL NewIrql ) { LOG_FUNC_ONE_ARG(NewIrql); @@ -336,6 +354,8 @@ XBSYSAPI EXPORTNUM(161) xboxkrnl::VOID FASTCALL xboxkrnl::KfLowerIrql // Source:ReactOS XBSYSAPI EXPORTNUM(162) xboxkrnl::ULONG_PTR xboxkrnl::KiBugCheckData[5] = { NULL, NULL, NULL, NULL, NULL }; +extern xboxkrnl::KPRCB *KeGetCurrentPrcb(); + // ****************************************************************** // * 0x00A3 - KiUnlockDispatcherDatabase() // ****************************************************************** @@ -346,7 +366,12 @@ XBSYSAPI EXPORTNUM(163) xboxkrnl::VOID FASTCALL xboxkrnl::KiUnlockDispatcherData { LOG_FUNC_ONE_ARG(OldIrql); - LOG_UNIMPLEMENTED(); + if (!(KeGetCurrentPrcb()->DpcRoutineActive)) // Avoid KeIsExecutingDpc(), as that logs + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + + LOG_INCOMPLETE(); // TODO : Thread-switch? + + KfLowerIrql(OldIrql); } // ****************************************************************** @@ -358,8 +383,10 @@ XBSYSAPI EXPORTNUM(252) xboxkrnl::DWORD NTAPI xboxkrnl::PhyGetLinkState ) { LOG_FUNC_ONE_ARG(Mode); + LOG_UNIMPLEMENTED(); - return 0; + + return 0; // Was XNET_ETHERNET_LINK_ACTIVE | XNET_ETHERNET_LINK_100MBPS | XNET_ETHERNET_LINK_FULL_DUPLEX; } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnl.h b/src/CxbxKrnl/EmuKrnl.h index 53b4140a3..af0a4744a 100644 --- a/src/CxbxKrnl/EmuKrnl.h +++ b/src/CxbxKrnl/EmuKrnl.h @@ -91,7 +91,7 @@ public: } void Trigger(xboxkrnl::PKINTERRUPT Interrupt) { - // If interrupt was level sensitive, we clear the pending flag, oreventing the interrupt from being triggered + // If interrupt was level sensitive, we clear the pending flag, preventing the interrupt from being triggered // until it is deasserted then asserted again. Latched interrupts are triggered until the line is Deasserted! if (m_InterruptMode == xboxkrnl::KINTERRUPT_MODE::LevelSensitive) { m_Pending = false; diff --git a/src/CxbxKrnl/EmuKrnlHal.cpp b/src/CxbxKrnl/EmuKrnlHal.cpp index c8e52b1ad..77face661 100644 --- a/src/CxbxKrnl/EmuKrnlHal.cpp +++ b/src/CxbxKrnl/EmuKrnlHal.cpp @@ -65,6 +65,7 @@ namespace NtDll #include "EmuNtDll.h" }; +static DWORD EmuSoftwareInterrupRequestRegister = 0; HalSystemInterrupt HalSystemInterrupts[MAX_BUS_INTERRUPT_LEVEL + 1]; // ****************************************************************** @@ -109,7 +110,9 @@ XBSYSAPI EXPORTNUM(38) xboxkrnl::VOID FASTCALL xboxkrnl::HalClearSoftwareInterru ) { LOG_FUNC_ONE_ARG(Request); - LOG_UNIMPLEMENTED(); + + // Mask out this interrupt request + EmuSoftwareInterrupRequestRegister &= ~(1 << Request); } // ****************************************************************** @@ -224,7 +227,7 @@ XBSYSAPI EXPORTNUM(44) xboxkrnl::ULONG NTAPI xboxkrnl::HalGetInterruptVector *Irql = (KIRQL)VECTOR2IRQL(dwVector); #ifdef _DEBUG_TRACE - DbgPrintf("HalGetInterruptVector(): Interrupt vector requested for %d (%s)!\n", + DbgPrintf("KRNL: HalGetInterruptVector(): Interrupt vector requested for %d (%s)\n", BusInterruptLevel, IRQNames[BusInterruptLevel]); #endif } @@ -408,7 +411,10 @@ XBSYSAPI EXPORTNUM(48) xboxkrnl::VOID FASTCALL xboxkrnl::HalRequestSoftwareInter { LOG_FUNC_ONE_ARG(Request); - LOG_UNIMPLEMENTED(); + // Set this software interrupt request : + EmuSoftwareInterrupRequestRegister |= (1 << Request); + + LOG_INCOMPLETE(); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlIo.cpp b/src/CxbxKrnl/EmuKrnlIo.cpp index f6161afc6..4d2db2dfa 100644 --- a/src/CxbxKrnl/EmuKrnlIo.cpp +++ b/src/CxbxKrnl/EmuKrnlIo.cpp @@ -279,7 +279,7 @@ XBSYSAPI EXPORTNUM(66) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateFile // Force ShareAccess to all ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - if (!FAILED(ret)) + if (SUCCEEDED(ret)) // redirect to NtCreateFile ret = NtDll::NtCreateFile( FileHandle, @@ -296,11 +296,11 @@ XBSYSAPI EXPORTNUM(66) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateFile if (FAILED(ret)) { - EmuWarning("EmuKrnl: IoCreateFile Failed! (%s)\n", NtStatusToString(ret)); + EmuWarning("KRNL: IoCreateFile Failed! (%s)\n", NtStatusToString(ret)); } else { - DbgPrintf("EmuKrnl: IoCreateFile = 0x%.08X\n", *FileHandle); + DbgPrintf("KRNL: IoCreateFile = 0x%.8X\n", *FileHandle); } RETURN(ret); @@ -330,10 +330,10 @@ XBSYSAPI EXPORTNUM(67) xboxkrnl::NTSTATUS NTAPI xboxkrnl::IoCreateSymbolicLink // ****************************************************************** XBSYSAPI EXPORTNUM(68) xboxkrnl::VOID NTAPI xboxkrnl::IoDeleteDevice ( - IN PDEVICE_OBJECT irql + IN PDEVICE_OBJECT Irql ) { - LOG_FUNC_ONE_ARG(irql); + LOG_FUNC_ONE_ARG(Irql); LOG_UNIMPLEMENTED(); } diff --git a/src/CxbxKrnl/EmuKrnlKe.cpp b/src/CxbxKrnl/EmuKrnlKe.cpp index c7f8533a5..af975c71b 100644 --- a/src/CxbxKrnl/EmuKrnlKe.cpp +++ b/src/CxbxKrnl/EmuKrnlKe.cpp @@ -164,7 +164,7 @@ xboxkrnl::KPRCB *KeGetCurrentPrcb() // Forward KeRaiseIrql() to KfRaiseIrql() #define KeRaiseIrql(NewIrql, OldIrql) \ - *OldIrql = KfRaiseIrql(NewIrql) + *(OldIrql) = KfRaiseIrql(NewIrql) ULONGLONG BootTickCount = 0; @@ -176,7 +176,7 @@ DWORD CxbxXboxGetTickCount() return (DWORD)(GetTickCount64() - BootTickCount); } -DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) +DWORD ExecuteDpcQueue() { xboxkrnl::PKDPC pkdpc; DWORD dwWait; @@ -184,16 +184,8 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) LONG lWait; xboxkrnl::PKTIMER pktimer; - // since callbacks come from here - // Note : This function runs on the Xbox core to somewhat approximate - // CPU locking (the prevention of interrupts to avoid thread-switches) - // so that callbacks don't get preempted. This needs more work. - InitXboxThread(g_CPUXbox); - - while (true) - { - // While we're working with the DpcQueue, we need to be thread-safe : - EnterCriticalSection(&(g_DpcData.Lock)); + // While we're working with the DpcQueue, we need to be thread-safe : + EnterCriticalSection(&(g_DpcData.Lock)); // if (g_DpcData._fShutdown) // break; // while @@ -203,18 +195,61 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) // g_DpcData._dwDpcThreadId = g_DpcData._dwThreadId; // Assert(g_DpcData._dwDpcThreadId != 0); - // Are there entries in the DpqQueue? - while (!IsListEmpty(&(g_DpcData.DpcQueue))) + // Are there entries in the DpqQueue? + while (!IsListEmpty(&(g_DpcData.DpcQueue))) + { + // Extract the head entry and retrieve the containing KDPC pointer for it: + pkdpc = CONTAINING_RECORD(RemoveHeadList(&(g_DpcData.DpcQueue)), xboxkrnl::KDPC, DpcListEntry); + // Mark it as no longer linked into the DpcQueue + pkdpc->Inserted = FALSE; + // Set DpcRoutineActive to support KeIsExecutingDpc: + KeGetCurrentPrcb()->DpcRoutineActive = TRUE; // Experimental + DbgPrintf("KRNL: Global DpcQueue, calling DPC at 0x%.8X\n", pkdpc->DeferredRoutine); + __try { + // Call the Deferred Procedure : + pkdpc->DeferredRoutine( + pkdpc, + pkdpc->DeferredContext, + pkdpc->SystemArgument1, + pkdpc->SystemArgument2); + } __except (EmuException(GetExceptionInformation())) { - // Extract the head entry and retrieve the containing KDPC pointer for it: - pkdpc = CONTAINING_RECORD(RemoveHeadList(&(g_DpcData.DpcQueue)), xboxkrnl::KDPC, DpcListEntry); - // Mark it as no longer linked into the DpcQueue - pkdpc->Inserted = FALSE; - // Set DpcRoutineActive to support KeIsExecutingDpc: - KeGetCurrentPrcb()->DpcRoutineActive = TRUE; // Experimental + EmuWarning("Problem with ExceptionFilter!"); + } + KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental + } + + dwWait = INFINITE; + if (!IsListEmpty(&(g_DpcData.TimerQueue))) + { + while (true) + { + dwNow = CxbxXboxGetTickCount(); + dwWait = INFINITE; + pktimer = (xboxkrnl::PKTIMER)g_DpcData.TimerQueue.Flink; + pkdpc = nullptr; + while (pktimer != (xboxkrnl::PKTIMER)&(g_DpcData.TimerQueue)) + { + lWait = (LONG)pktimer->DueTime.u.LowPart - dwNow; + if (lWait <= 0) + { + pktimer->DueTime.u.LowPart = pktimer->Period + dwNow; + pkdpc = pktimer->Dpc; + break; // while + } + + if (dwWait > (DWORD)lWait) + dwWait = (DWORD)lWait; + + pktimer = (xboxkrnl::PKTIMER)pktimer->TimerListEntry.Flink; + } + + if (pkdpc == nullptr) + break; // while + + DbgPrintf("KRNL: Global TimerQueue, calling DPC at 0x%.8X\n", pkdpc->DeferredRoutine); __try { - // Call the Deferred Procedure : pkdpc->DeferredRoutine( pkdpc, pkdpc->DeferredContext, @@ -224,55 +259,30 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) { EmuWarning("Problem with ExceptionFilter!"); } - - KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental - } - - dwWait = INFINITE; - if (!IsListEmpty(&(g_DpcData.TimerQueue))) - { - while (true) - { - dwNow = CxbxXboxGetTickCount(); - dwWait = INFINITE; - pktimer = (xboxkrnl::PKTIMER)g_DpcData.TimerQueue.Flink; - pkdpc = nullptr; - while (pktimer != (xboxkrnl::PKTIMER)&(g_DpcData.TimerQueue)) - { - lWait = (LONG)pktimer->DueTime.u.LowPart - dwNow; - if (lWait <= 0) - { - pktimer->DueTime.u.LowPart = pktimer->Period + dwNow; - pkdpc = pktimer->Dpc; - break; // while - } - - if (dwWait > (DWORD)lWait) - dwWait = (DWORD)lWait; - - pktimer = (xboxkrnl::PKTIMER)pktimer->TimerListEntry.Flink; - } - - if (pkdpc == nullptr) - break; // while - - __try { - pkdpc->DeferredRoutine( - pkdpc, - pkdpc->DeferredContext, - pkdpc->SystemArgument1, - pkdpc->SystemArgument2); - } __except (EmuException(GetExceptionInformation())) - { - EmuWarning("Problem with ExceptionFilter!"); - } - } } + } // Assert(g_DpcData._dwThreadId == GetCurrentThreadId()); // Assert(g_DpcData._dwDpcThreadId == g_DpcData._dwThreadId); // g_DpcData._dwDpcThreadId = 0; - LeaveCriticalSection(&(g_DpcData.Lock)); + LeaveCriticalSection(&(g_DpcData.Lock)); + + return dwWait; +} + +DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) +{ + DbgPrintf("KRNL: DPC thread is running\n"); + + // Make sure DPC callbacks run on the same core as the one that runs Xbox1 code : + // Note : This function runs on the Xbox core to somewhat approximate + // CPU locking (the prevention of interrupts to avoid thread-switches) + // so that callbacks don't get preempted. This needs more work. + InitXboxThread(g_CPUXbox); + + while (true) + { + DWORD dwWait = ExecuteDpcQueue(); // TODO : Wait for shutdown too here WaitForSingleObject(g_DpcData.DpcEvent, dwWait); @@ -280,19 +290,24 @@ DWORD __stdcall EmuThreadDpcHandler(LPVOID lpVoid) SwitchToThread(); } // while + DbgPrintf("KRNL: DPC thread is finished\n"); + return S_OK; } void InitDpcAndTimerThread() { - DWORD dwThreadId; + DWORD dwThreadId = 0; InitializeCriticalSection(&(g_DpcData.Lock)); InitializeListHead(&(g_DpcData.DpcQueue)); InitializeListHead(&(g_DpcData.TimerQueue)); + + DbgPrintf("INIT: Creating DPC event\n"); g_DpcData.DpcEvent = CreateEvent(/*lpEventAttributes=*/nullptr, /*bManualReset=*/FALSE, /*bInitialState=*/FALSE, /*lpName=*/nullptr); + g_DpcData.DpcThread = CreateThread(/*lpThreadAttributes=*/nullptr, /*dwStackSize=*/0, (LPTHREAD_START_ROUTINE)&EmuThreadDpcHandler, /*lpParameter=*/nullptr, /*dwCreationFlags=*/0, &dwThreadId); - SetThreadAffinityMask(g_DpcData.DpcThread, g_CPUXbox); + DbgPrintf("INIT: Created DPC thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", g_DpcData.DpcThread, dwThreadId); SetThreadPriority(g_DpcData.DpcThread, THREAD_PRIORITY_HIGHEST); } @@ -426,11 +441,11 @@ XBSYSAPI EXPORTNUM(96) xboxkrnl::NTSTATUS NTAPI xboxkrnl::KeBugCheckEx char buffer[1024]; sprintf(buffer, "The running software triggered KeBugCheck with the following information\n" - "BugCheckCode: 0x%08X\n" - "BugCheckParameter1: 0x%08X\n" - "BugCheckParameter2: 0x%08X\n" - "BugCheckParameter3: 0x%08X\n" - "BugCheckParameter4: 0x%08X\n" + "BugCheckCode: 0x%.8X\n" + "BugCheckParameter1: 0x%p\n" + "BugCheckParameter2: 0x%p\n" + "BugCheckParameter3: 0x%p\n" + "BugCheckParameter4: 0x%p\n" "\nThis is the Xbox equivalent to a BSOD and would cause the console to automatically reboot\n" "\nContinue Execution (Not Recommended)?\n", BugCheckCode, BugCheckParameter1, BugCheckParameter2, BugCheckParameter3, BugCheckParameter4); @@ -480,6 +495,9 @@ XBSYSAPI EXPORTNUM(98) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeConnectInterrupt LOG_FUNC_ONE_ARG(InterruptObject); BOOLEAN ret = FALSE; + KIRQL OldIrql; + + KiLockDispatcherDatabase(&OldIrql); // here we have to connect the interrupt object to the vector if (!InterruptObject->Connected) @@ -495,6 +513,8 @@ XBSYSAPI EXPORTNUM(98) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeConnectInterrupt } // else do nothing + KiUnlockDispatcherDatabase(OldIrql); + RETURN(ret); } @@ -529,15 +549,19 @@ XBSYSAPI EXPORTNUM(100) xboxkrnl::VOID NTAPI xboxkrnl::KeDisconnectInterrupt { LOG_FUNC_ONE_ARG(InterruptObject); + KIRQL OldIrql; + + KiLockDispatcherDatabase(&OldIrql); + // Do the reverse of KeConnectInterrupt - // Untested (no known test cases) and not thread safe : - if (InterruptObject->Connected) - { + if (InterruptObject->Connected) { // Text case : d3dbvt.xbe // Mark InterruptObject as not connected anymore HalDisableSystemInterrupt(InterruptObject->BusInterruptLevel); EmuInterruptList[InterruptObject->BusInterruptLevel] = NULL; InterruptObject->Connected = FALSE; } + + KiUnlockDispatcherDatabase(OldIrql); } // ****************************************************************** @@ -560,9 +584,10 @@ XBSYSAPI EXPORTNUM(101) xboxkrnl::VOID NTAPI xboxkrnl::KeEnterCriticalRegion // ****************************************************************** XBSYSAPI EXPORTNUM(103) xboxkrnl::KIRQL NTAPI xboxkrnl::KeGetCurrentIrql(void) { - LOG_FUNC(); + LOG_FUNC(); // TODO : Remove nested logging on this somehow, so we can call this (instead of inlining) - KIRQL Irql = KeGetPcr()->Irql; + KPCR* Pcr = KeGetPcr(); + KIRQL Irql = (KIRQL)Pcr->Irql; RETURN(Irql); } @@ -722,6 +747,7 @@ XBSYSAPI EXPORTNUM(109) xboxkrnl::VOID NTAPI xboxkrnl::KeInitializeInterrupt // Interrupt->DispatchCode = []?; //TODO : Populate this interrupt dispatch // code block, patch it up so it works with the address of this Interrupt // struct and calls the right dispatch routine (depending on InterruptMode). + LOG_INCOMPLETE(); } // ****************************************************************** @@ -953,7 +979,7 @@ XBSYSAPI EXPORTNUM(119) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeInsertQueueDpc // Thread-safety is no longer required anymore LeaveCriticalSection(&(g_DpcData.Lock)); - // TODO : Instead, enable interrupts - use KeLowerIrql(&OldIrql) ? + // TODO : Instead, enable interrupts - use KeLowerIrql(OldIrql) ? RETURN(NeedsInsertion); } @@ -1135,23 +1161,24 @@ XBSYSAPI EXPORTNUM(129) xboxkrnl::UCHAR NTAPI xboxkrnl::KeRaiseIrqlToDpcLevel() { LOG_FUNC(); - if(KeGetCurrentIrql() > DISPATCH_LEVEL) + // Inlined KeGetCurrentIrql() : + KPCR* Pcr = KeGetPcr(); + KIRQL OldIrql = (KIRQL)Pcr->Irql; + + if(OldIrql > DISPATCH_LEVEL) CxbxKrnlCleanup("Bugcheck: Caller of KeRaiseIrqlToDpcLevel is higher than DISPATCH_LEVEL!"); - KIRQL kRet = NULL; - - KPCR* Pcr = KeGetPcr(); Pcr->Irql = DISPATCH_LEVEL; #ifdef _DEBUG_TRACE - DbgPrintf("Raised IRQL to DISPATCH_LEVEL (2).\n"); - DbgPrintf("Old IRQL is %d.\n", kRet); + DbgPrintf("KRNL: Raised IRQL to DISPATCH_LEVEL (2).\n"); + DbgPrintf("Old IRQL is %d.\n", OldIrql); #endif - // We reached the DISPATCH_LEVEL, so the queue can be processed now : - // TODO : ExecuteDpcQueue(); + // We reached the DISPATCH_LEVEL, so the queue can be processed now + ExecuteDpcQueue(); - RETURN(kRet); + RETURN(OldIrql); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlMm.cpp b/src/CxbxKrnl/EmuKrnlMm.cpp index df67e9d84..0448b6abf 100644 --- a/src/CxbxKrnl/EmuKrnlMm.cpp +++ b/src/CxbxKrnl/EmuKrnlMm.cpp @@ -50,8 +50,6 @@ namespace xboxkrnl #include "EmuKrnlLogging.h" #include "CxbxKrnl.h" // For CxbxKrnlCleanup #include "Emu.h" // For EmuWarning() -#include "EmuAlloc.h" // For CxbxFree(), g_MemoryManager.Allocate(), etc. -#include "ResourceTracker.h" // For g_AlignCache #include "MemoryManager.h" // prevent name collisions @@ -181,7 +179,7 @@ XBSYSAPI EXPORTNUM(168) xboxkrnl::PVOID NTAPI xboxkrnl::MmClaimGpuInstanceMemory *NumberOfPaddingBytes = MI_CONVERT_PFN_TO_PHYSICAL(MM_64M_PHYSICAL_PAGE) - MI_CONVERT_PFN_TO_PHYSICAL(MM_INSTANCE_PHYSICAL_PAGE + MM_INSTANCE_PAGE_COUNT); - DbgPrintf("MmClaimGpuInstanceMemory : *NumberOfPaddingBytes = 0x%08X\n", *NumberOfPaddingBytes); + DbgPrintf("KNRL: MmClaimGpuInstanceMemory : *NumberOfPaddingBytes = 0x%.8X\n", *NumberOfPaddingBytes); #ifdef _DEBUG_TRACE if (NumberOfBytes != MAXULONG_PTR) @@ -288,7 +286,7 @@ XBSYSAPI EXPORTNUM(171) xboxkrnl::VOID NTAPI xboxkrnl::MmFreeContiguousMemory LOG_FUNC_ONE_ARG(BaseAddress); if (BaseAddress == &DefaultLaunchDataPage) { - DbgPrintf("Ignored MmFreeContiguousMemory(&DefaultLaunchDataPage)\n"); + DbgPrintf("KNRL: Ignored MmFreeContiguousMemory(&DefaultLaunchDataPage)\n"); LOG_IGNORED(); return; } @@ -455,17 +453,17 @@ XBSYSAPI EXPORTNUM(178) xboxkrnl::VOID NTAPI xboxkrnl::MmPersistContiguousMemory FILE* fp = fopen(szFilePath_LaunchDataPage_bin, "wb"); // TODO : Support wide char paths using _wfopen if (fp) { - DbgPrintf("Persisting LaunchDataPage\n"); + DbgPrintf("KNRL: Persisting LaunchDataPage\n"); fseek(fp, 0, SEEK_SET); fwrite(LaunchDataPage, sizeof(LAUNCH_DATA_PAGE), 1, fp); fclose(fp); } else - DbgPrintf("Can't persist LaunchDataPage to %s!\n", szFilePath_LaunchDataPage_bin); + DbgPrintf("KNRL: Can't persist LaunchDataPage to %s!\n", szFilePath_LaunchDataPage_bin); } else { - DbgPrintf("Forgetting LaunchDataPage\n"); + DbgPrintf("KNRL: Forgetting LaunchDataPage\n"); remove(szFilePath_LaunchDataPage_bin); } } @@ -574,7 +572,7 @@ XBSYSAPI EXPORTNUM(181) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmQueryStatistics } else { - EmuWarning("EmuKrnl: MmQueryStatistics with unusual size -> 0x%.08X", MemoryStatistics->Length); + EmuWarning("KRNL: MmQueryStatistics with unusual size -> 0x%.8X", MemoryStatistics->Length); ret = STATUS_INVALID_PARAMETER; } @@ -602,7 +600,7 @@ XBSYSAPI EXPORTNUM(182) xboxkrnl::VOID NTAPI xboxkrnl::MmSetAddressProtect if (!VirtualProtect(BaseAddress, NumberOfBytes, NewProtect & (~PAGE_WRITECOMBINE), &dwOldProtect)) EmuWarning("VirtualProtect Failed!"); - DbgPrintf("EmuKrnl: VirtualProtect was 0x%.08X -> 0x%.08X\n", dwOldProtect, NewProtect & (~PAGE_WRITECOMBINE)); + DbgPrintf("KRNL: VirtualProtect was 0x%.8X -> 0x%.8X\n", dwOldProtect, NewProtect & (~PAGE_WRITECOMBINE)); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlNt.cpp b/src/CxbxKrnl/EmuKrnlNt.cpp index 635b2a77c..bdfc97b83 100644 --- a/src/CxbxKrnl/EmuKrnlNt.cpp +++ b/src/CxbxKrnl/EmuKrnlNt.cpp @@ -96,7 +96,7 @@ XBSYSAPI EXPORTNUM(184) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtAllocateVirtualMemo ULONG_PTR RequestedBaseAddress = (ULONG_PTR)*BaseAddress; ULONG RequestedAllocationSize = *AllocationSize; - DbgPrintf("NtAllocateVirtualMemory requested range : 0x%.08X - 0x%.08X\n", RequestedBaseAddress, RequestedBaseAddress + RequestedAllocationSize); + DbgPrintf("KNRL: NtAllocateVirtualMemory requested range : 0x%.8X - 0x%.8X\n", RequestedBaseAddress, RequestedBaseAddress + RequestedAllocationSize); // Don't allow base address to exceed highest virtual address if (RequestedBaseAddress > MM_HIGHEST_VAD_ADDRESS) @@ -154,7 +154,7 @@ XBSYSAPI EXPORTNUM(184) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtAllocateVirtualMemo ULONG_PTR ResultingBaseAddress = (ULONG_PTR)*BaseAddress; ULONG ResultingAllocationSize = *AllocationSize; - DbgPrintf("NtAllocateVirtualMemory resulting range : 0x%.08X - 0x%.08X\n", ResultingBaseAddress, ResultingBaseAddress + ResultingAllocationSize); + DbgPrintf("KNRL: NtAllocateVirtualMemory resulting range : 0x%.8X - 0x%.8X\n", ResultingBaseAddress, ResultingBaseAddress + ResultingAllocationSize); } else if (ret == STATUS_INVALID_PARAMETER_5) // = 0xC00000F3 @@ -269,7 +269,7 @@ XBSYSAPI EXPORTNUM(188) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateDirectoryObje if (FAILED(ret)) EmuWarning("NtCreateDirectoryObject Failed!"); else - DbgPrintf("EmuKrnl: NtCreateDirectoryObject DirectoryHandle = 0x%.08X\n", *DirectoryHandle); + DbgPrintf("KRNL: NtCreateDirectoryObject DirectoryHandle = 0x%.8X\n", *DirectoryHandle); RETURN(ret); } @@ -346,10 +346,10 @@ XBSYSAPI EXPORTNUM(189) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateEvent if(FAILED(ret)) EmuWarning("NtCreateEvent Failed!"); else - DbgPrintf("EmuKrnl: NtCreateEvent EventHandle = 0x%.08X\n", *EventHandle); + DbgPrintf("KRNL: NtCreateEvent EventHandle = 0x%.8X\n", *EventHandle); } else - DbgPrintf("EmuKrnl: NtCreateEvent EventHandle = 0x%.08X\n", *EventHandle); + DbgPrintf("KRNL: NtCreateEvent EventHandle = 0x%.8X\n", *EventHandle); RETURN(ret); } @@ -471,10 +471,10 @@ XBSYSAPI EXPORTNUM(192) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateMutant if(FAILED(ret)) EmuWarning("NtCreateMutant Failed!"); else - DbgPrintf("EmuKrnl: NtCreateMutant MutantHandle = 0x%.08X\n", *MutantHandle); + DbgPrintf("KRNL: NtCreateMutant MutantHandle = 0x%.8X\n", *MutantHandle); } else - DbgPrintf("EmuKrnl: NtCreateMutant MutantHandle = 0x%.08X\n", *MutantHandle); + DbgPrintf("KRNL: NtCreateMutant MutantHandle = 0x%.8X\n", *MutantHandle); RETURN(ret); } @@ -546,10 +546,10 @@ XBSYSAPI EXPORTNUM(193) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateSemaphore if(FAILED(ret)) EmuWarning("NtCreateSemaphore failed!"); else - DbgPrintf("EmuKrnl: NtCreateSemaphore SemaphoreHandle = 0x%.08X\n", *SemaphoreHandle); + DbgPrintf("KRNL: NtCreateSemaphore SemaphoreHandle = 0x%.8X\n", *SemaphoreHandle); } else - DbgPrintf("EmuKrnl: NtCreateSemaphore SemaphoreHandle = 0x%.08X\n", *SemaphoreHandle); + DbgPrintf("KRNL: NtCreateSemaphore SemaphoreHandle = 0x%.8X\n", *SemaphoreHandle); RETURN(ret); } @@ -609,7 +609,7 @@ XBSYSAPI EXPORTNUM(194) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtCreateTimer if (FAILED(ret)) EmuWarning("NtCreateTimer failed!"); else - DbgPrintf("EmuKrnl: NtCreateTimer TimerHandle = 0x%.08X\n", *TimerHandle); + DbgPrintf("KRNL: NtCreateTimer TimerHandle = 0x%.8X\n", *TimerHandle); RETURN(ret); } @@ -925,7 +925,7 @@ XBSYSAPI EXPORTNUM(203) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtOpenSymbolicLinkObj if (ret != STATUS_SUCCESS) EmuWarning("NtOpenSymbolicLinkObject failed! (%s)", NtStatusToString(ret)); else - DbgPrintf("EmuKrnl : NtOpenSymbolicLinkObject LinkHandle^ = 0x%.08X", *LinkHandle); + DbgPrintf("KRNL: NtOpenSymbolicLinkObject LinkHandle^ = 0x%.8X", *LinkHandle); RETURN(ret); } @@ -1423,7 +1423,7 @@ XBSYSAPI EXPORTNUM(217) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtQueryVirtualMemory ret = STATUS_SUCCESS; - DbgPrintf("EmuKrnl: NtQueryVirtualMemory: Applied fix for Forza Motorsport!\n"); + DbgPrintf("KRNL: NtQueryVirtualMemory: Applied fix for Forza Motorsport!\n"); } } @@ -1575,6 +1575,8 @@ XBSYSAPI EXPORTNUM(219) xboxkrnl::NTSTATUS NTAPI xboxkrnl::NtReadFile if (FAILED(ret)) EmuWarning("NtReadFile Failed! (0x%.08X)", ret); + else + Sleep(10); // HACK : This prevents Turok from skipping it's intro-movie RETURN(ret); } @@ -1849,7 +1851,7 @@ XBSYSAPI EXPORTNUM(232) xboxkrnl::VOID NTAPI xboxkrnl::NtUserIoApcDispatcher (CompletionRoutine)(dwErrorCode, dwTransferred, lpOverlapped); - DbgPrintf("EmuKrnl: NtUserIoApcDispatcher Completed\n"); + DbgPrintf("KRNL: NtUserIoApcDispatcher Completed\n"); } // ****************************************************************** diff --git a/src/CxbxKrnl/EmuKrnlPs.cpp b/src/CxbxKrnl/EmuKrnlPs.cpp index 0d0cc3e51..4bc5d623a 100644 --- a/src/CxbxKrnl/EmuKrnlPs.cpp +++ b/src/CxbxKrnl/EmuKrnlPs.cpp @@ -151,7 +151,7 @@ static unsigned int WINAPI PCSTProxy if (pfnNotificationRoutine == NULL) continue; - DbgPrintf("EmuKrnl: Calling pfnNotificationRoutine[%d] (0x%.08X)\n", g_iThreadNotificationCount, pfnNotificationRoutine); + DbgPrintf("KRNL: Calling pfnNotificationRoutine[%d] (0x%.8X)\n", g_iThreadNotificationCount, pfnNotificationRoutine); pfnNotificationRoutine(TRUE); } @@ -293,26 +293,50 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE // else // KernelStackSize = round up; - static bool bFirstTime = false; + static bool bFirstTime = false; - // create thread, using our special proxy technique - { - DWORD dwThreadId; + // create thread, using our special proxy technique + { + DWORD dwThreadId = 0, dwThreadWait; + bool bWait = true; - // PCSTProxy is responsible for cleaning up this pointer - ::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam(); + // PCSTProxy is responsible for cleaning up this pointer + ::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam(); - iPCSTProxyParam->StartRoutine = StartRoutine; - iPCSTProxyParam->StartContext = StartContext; - iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown? - iPCSTProxyParam->StartSuspended = CreateSuspended; - iPCSTProxyParam->hStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + iPCSTProxyParam->StartRoutine = StartRoutine; + iPCSTProxyParam->StartContext = StartContext; + iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown? + iPCSTProxyParam->StartSuspended = CreateSuspended; + iPCSTProxyParam->hStartedEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("PCSTProxyEvent")); - *ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId); + *ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId); - WaitForSingleObject(iPCSTProxyParam->hStartedEvent, 1000); + DbgPrintf("KRNL: Waiting for Xbox proxy thread to start...\n"); - DbgPrintf("EmuKrnl: ThreadHandle : 0x%X, ThreadId : 0x%.08X\n", *ThreadHandle, dwThreadId); + while (bWait) { + dwThreadWait = WaitForSingleObject(*ThreadHandle, 300); + switch (dwThreadWait) { + // Thread is running + case WAIT_TIMEOUT: + // Thread is complete + case WAIT_OBJECT_0: { + // if either of two above is true, don't need to wait. + bWait = false; + break; + } + // A problem has occurred, what should we do? + case WAIT_FAILED: { + break; + } + // Unknown wait + default: + bWait = false; + break; + } + } + + // Log ThreadID identical to how GetCurrentThreadID() is rendered : + DbgPrintf("KRNL: Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", *ThreadHandle, dwThreadId); // we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread { @@ -413,7 +437,7 @@ XBSYSAPI EXPORTNUM(258) xboxkrnl::VOID NTAPI xboxkrnl::PsTerminateSystemThread if (pfnNotificationRoutine == NULL) continue; - DbgPrintf("EmuKrnl: Calling pfnNotificationRoutine[%d] (0x%.08X)\n", g_iThreadNotificationCount, pfnNotificationRoutine); + DbgPrintf("KRNL: Calling pfnNotificationRoutine[%d] (0x%.8X)\n", g_iThreadNotificationCount, pfnNotificationRoutine); pfnNotificationRoutine(FALSE); }