Updated KeInterruptTime, KeSystemTime, KeTickCount and timer handling
This commit is contained in:
parent
62dfa7b4e2
commit
1ae67fb215
|
@ -249,7 +249,7 @@ XBSYSAPI EXPORTNUM(119) BOOLEAN NTAPI KeInsertQueueDpc
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x0078 - KeInterruptTime
|
// * 0x0078 - KeInterruptTime
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
XBSYSAPI EXPORTNUM(120) PKSYSTEM_TIME KeInterruptTime;
|
XBSYSAPI EXPORTNUM(120) KSYSTEM_TIME KeInterruptTime;
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x0079 - KeIsExecutingDpc()
|
// * 0x0079 - KeIsExecutingDpc()
|
||||||
|
@ -490,7 +490,7 @@ XBSYSAPI EXPORTNUM(153) BOOLEAN NTAPI KeSynchronizeExecution
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x009A - KeSystemTime
|
// * 0x009A - KeSystemTime
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
XBSYSAPI EXPORTNUM(154) PKSYSTEM_TIME KeSystemTime;
|
XBSYSAPI EXPORTNUM(154) KSYSTEM_TIME KeSystemTime;
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x009B - KeTestAlertThread()
|
// * 0x009B - KeTestAlertThread()
|
||||||
|
|
|
@ -154,7 +154,7 @@ void RestoreInterruptMode(bool value)
|
||||||
g_bInterruptsEnabled = value;
|
g_bInterruptsEnabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern DWORD ExecuteDpcQueue();
|
extern void ExecuteDpcQueue();
|
||||||
|
|
||||||
void KiUnexpectedInterrupt()
|
void KiUnexpectedInterrupt()
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,10 +71,9 @@ typedef struct _DpcData {
|
||||||
CRITICAL_SECTION Lock;
|
CRITICAL_SECTION Lock;
|
||||||
HANDLE DpcEvent;
|
HANDLE DpcEvent;
|
||||||
xboxkrnl::LIST_ENTRY DpcQueue; // TODO : Use KeGetCurrentPrcb()->DpcListHead instead
|
xboxkrnl::LIST_ENTRY DpcQueue; // TODO : Use KeGetCurrentPrcb()->DpcListHead instead
|
||||||
xboxkrnl::LIST_ENTRY TimerQueue;
|
|
||||||
} DpcData;
|
} DpcData;
|
||||||
|
|
||||||
DpcData g_DpcData = { 0 }; // Note : g_DpcData is initialized in InitDpcAndTimerThread()
|
DpcData g_DpcData = { 0 }; // Note : g_DpcData is initialized in InitDpcThread()
|
||||||
|
|
||||||
xboxkrnl::ULONGLONG LARGE_INTEGER2ULONGLONG(xboxkrnl::LARGE_INTEGER value)
|
xboxkrnl::ULONGLONG LARGE_INTEGER2ULONGLONG(xboxkrnl::LARGE_INTEGER value)
|
||||||
{
|
{
|
||||||
|
@ -220,23 +219,9 @@ xboxkrnl::KPRCB *KeGetCurrentPrcb()
|
||||||
#define KeRaiseIrql(NewIrql, OldIrql) \
|
#define KeRaiseIrql(NewIrql, OldIrql) \
|
||||||
*(OldIrql) = KfRaiseIrql(NewIrql)
|
*(OldIrql) = KfRaiseIrql(NewIrql)
|
||||||
|
|
||||||
ULONGLONG BootTickCount = 0;
|
void ExecuteDpcQueue()
|
||||||
|
|
||||||
// The Xbox GetTickCount is measured in milliseconds, just like the native GetTickCount.
|
|
||||||
// The only difference we'll take into account here, is that the Xbox will probably reboot
|
|
||||||
// much more often than Windows, so we correct this with a 'BootTickCount' value :
|
|
||||||
DWORD CxbxXboxGetTickCount()
|
|
||||||
{
|
|
||||||
return (DWORD)(GetTickCount64() - BootTickCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD ExecuteDpcQueue()
|
|
||||||
{
|
{
|
||||||
xboxkrnl::PKDPC pkdpc;
|
xboxkrnl::PKDPC pkdpc;
|
||||||
DWORD dwWait;
|
|
||||||
DWORD dwNow;
|
|
||||||
LONG lWait;
|
|
||||||
xboxkrnl::PKTIMER pktimer;
|
|
||||||
|
|
||||||
// While we're working with the DpcQueue, we need to be thread-safe :
|
// While we're working with the DpcQueue, we need to be thread-safe :
|
||||||
EnterCriticalSection(&(g_DpcData.Lock));
|
EnterCriticalSection(&(g_DpcData.Lock));
|
||||||
|
@ -274,64 +259,18 @@ DWORD ExecuteDpcQueue()
|
||||||
KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental
|
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
|
|
||||||
|
|
||||||
DBG_PRINTF("Global TimerQueue, calling DPC at 0x%.8X\n", pkdpc->DeferredRoutine);
|
|
||||||
|
|
||||||
__try {
|
|
||||||
pkdpc->DeferredRoutine(
|
|
||||||
pkdpc,
|
|
||||||
pkdpc->DeferredContext,
|
|
||||||
pkdpc->SystemArgument1,
|
|
||||||
pkdpc->SystemArgument2);
|
|
||||||
} __except (EmuException(GetExceptionInformation()))
|
|
||||||
{
|
|
||||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assert(g_DpcData._dwThreadId == GetCurrentThreadId());
|
// Assert(g_DpcData._dwThreadId == GetCurrentThreadId());
|
||||||
// Assert(g_DpcData._dwDpcThreadId == g_DpcData._dwThreadId);
|
// Assert(g_DpcData._dwDpcThreadId == g_DpcData._dwThreadId);
|
||||||
// g_DpcData._dwDpcThreadId = 0;
|
// g_DpcData._dwDpcThreadId = 0;
|
||||||
LeaveCriticalSection(&(g_DpcData.Lock));
|
LeaveCriticalSection(&(g_DpcData.Lock));
|
||||||
|
|
||||||
return dwWait;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitDpcAndTimerThread()
|
void InitDpcThread()
|
||||||
{
|
{
|
||||||
DWORD dwThreadId = 0;
|
DWORD dwThreadId = 0;
|
||||||
|
|
||||||
InitializeCriticalSection(&(g_DpcData.Lock));
|
InitializeCriticalSection(&(g_DpcData.Lock));
|
||||||
InitializeListHead(&(g_DpcData.DpcQueue));
|
InitializeListHead(&(g_DpcData.DpcQueue));
|
||||||
InitializeListHead(&(g_DpcData.TimerQueue));
|
|
||||||
|
|
||||||
DBG_PRINTF_EX(CXBXR_MODULE::INIT, "Creating DPC event\n");
|
DBG_PRINTF_EX(CXBXR_MODULE::INIT, "Creating DPC event\n");
|
||||||
g_DpcData.DpcEvent = CreateEvent(/*lpEventAttributes=*/nullptr, /*bManualReset=*/FALSE, /*bInitialState=*/FALSE, /*lpName=*/nullptr);
|
g_DpcData.DpcEvent = CreateEvent(/*lpEventAttributes=*/nullptr, /*bManualReset=*/FALSE, /*bInitialState=*/FALSE, /*lpName=*/nullptr);
|
||||||
|
@ -342,8 +281,6 @@ void InitDpcAndTimerThread()
|
||||||
ULONGLONG NativeToXbox_FactorForRdtsc;
|
ULONGLONG NativeToXbox_FactorForRdtsc;
|
||||||
ULONGLONG NativeToXbox_FactorForAcpi;
|
ULONGLONG NativeToXbox_FactorForAcpi;
|
||||||
|
|
||||||
void ConnectKeInterruptTimeToThunkTable(); // forward
|
|
||||||
|
|
||||||
ULONGLONG CxbxGetPerformanceCounter(bool acpi) {
|
ULONGLONG CxbxGetPerformanceCounter(bool acpi) {
|
||||||
LARGE_INTEGER tsc;
|
LARGE_INTEGER tsc;
|
||||||
ULARGE_INTEGER scaledTsc;
|
ULARGE_INTEGER scaledTsc;
|
||||||
|
@ -377,11 +314,9 @@ void CxbxInitPerformanceCounters()
|
||||||
t /= XBOX_ACPI_FREQUENCY;
|
t /= XBOX_ACPI_FREQUENCY;
|
||||||
NativeToXbox_FactorForAcpi = t;
|
NativeToXbox_FactorForAcpi = t;
|
||||||
|
|
||||||
ConnectKeInterruptTimeToThunkTable();
|
// Let's initialize the Dpc handling thread too,
|
||||||
|
|
||||||
// Let's initialize the Dpc and timer handling thread too,
|
|
||||||
// here for now (should be called by our caller)
|
// here for now (should be called by our caller)
|
||||||
InitDpcAndTimerThread();
|
InitDpcThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -1107,14 +1042,7 @@ XBSYSAPI EXPORTNUM(121) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeIsExecutingDpc
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x0078 - KeInterruptTime
|
// * 0x0078 - KeInterruptTime
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// Dxbx note : This was once a value, but instead we now point to
|
XBSYSAPI EXPORTNUM(120) xboxkrnl::KSYSTEM_TIME xboxkrnl::KeInterruptTime = { 0, 0, 0 };
|
||||||
// the native Windows versions (see ConnectWindowsTimersToThunkTable) :
|
|
||||||
XBSYSAPI EXPORTNUM(120) xboxkrnl::PKSYSTEM_TIME xboxkrnl::KeInterruptTime = nullptr; // Set by ConnectKeInterruptTimeToThunkTable
|
|
||||||
|
|
||||||
void ConnectKeInterruptTimeToThunkTable()
|
|
||||||
{
|
|
||||||
xboxkrnl::KeInterruptTime = (xboxkrnl::PKSYSTEM_TIME)CxbxKrnl_KernelThunkTable[120];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x007A - KeLeaveCriticalRegion()
|
// * 0x007A - KeLeaveCriticalRegion()
|
||||||
|
@ -1204,12 +1132,12 @@ XBSYSAPI EXPORTNUM(125) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryInterruptTime
|
||||||
{
|
{
|
||||||
// Don't use NtDll::QueryInterruptTime, it's too new (Windows 10).
|
// Don't use NtDll::QueryInterruptTime, it's too new (Windows 10).
|
||||||
// Instead, read KeInterruptTime from our kernel thunk table.
|
// Instead, read KeInterruptTime from our kernel thunk table.
|
||||||
InterruptTime.u.HighPart = KeInterruptTime->High1Time;
|
InterruptTime.u.HighPart = KeInterruptTime.High1Time;
|
||||||
InterruptTime.u.LowPart = KeInterruptTime->LowPart;
|
InterruptTime.u.LowPart = KeInterruptTime.LowPart;
|
||||||
|
|
||||||
// Read InterruptTime atomically with a spinloop to avoid errors
|
// Read InterruptTime atomically with a spinloop to avoid errors
|
||||||
// when High1Time and High2Time differ (during unprocessed overflow in LowPart).
|
// when High1Time and High2Time differ (during unprocessed overflow in LowPart).
|
||||||
if (InterruptTime.u.HighPart == KeInterruptTime->High2Time)
|
if (InterruptTime.u.HighPart == KeInterruptTime.High2Time)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,12 +1182,12 @@ XBSYSAPI EXPORTNUM(128) xboxkrnl::VOID NTAPI xboxkrnl::KeQuerySystemTime
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
SystemTime.u.HighPart = KeSystemTime->High1Time;
|
SystemTime.u.HighPart = KeSystemTime.High1Time;
|
||||||
SystemTime.u.LowPart = KeSystemTime->LowPart;
|
SystemTime.u.LowPart = KeSystemTime.LowPart;
|
||||||
|
|
||||||
// Read InterruptTime atomically with a spinloop to avoid errors
|
// Read InterruptTime atomically with a spinloop to avoid errors
|
||||||
// when High1Time and High2Time differ (during unprocessed overflow in LowPart).
|
// when High1Time and High2Time differ (during unprocessed overflow in LowPart).
|
||||||
if (SystemTime.u.HighPart == KeSystemTime->High2Time)
|
if (SystemTime.u.HighPart == KeSystemTime.High2Time)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1858,9 +1786,7 @@ XBSYSAPI EXPORTNUM(153) xboxkrnl::BOOLEAN NTAPI xboxkrnl::KeSynchronizeExecution
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x009A - KeSystemTime
|
// * 0x009A - KeSystemTime
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// Dxbx note : This was once a value, but instead we now point to
|
// XBSYSAPI EXPORTNUM(154) xboxkrnl::KSYSTEM_TIME xboxkrnl::KeSystemTime; // Used for KernelThunk[154]
|
||||||
// the native Windows versions (see ConnectWindowsTimersToThunkTable) :
|
|
||||||
// XBSYSAPI EXPORTNUM(154) xboxkrnl::PKSYSTEM_TIME xboxkrnl::KeSystemTime; // Used for KernelThunk[154]
|
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * 0x009B - KeTestAlertThread()
|
// * 0x009B - KeTestAlertThread()
|
||||||
|
|
|
@ -72,26 +72,26 @@ VOID xboxkrnl::KiClockIsr(unsigned int ScalingFactor)
|
||||||
OldIrql = KfRaiseIrql(CLOCK_LEVEL);
|
OldIrql = KfRaiseIrql(CLOCK_LEVEL);
|
||||||
|
|
||||||
// Update the interrupt time
|
// Update the interrupt time
|
||||||
InterruptTime.u.LowPart = KeInterruptTime->LowPart;
|
InterruptTime.u.LowPart = KeInterruptTime.LowPart;
|
||||||
InterruptTime.u.HighPart = KeInterruptTime->High1Time;
|
InterruptTime.u.HighPart = KeInterruptTime.High1Time;
|
||||||
InterruptTime.QuadPart += (CLOCK_TIME_INCREMENT * ScalingFactor);
|
InterruptTime.QuadPart += (CLOCK_TIME_INCREMENT * ScalingFactor);
|
||||||
KeInterruptTime->High2Time = InterruptTime.u.HighPart;
|
KeInterruptTime.High2Time = InterruptTime.u.HighPart;
|
||||||
KeInterruptTime->LowPart = InterruptTime.u.LowPart;
|
KeInterruptTime.LowPart = InterruptTime.u.LowPart;
|
||||||
KeInterruptTime->High1Time = InterruptTime.u.HighPart;
|
KeInterruptTime.High1Time = InterruptTime.u.HighPart;
|
||||||
|
|
||||||
// Update the system time
|
// Update the system time
|
||||||
// NOTE: I'm not sure if we should round down the host system time to the nearest multiple
|
// NOTE: I'm not sure if we should round down the host system time to the nearest multiple
|
||||||
// of the Xbox clock increment...
|
// of the Xbox clock increment...
|
||||||
GetSystemTimeAsFileTime((LPFILETIME)&HostSystemTime);
|
GetSystemTimeAsFileTime((LPFILETIME)&HostSystemTime);
|
||||||
HostSystemTime.QuadPart += HostSystemTimeDelta.QuadPart;
|
HostSystemTime.QuadPart += HostSystemTimeDelta.QuadPart;
|
||||||
KeSystemTime->High2Time = HostSystemTime.u.HighPart;
|
KeSystemTime.High2Time = HostSystemTime.u.HighPart;
|
||||||
KeSystemTime->LowPart = HostSystemTime.u.LowPart;
|
KeSystemTime.LowPart = HostSystemTime.u.LowPart;
|
||||||
KeSystemTime->High1Time = HostSystemTime.u.HighPart;
|
KeSystemTime.High1Time = HostSystemTime.u.HighPart;
|
||||||
|
|
||||||
// Update the tick counter
|
// Update the tick counter
|
||||||
KeTickCount += ScalingFactor;
|
KeTickCount += ScalingFactor;
|
||||||
|
|
||||||
// Check if a timer have expired
|
// Check if a timer has expired
|
||||||
Hand = KeTickCount & (TIMER_TABLE_SIZE - 1);
|
Hand = KeTickCount & (TIMER_TABLE_SIZE - 1);
|
||||||
if (KiTimerTableListHead[Hand].Entry.Flink != &KiTimerTableListHead[Hand].Entry &&
|
if (KiTimerTableListHead[Hand].Entry.Flink != &KiTimerTableListHead[Hand].Entry &&
|
||||||
InterruptTime.QuadPart >= KiTimerTableListHead[Hand].Time.QuadPart) {
|
InterruptTime.QuadPart >= KiTimerTableListHead[Hand].Time.QuadPart) {
|
||||||
|
|
|
@ -175,7 +175,7 @@ uint32 CxbxKrnl_KernelThunkTable[379] =
|
||||||
(uint32)FUNC(&xboxkrnl::KeInsertQueue), // 0x0075 (117)
|
(uint32)FUNC(&xboxkrnl::KeInsertQueue), // 0x0075 (117)
|
||||||
(uint32)FUNC(&xboxkrnl::KeInsertQueueApc), // 0x0076 (118)
|
(uint32)FUNC(&xboxkrnl::KeInsertQueueApc), // 0x0076 (118)
|
||||||
(uint32)FUNC(&xboxkrnl::KeInsertQueueDpc), // 0x0077 (119)
|
(uint32)FUNC(&xboxkrnl::KeInsertQueueDpc), // 0x0077 (119)
|
||||||
(uint32)VARIABLE(0x0078), // 0x0078 (120) KeInterruptTime (Set by ConnectWindowsTimersToThunkTable)
|
(uint32)VARIABLE(&xboxkrnl::KeInterruptTime), // 0x0078 (120) KeInterruptTime
|
||||||
(uint32)FUNC(&xboxkrnl::KeIsExecutingDpc), // 0x0079 (121)
|
(uint32)FUNC(&xboxkrnl::KeIsExecutingDpc), // 0x0079 (121)
|
||||||
(uint32)FUNC(&xboxkrnl::KeLeaveCriticalRegion), // 0x007A (122)
|
(uint32)FUNC(&xboxkrnl::KeLeaveCriticalRegion), // 0x007A (122)
|
||||||
(uint32)FUNC(&xboxkrnl::KePulseEvent), // 0x007B (123)
|
(uint32)FUNC(&xboxkrnl::KePulseEvent), // 0x007B (123)
|
||||||
|
@ -209,7 +209,7 @@ uint32 CxbxKrnl_KernelThunkTable[379] =
|
||||||
(uint32)FUNC(&xboxkrnl::KeStallExecutionProcessor), // 0x0097 (151)
|
(uint32)FUNC(&xboxkrnl::KeStallExecutionProcessor), // 0x0097 (151)
|
||||||
(uint32)FUNC(&xboxkrnl::KeSuspendThread), // 0x0098 (152)
|
(uint32)FUNC(&xboxkrnl::KeSuspendThread), // 0x0098 (152)
|
||||||
(uint32)FUNC(&xboxkrnl::KeSynchronizeExecution), // 0x0099 (153)
|
(uint32)FUNC(&xboxkrnl::KeSynchronizeExecution), // 0x0099 (153)
|
||||||
(uint32)VARIABLE(0x009A), // 0x009A (154) KeSystemTime (Set by ConnectWindowsTimersToThunkTable)
|
(uint32)VARIABLE(&xboxkrnl::KeSystemTime), // 0x009A (154) KeSystemTime
|
||||||
(uint32)FUNC(&xboxkrnl::KeTestAlertThread), // 0x009B (155)
|
(uint32)FUNC(&xboxkrnl::KeTestAlertThread), // 0x009B (155)
|
||||||
(uint32)VARIABLE(&xboxkrnl::KeTickCount), // 0x009C (156)
|
(uint32)VARIABLE(&xboxkrnl::KeTickCount), // 0x009C (156)
|
||||||
(uint32)VARIABLE(&xboxkrnl::KeTimeIncrement), // 0x009D (157)
|
(uint32)VARIABLE(&xboxkrnl::KeTimeIncrement), // 0x009D (157)
|
||||||
|
@ -435,44 +435,3 @@ uint32 CxbxKrnl_KernelThunkTable[379] =
|
||||||
(uint32)FUNC(&xboxkrnl::MmDbgReleaseAddress), // 0x0179 (377) DEVKIT ONLY!
|
(uint32)FUNC(&xboxkrnl::MmDbgReleaseAddress), // 0x0179 (377) DEVKIT ONLY!
|
||||||
(uint32)FUNC(&xboxkrnl::MmDbgWriteCheck), // 0x017A (378) DEVKIT ONLY!
|
(uint32)FUNC(&xboxkrnl::MmDbgWriteCheck), // 0x017A (378) DEVKIT ONLY!
|
||||||
};
|
};
|
||||||
|
|
||||||
/* prevent name collisions */
|
|
||||||
namespace NtDll
|
|
||||||
{
|
|
||||||
#include "core\kernel\support\EmuNtDll.h"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Virtual memory location of KUSER_SHARED_DATA :
|
|
||||||
// See http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/base/md/i386/sim/_pertest2.c.htm
|
|
||||||
// and http://research.microsoft.com/en-us/um/redmond/projects/invisible/src/base/md/i386/sim/_glue.c.htm
|
|
||||||
// and http://processhacker.sourceforge.net/doc/ntexapi_8h_source.html
|
|
||||||
// and http://forum.sysinternals.com/0x7ffe0000-what-is-in-it_topic10012.html
|
|
||||||
#define MM_SHARED_USER_DATA_VA 0x7FFE0000
|
|
||||||
#define USER_SHARED_DATA ((NtDll::KUSER_SHARED_DATA * const)MM_SHARED_USER_DATA_VA)
|
|
||||||
|
|
||||||
// KUSER_SHARED_DATA Offsets
|
|
||||||
// See http://native-nt-toolkit.googlecode.com/svn/trunk/ndk/asm.h
|
|
||||||
// Note : KUSER_SHARED_DATA.TickCountLow seems deprecated
|
|
||||||
const UINT USER_SHARED_DATA_TICK_COUNT = 0x320;
|
|
||||||
|
|
||||||
// Here we define the addresses of the native Windows timers :
|
|
||||||
// Source: Dxbx
|
|
||||||
const xboxkrnl::PKSYSTEM_TIME CxbxNtTickCount = (xboxkrnl::PKSYSTEM_TIME)(MM_SHARED_USER_DATA_VA + USER_SHARED_DATA_TICK_COUNT);
|
|
||||||
|
|
||||||
void ConnectWindowsTimersToThunkTable()
|
|
||||||
{
|
|
||||||
// Couple the xbox thunks for xboxkrnl::KeInterruptTime and xboxkrnl::KeSystemTime
|
|
||||||
// to their actual counterparts on Windows, this way we won't have to spend any
|
|
||||||
// time on updating them ourselves, and still get highly accurate timers!
|
|
||||||
// See http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
|
|
||||||
|
|
||||||
// Point Xbox KeInterruptTime to host InterruptTime:
|
|
||||||
CxbxKrnl_KernelThunkTable[120] = (uint32)&(USER_SHARED_DATA->InterruptTime);
|
|
||||||
|
|
||||||
// Point Xbox KeSystemTime to host SystemTime; If read directly (thus skipping
|
|
||||||
// KeQuerySystemTime), this value is not adjusted with HostSystemTimeDelta!
|
|
||||||
CxbxKrnl_KernelThunkTable[154] = (uint32)&(USER_SHARED_DATA->SystemTime);
|
|
||||||
|
|
||||||
// We can't point Xbox KeTickCount to host TickCount, because it
|
|
||||||
// updates slower on the xbox. See EmuUpdateTickCount().
|
|
||||||
}
|
|
||||||
|
|
|
@ -1248,9 +1248,6 @@ void CxbxKrnlMain(int argc, char* argv[])
|
||||||
RestoreExeImageHeader();
|
RestoreExeImageHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before readout, make sure our kernel thunk table references the Windows host timer addresses :
|
|
||||||
ConnectWindowsTimersToThunkTable();
|
|
||||||
|
|
||||||
// Decode kernel thunk table address :
|
// Decode kernel thunk table address :
|
||||||
uint32_t kt = CxbxKrnl_Xbe->m_Header.dwKernelImageThunkAddr;
|
uint32_t kt = CxbxKrnl_Xbe->m_Header.dwKernelImageThunkAddr;
|
||||||
kt ^= XOR_KT_KEY[g_XbeType];
|
kt ^= XOR_KT_KEY[g_XbeType];
|
||||||
|
|
|
@ -266,8 +266,6 @@ void CxbxInitPerformanceCounters(); // Implemented in EmuKrnlKe.cpp
|
||||||
|
|
||||||
void CxbxInitFilePaths();
|
void CxbxInitFilePaths();
|
||||||
|
|
||||||
void ConnectWindowsTimersToThunkTable();
|
|
||||||
|
|
||||||
/*! Generate a standard arg format string */
|
/*! Generate a standard arg format string */
|
||||||
void CxbxConvertArgToString(std::string &dest, const char* krnlExe, const char* xbeFile, HWND hwndParent, DebugMode krnlDebug, const char* krnlDebugFile);
|
void CxbxConvertArgToString(std::string &dest, const char* krnlExe, const char* xbeFile, HWND hwndParent, DebugMode krnlDebug, const char* krnlDebugFile);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue