Merge pull request #2353 from RadWolfie/fix-tls-data-emu
Fix tls data initialization from cxbxr's emulation threads end
This commit is contained in:
commit
88a37ac496
|
@ -25,8 +25,6 @@
|
|||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#include <core\kernel\exports\xboxkrnl.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
@ -36,6 +34,7 @@
|
|||
#include "Timer.h"
|
||||
#include "common\util\CxbxUtil.h"
|
||||
#include "core\kernel\support\EmuFS.h"
|
||||
#include "core/kernel/exports/EmuKrnlPs.hpp"
|
||||
#ifdef __linux__
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
@ -218,7 +217,7 @@ void Timer_Start(TimerObject* Timer, uint64_t Expire_MS)
|
|||
Timer->ExpireTime_MS.store(Expire_MS);
|
||||
if (Timer->IsXboxTimer) {
|
||||
xbox::HANDLE hThread;
|
||||
xbox::PsCreateSystemThread(&hThread, xbox::zeroptr, ClockThread, Timer, FALSE);
|
||||
CxbxrCreateThread(&hThread, xbox::zeroptr, ClockThread, Timer, FALSE);
|
||||
}
|
||||
else {
|
||||
std::thread(ClockThread, Timer).detach();
|
||||
|
|
|
@ -154,7 +154,7 @@ static unsigned int WINAPI PCSTProxy
|
|||
return 0; // will never be reached
|
||||
}
|
||||
|
||||
// Placeholder system function, instead of XapiThreadStartup
|
||||
// Placeholder system function
|
||||
xbox::void_xt NTAPI PspSystemThreadStartup
|
||||
(
|
||||
IN xbox::PKSTART_ROUTINE StartRoutine,
|
||||
|
@ -231,6 +231,35 @@ xbox::void_xt NTAPI PspReaperRoutine(
|
|||
}
|
||||
}
|
||||
|
||||
xbox::ntstatus_xt NTAPI CxbxrCreateThread
|
||||
(
|
||||
OUT xbox::PHANDLE ThreadHandle,
|
||||
OUT xbox::PHANDLE ThreadId OPTIONAL,
|
||||
IN xbox::PKSTART_ROUTINE StartRoutine,
|
||||
IN xbox::PVOID StartContext,
|
||||
IN xbox::boolean_xt DebuggerThread
|
||||
)
|
||||
{
|
||||
Xbe::TLS* XbeTls = (Xbe::TLS*)CxbxKrnl_Xbe->m_Header.dwTLSAddr;
|
||||
xbox::ulong_xt TlsDataSize = (XbeTls->dwDataEndAddr - XbeTls->dwDataStartAddr);
|
||||
TlsDataSize += XbeTls->dwSizeofZeroFill + 15;
|
||||
TlsDataSize = (TlsDataSize & ~15) + 4;
|
||||
// Verify EmuGenerateFS's TlsData's setup is carry over to XapiThreadStartup function.
|
||||
// Instead of using PspSystemThreadStartup which is entirely different function.
|
||||
return xbox::PsCreateSystemThreadEx(
|
||||
/*OUT*/ThreadHandle,
|
||||
/*ThreadExtensionSize=*/0,
|
||||
/*KernelStackSize=*/KERNEL_STACK_SIZE,
|
||||
TlsDataSize,
|
||||
/*OUT*/ThreadId,
|
||||
/*StartRoutine=*/StartRoutine,
|
||||
StartContext,
|
||||
/*CreateSuspended=*/FALSE,
|
||||
/*DebuggerThread=*/DebuggerThread,
|
||||
/*SystemRoutine=*/PspSystemThreadStartup // should use XapiThreadStartup
|
||||
);
|
||||
}
|
||||
|
||||
static xbox::KDPC PsReaperDpc;
|
||||
xbox::void_xt xbox::PsInitSystem()
|
||||
{
|
||||
|
|
|
@ -26,3 +26,12 @@ namespace xbox
|
|||
{
|
||||
void_xt PsInitSystem();
|
||||
};
|
||||
|
||||
xbox::ntstatus_xt NTAPI CxbxrCreateThread
|
||||
(
|
||||
OUT xbox::PHANDLE ThreadHandle,
|
||||
OUT xbox::PHANDLE ThreadId OPTIONAL,
|
||||
IN xbox::PKSTART_ROUTINE StartRoutine,
|
||||
IN xbox::PVOID StartContext,
|
||||
IN xbox::boolean_xt DebuggerThread
|
||||
);
|
||||
|
|
|
@ -1432,7 +1432,7 @@ static void CxbxrKrnlInitHacks()
|
|||
EmuX86_Init();
|
||||
// Create the interrupt processing thread
|
||||
xbox::HANDLE hThread;
|
||||
xbox::PsCreateSystemThread(&hThread, xbox::zeroptr, CxbxKrnlInterruptThread, xbox::zeroptr, FALSE);
|
||||
CxbxrCreateThread(&hThread, xbox::zeroptr, CxbxKrnlInterruptThread, xbox::zeroptr, FALSE);
|
||||
// Start the kernel clock thread
|
||||
TimerObject* KernelClockThr = Timer_Create(CxbxKrnlClockThread, nullptr, "Kernel clock thread", true);
|
||||
Timer_Start(KernelClockThr, SCALE_MS_IN_NS);
|
||||
|
|
|
@ -770,6 +770,25 @@ void EmuGenerateFS(xbox::PETHREAD Ethread, unsigned Host2XbStackBaseReserved, un
|
|||
}
|
||||
#endif
|
||||
|
||||
// Initialize TlsData in order to avoid xbox's APIs attempt to try access null pointer from CxbxrCreateThread.
|
||||
// As far as I have seen, Xapi's CreateThread's startup function is the only one that does the tls' initialization.
|
||||
// It will repeat same process yet will not cause performance impact.
|
||||
// NOTE: PsCreateSystemThread's startup function does not do tls' initialization.
|
||||
if (Ethread->Tcb.TlsData) {
|
||||
Xbe::TLS* XbeTls = (Xbe::TLS*)CxbxKrnl_Xbe->m_Header.dwTLSAddr;
|
||||
uint32_t RawTlsDataSize = XbeTls->dwDataEndAddr - XbeTls->dwDataStartAddr;
|
||||
// First index is a pointer to the array of tls datas.
|
||||
xbox::addr_xt* TlsData = reinterpret_cast<xbox::addr_xt*>(Ethread->Tcb.TlsData);
|
||||
*TlsData = reinterpret_cast<xbox::addr_xt>(Ethread->Tcb.TlsData) + sizeof(xbox::addr_xt);
|
||||
// Set the actual tls data from xbe.
|
||||
TlsData += 1;
|
||||
std::memcpy(TlsData, reinterpret_cast<xbox::PVOID>(XbeTls->dwDataStartAddr), RawTlsDataSize);
|
||||
|
||||
if (XbeTls->dwSizeofZeroFill) {
|
||||
std::memset(reinterpret_cast<xbox::PBYTE>(TlsData) + RawTlsDataSize, 0, XbeTls->dwSizeofZeroFill);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize a fake PrcbData.CurrentThread
|
||||
{
|
||||
// TODO: Do we need NtTib's overwrite in ENABLE_KTHREAD_SWITCHING usage?
|
||||
|
|
Loading…
Reference in New Issue