Merge pull request #1503 from LukeUsher/fix-nxdk-and-more
Fix nxdk and KeQueryPerformanceCounter
This commit is contained in:
commit
3393ccc684
|
@ -252,74 +252,28 @@ Xbe::Xbe(const char *x_szFilename, bool bFromGUI)
|
|||
}
|
||||
|
||||
// read Xbe library versions
|
||||
if(m_Header.dwLibraryVersionsAddr != 0)
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Library Versions...\n");
|
||||
if (m_Header.dwLibraryVersionsAddr != 0)
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Library Versions...\n");
|
||||
|
||||
fseek(XbeFile, m_Header.dwLibraryVersionsAddr - m_Header.dwBaseAddr, SEEK_SET);
|
||||
fseek(XbeFile, m_Header.dwLibraryVersionsAddr - m_Header.dwBaseAddr, SEEK_SET);
|
||||
|
||||
m_LibraryVersion = new LibraryVersion[m_Header.dwLibraryVersions];
|
||||
m_LibraryVersion = new LibraryVersion[m_Header.dwLibraryVersions];
|
||||
|
||||
for(uint32 v=0;v<m_Header.dwLibraryVersions;v++)
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Library Version 0x%.04X...", v);
|
||||
for (uint32 v = 0; v < m_Header.dwLibraryVersions; v++)
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Library Version 0x%.04X...", v);
|
||||
|
||||
if(fread(&m_LibraryVersion[v], sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
|
||||
{
|
||||
sprintf(szBuffer, "Unexpected end of file while reading Xbe Library Version %d (%Xh)", v, v);
|
||||
SetFatalError(szBuffer);
|
||||
goto cleanup;
|
||||
}
|
||||
if (fread(&m_LibraryVersion[v], sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
|
||||
{
|
||||
sprintf(szBuffer, "Unexpected end of file while reading Xbe Library Version %d (%Xh)", v, v);
|
||||
SetFatalError(szBuffer);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// read Xbe kernel library version
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Kernel Library Version...");
|
||||
|
||||
if(m_Header.dwKernelLibraryVersionAddr == 0)
|
||||
{
|
||||
SetFatalError("Could not locate kernel library version");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fseek(XbeFile, m_Header.dwKernelLibraryVersionAddr - m_Header.dwBaseAddr, SEEK_SET);
|
||||
|
||||
m_KernelLibraryVersion = new LibraryVersion;
|
||||
|
||||
if(fread(m_KernelLibraryVersion, sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
|
||||
{
|
||||
SetFatalError("Unexpected end of file while reading Xbe Kernel Version");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// read Xbe Xapi library version
|
||||
{
|
||||
printf("Xbe::Xbe: Reading Xapi Library Version...");
|
||||
|
||||
if(m_Header.dwXAPILibraryVersionAddr == 0)
|
||||
{
|
||||
SetFatalError("Could not locate Xapi Library Version");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fseek(XbeFile, m_Header.dwXAPILibraryVersionAddr - m_Header.dwBaseAddr, SEEK_SET);
|
||||
|
||||
m_XAPILibraryVersion = new LibraryVersion;
|
||||
|
||||
if(fread(m_XAPILibraryVersion, sizeof(*m_LibraryVersion), 1, XbeFile) != 1)
|
||||
{
|
||||
SetFatalError("Unexpected end of file while reading Xbe Xapi Version");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
// read Xbe sections
|
||||
{
|
||||
|
@ -412,8 +366,6 @@ Xbe::~Xbe()
|
|||
delete[] m_bzSection;
|
||||
}
|
||||
|
||||
delete m_XAPILibraryVersion;
|
||||
delete m_KernelLibraryVersion;
|
||||
delete[] m_LibraryVersion;
|
||||
delete m_TLS;
|
||||
delete[] m_szSectionName;
|
||||
|
@ -579,8 +531,6 @@ void Xbe::ConstructorInit()
|
|||
m_SectionHeader = 0;
|
||||
m_szSectionName = 0;
|
||||
m_LibraryVersion = 0;
|
||||
m_KernelLibraryVersion = 0;
|
||||
m_XAPILibraryVersion = 0;
|
||||
m_TLS = 0;
|
||||
m_bzSection = 0;
|
||||
m_SignatureHeader = 0;
|
||||
|
|
|
@ -230,7 +230,7 @@ class Xbe : public Error
|
|||
};
|
||||
}
|
||||
#include "AlignPosfix1.h"
|
||||
*m_LibraryVersion, *m_KernelLibraryVersion, *m_XAPILibraryVersion;
|
||||
*m_LibraryVersion;
|
||||
|
||||
// Xbe thread local storage
|
||||
#include "AlignPrefix1.h"
|
||||
|
|
|
@ -336,22 +336,27 @@ void InitDpcAndTimerThread()
|
|||
g_DpcData.DpcEvent = CreateEvent(/*lpEventAttributes=*/nullptr, /*bManualReset=*/FALSE, /*bInitialState=*/FALSE, /*lpName=*/nullptr);
|
||||
}
|
||||
|
||||
// Xbox Performance Counter Frequency = 733333333 (CPU Clock)
|
||||
#define XBOX_PERFORMANCE_FREQUENCY 733333333
|
||||
ULONGLONG NativeToXbox_FactorForPerformanceFrequency;
|
||||
#define XBOX_TSC_FREQUENCY 733333333 // Xbox Time Stamp Counter Frequency = 733333333 (CPU Clock)
|
||||
#define XBOX_ACPI_FREQUENCY 3375000 // Xbox ACPI frequency (3.375 mhz)
|
||||
ULONGLONG NativeToXbox_FactorForRdtsc;
|
||||
ULONGLONG NativeToXbox_FactorForAcpi;
|
||||
|
||||
void ConnectKeInterruptTimeToThunkTable(); // forward
|
||||
|
||||
ULONGLONG CxbxRdTsc(bool xbox) {
|
||||
ULONGLONG CxbxGetPerformanceCounter(bool acpi) {
|
||||
LARGE_INTEGER tsc;
|
||||
ULARGE_INTEGER scaledTsc;
|
||||
|
||||
QueryPerformanceCounter(&tsc);
|
||||
|
||||
scaledTsc.QuadPart = 1000000000;
|
||||
scaledTsc.QuadPart *= (ULONGLONG)tsc.QuadPart;
|
||||
|
||||
QueryPerformanceCounter(&tsc);
|
||||
|
||||
if (xbox && NativeToXbox_FactorForPerformanceFrequency) {
|
||||
ULARGE_INTEGER scaledTsc;
|
||||
scaledTsc.QuadPart = 1000000000;
|
||||
scaledTsc.QuadPart *= (ULONGLONG)tsc.QuadPart;
|
||||
scaledTsc.QuadPart /= NativeToXbox_FactorForPerformanceFrequency;
|
||||
if (acpi == false && NativeToXbox_FactorForRdtsc) {
|
||||
scaledTsc.QuadPart /= NativeToXbox_FactorForRdtsc;
|
||||
return scaledTsc.QuadPart;
|
||||
} else if (acpi == true && NativeToXbox_FactorForRdtsc) {
|
||||
scaledTsc.QuadPart /= NativeToXbox_FactorForAcpi;
|
||||
return scaledTsc.QuadPart;
|
||||
}
|
||||
|
||||
|
@ -370,8 +375,13 @@ void CxbxInitPerformanceCounters()
|
|||
LARGE_INTEGER t;
|
||||
t.QuadPart = 1000000000;
|
||||
t.QuadPart *= CxbxCalibrateTsc();
|
||||
t.QuadPart /= XBOX_PERFORMANCE_FREQUENCY;
|
||||
NativeToXbox_FactorForPerformanceFrequency = t.QuadPart;
|
||||
t.QuadPart /= XBOX_TSC_FREQUENCY;
|
||||
NativeToXbox_FactorForRdtsc = t.QuadPart;
|
||||
|
||||
t.QuadPart = 1000000000;
|
||||
t.QuadPart *= CxbxCalibrateTsc();
|
||||
t.QuadPart /= XBOX_ACPI_FREQUENCY;
|
||||
NativeToXbox_FactorForAcpi = t.QuadPart;
|
||||
|
||||
ConnectKeInterruptTimeToThunkTable();
|
||||
|
||||
|
@ -1204,19 +1214,15 @@ XBSYSAPI EXPORTNUM(125) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryInterruptTime
|
|||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * 0x007E - KeQueryPerformanceCounter()
|
||||
// * 0x007E - KeQueryPerformanceCounter()
|
||||
// NOTE: The KeQueryPerformance* functions run at the ACPI clock
|
||||
// The XAPI QueryPerformance* functions run at the TSC clock
|
||||
// ******************************************************************
|
||||
XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCounter(void)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
ULONGLONG ret;
|
||||
|
||||
//no matter rdtsc is patched or not, we should always return a scaled performance counter here.
|
||||
DBG_PRINTF("host tick count : %lu\n", CxbxRdTsc(/*xbox=*/false));
|
||||
ret = CxbxRdTsc(/*xbox=*/true);
|
||||
DBG_PRINTF("emulated tick count : %lu\n", ret);
|
||||
|
||||
ret = CxbxGetPerformanceCounter(/*acpi=*/true);
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
|
@ -1226,11 +1232,7 @@ XBSYSAPI EXPORTNUM(126) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceCo
|
|||
XBSYSAPI EXPORTNUM(127) xboxkrnl::ULONGLONG NTAPI xboxkrnl::KeQueryPerformanceFrequency(void)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
// Dxbx note : We return the real Xbox1 frequency here,
|
||||
// to make subsequent calculations behave the same as on the real Xbox1 :
|
||||
ULONGLONG ret = XBOX_PERFORMANCE_FREQUENCY;
|
||||
|
||||
ULONGLONG ret = XBOX_ACPI_FREQUENCY;
|
||||
RETURN(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -1297,13 +1297,12 @@ bool EmuX86_Opcode_PUSH(LPEXCEPTION_POINTERS e, _DInst& info)
|
|||
return true;
|
||||
}
|
||||
|
||||
ULONGLONG CxbxRdTsc(bool xbox); // implemented in EmuKrnlKe.cpp
|
||||
ULONGLONG CxbxGetPerformanceCounter(bool acpi); // implemented in EmuKrnlKe.cpp
|
||||
void EmuX86_Opcode_RDTSC(LPEXCEPTION_POINTERS e)
|
||||
{
|
||||
// Avoid the overhead of xboxkrnl::KeQueryPerformanceCounter,
|
||||
// by calling directly into it's backing implementation:
|
||||
// We use CxbxGetPerformanceCounter. KeQueryPerformanceCounter is a differnet frequency and cannot be used!
|
||||
ULARGE_INTEGER PerformanceCount;
|
||||
PerformanceCount.QuadPart = CxbxRdTsc(/*xbox=*/true);
|
||||
PerformanceCount.QuadPart = CxbxGetPerformanceCounter(/*acpi*/false);
|
||||
e->ContextRecord->Eax = PerformanceCount.LowPart;
|
||||
e->ContextRecord->Edx = PerformanceCount.HighPart;
|
||||
}
|
||||
|
|
|
@ -1505,15 +1505,16 @@ LPVOID WINAPI XTL::EMUPATCH(ConvertThreadToFiber)
|
|||
|
||||
// ******************************************************************
|
||||
// * patch: QueryPerformanceCounter
|
||||
// ******************************************************************
|
||||
// ******************************************************************
|
||||
ULONGLONG CxbxGetPerformanceCounter(bool acpi); // implemented in EmuKrnlKe.cpp
|
||||
BOOL WINAPI XTL::EMUPATCH(QueryPerformanceCounter)
|
||||
(
|
||||
LARGE_INTEGER * lpPerformanceCount
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
lpPerformanceCount->QuadPart = xboxkrnl::KeQueryPerformanceCounter();
|
||||
// NOTE: QueryPerformanceCounter runs from the tsc via RdTsc (733mhz)
|
||||
// However, KeQueryPerformanceCounter runs at 3.375Mhz, so we can't use that here
|
||||
lpPerformanceCount->QuadPart = CxbxGetPerformanceCounter(false);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue