mirror of
https://github.com/libretro/Play-.git
synced 2025-03-04 01:07:01 +00:00
Made EE executor work on OSX.
This commit is contained in:
parent
81e3ce2820
commit
6cd0e5e3dd
@ -784,6 +784,7 @@ void CPS2VM::EmuThread()
|
||||
{
|
||||
fesetround(FE_TOWARDZERO);
|
||||
CProfiler::GetInstance().SetWorkThread();
|
||||
m_ee->m_executor.AddExceptionHandler();
|
||||
while(1)
|
||||
{
|
||||
while(m_mailBox.IsPending())
|
||||
|
@ -1,10 +1,27 @@
|
||||
#ifndef _MSC_VER
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include "EeExecutor.h"
|
||||
#include "../Ps2Const.h"
|
||||
#include "AlignedAlloc.h"
|
||||
|
||||
#if defined(__ANDROID__) || defined(__APPLE__)
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
//TODO: Include ARM/iOS stuff
|
||||
|
||||
#if TARGET_RT_64_BIT
|
||||
#define STATE_FLAVOR x86_THREAD_STATE64
|
||||
#define STATE_FLAVOR_COUNT x86_THREAD_STATE64_COUNT
|
||||
#else
|
||||
#define STATE_FLAVOR x86_THREAD_STATE32
|
||||
#define STATE_FLAVOR_COUNT x86_THREAD_STATE32_COUNT
|
||||
#endif // !TARGET_RT_64_BIT
|
||||
|
||||
#endif
|
||||
|
||||
static CEeExecutor* g_eeExecutor = nullptr;
|
||||
|
||||
CEeExecutor::CEeExecutor(CMIPS& context, uint8* ram)
|
||||
@ -12,14 +29,22 @@ CEeExecutor::CEeExecutor(CMIPS& context, uint8* ram)
|
||||
, m_ram(ram)
|
||||
{
|
||||
m_pageSize = framework_getpagesize();
|
||||
}
|
||||
|
||||
CEeExecutor::~CEeExecutor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CEeExecutor::AddExceptionHandler()
|
||||
{
|
||||
assert(g_eeExecutor == nullptr);
|
||||
g_eeExecutor = this;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_WIN32)
|
||||
m_handler = AddVectoredExceptionHandler(TRUE, &CEeExecutor::HandleException);
|
||||
assert(m_handler != NULL);
|
||||
#else
|
||||
#elif defined(__ANDROID__)
|
||||
struct sigaction sigAction;
|
||||
sigAction.sa_handler = nullptr;
|
||||
sigAction.sa_sigaction = &HandleException;
|
||||
@ -27,12 +52,26 @@ CEeExecutor::CEeExecutor(CMIPS& context, uint8* ram)
|
||||
sigemptyset(&sigAction.sa_mask);
|
||||
int result = sigaction(SIGSEGV, &sigAction, nullptr);
|
||||
assert(result >= 0);
|
||||
#elif defined(__APPLE__)
|
||||
kern_return_t result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_port);
|
||||
assert(result == KERN_SUCCESS);
|
||||
|
||||
m_handlerThread = std::thread([this] () { HandlerThreadProc(); });
|
||||
|
||||
result = mach_port_insert_right(mach_task_self(), m_port, m_port, MACH_MSG_TYPE_MAKE_SEND);
|
||||
assert(result == KERN_SUCCESS);
|
||||
|
||||
result = thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, m_port, EXCEPTION_STATE | MACH_EXCEPTION_CODES, STATE_FLAVOR);
|
||||
assert(result == KERN_SUCCESS);
|
||||
|
||||
result = mach_port_mod_refs(mach_task_self(), m_port, MACH_PORT_RIGHT_SEND, -1);
|
||||
assert(result == KERN_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
CEeExecutor::~CEeExecutor()
|
||||
void CEeExecutor::RemoveExceptionHandler()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_WIN32)
|
||||
RemoveVectoredExceptionHandler(m_handler);
|
||||
#endif
|
||||
g_eeExecutor = nullptr;
|
||||
@ -71,22 +110,36 @@ CMipsExecutor::BasicBlockPtr CEeExecutor::BlockFactory(CMIPS& context, uint32 st
|
||||
return CMipsExecutor::BlockFactory(context, start, end);
|
||||
}
|
||||
|
||||
bool CEeExecutor::HandleAccessFault(intptr_t ptr)
|
||||
{
|
||||
ptrdiff_t addr = reinterpret_cast<uint8*>(ptr) - m_ram;
|
||||
if(addr >= 0 && addr < PS2::EE_RAM_SIZE)
|
||||
{
|
||||
addr &= ~(m_pageSize - 1);
|
||||
ClearActiveBlocksInRange(addr, addr + m_pageSize);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CEeExecutor::SetMemoryProtected(void* addr, size_t size, bool protect)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_WIN32)
|
||||
DWORD oldProtect = 0;
|
||||
BOOL result = VirtualProtect(addr, size, protect ? PAGE_READONLY : PAGE_READWRITE, &oldProtect);
|
||||
assert(result == TRUE);
|
||||
#else
|
||||
#elif defined(__ANDROID__) || defined(__APPLE__)
|
||||
uintptr_t addrValue = reinterpret_cast<uintptr_t>(addr) & ~(m_pageSize - 1);
|
||||
addr = reinterpret_cast<void*>(addrValue);
|
||||
size = size + (m_pageSize - 1) & ~(m_pageSize - 1);
|
||||
int result = mprotect(addr, size, protect ? PROT_READ : PROT_READ | PROT_WRITE);
|
||||
assert(result >= 0);
|
||||
#else
|
||||
assert(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_WIN32)
|
||||
|
||||
LONG WINAPI CEeExecutor::HandleException(_EXCEPTION_POINTERS* exceptionInfo)
|
||||
{
|
||||
@ -98,18 +151,15 @@ LONG CEeExecutor::HandleExceptionInternal(_EXCEPTION_POINTERS* exceptionInfo)
|
||||
auto exceptionRecord = exceptionInfo->ExceptionRecord;
|
||||
if(exceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
ptrdiff_t addr = reinterpret_cast<uint8*>(exceptionRecord->ExceptionInformation[1]) - m_ram;
|
||||
if(addr >= 0 && addr < PS2::EE_RAM_SIZE)
|
||||
if(HandleAccessFault(exceptionRecord->ExceptionInformation[1]))
|
||||
{
|
||||
addr &= ~(m_pageSize - 1);
|
||||
ClearActiveBlocksInRange(addr, addr + m_pageSize);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(__ANDROID__)
|
||||
|
||||
void CEeExecutor::HandleException(int sigId, siginfo_t* sigInfo, void* baseContext)
|
||||
{
|
||||
@ -119,14 +169,78 @@ void CEeExecutor::HandleException(int sigId, siginfo_t* sigInfo, void* baseConte
|
||||
void CEeExecutor::HandleExceptionInternal(int sigId, siginfo_t* sigInfo, void* baseContext)
|
||||
{
|
||||
if(sigId != SIGSEGV) return;
|
||||
ptrdiff_t addr = reinterpret_cast<uint8*>(sigInfo->si_addr) - m_ram;
|
||||
if(addr >= 0 && addr < PS2::EE_RAM_SIZE)
|
||||
if(HandleAccessFault(sigInfo->si_addr))
|
||||
{
|
||||
addr &= ~(m_pageSize - 1);
|
||||
ClearActiveBlocksInRange(addr, addr + m_pageSize);
|
||||
return;
|
||||
}
|
||||
signal(SIGSEGV, SIG_DFL);
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
void CEeExecutor::HandlerThreadProc()
|
||||
{
|
||||
#pragma pack(push, 4)
|
||||
struct INPUT_MESSAGE
|
||||
{
|
||||
mach_msg_header_t head;
|
||||
NDR_record_t ndr;
|
||||
exception_type_t exception;
|
||||
mach_msg_type_number_t codeCount;
|
||||
intptr_t code[2];
|
||||
int flavor;
|
||||
mach_msg_type_number_t stateCount;
|
||||
natural_t state[STATE_FLAVOR_COUNT];
|
||||
mach_msg_trailer_t trailer;
|
||||
};
|
||||
struct OUTPUT_MESSAGE
|
||||
{
|
||||
mach_msg_header_t head;
|
||||
NDR_record_t ndr;
|
||||
kern_return_t result;
|
||||
int flavor;
|
||||
mach_msg_type_number_t stateCount;
|
||||
natural_t state[STATE_FLAVOR_COUNT];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
while(1)
|
||||
{
|
||||
kern_return_t result = KERN_SUCCESS;
|
||||
|
||||
INPUT_MESSAGE inMsg;
|
||||
result = mach_msg(&inMsg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof(inMsg), m_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
assert(result == KERN_SUCCESS);
|
||||
|
||||
assert(inMsg.head.msgh_id == 2406); //MACH_EXCEPTION_RAISE_RPC
|
||||
|
||||
bool success = HandleAccessFault(inMsg.code[1]);
|
||||
|
||||
OUTPUT_MESSAGE outMsg;
|
||||
outMsg.head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(inMsg.head.msgh_bits), 0);
|
||||
outMsg.head.msgh_remote_port = inMsg.head.msgh_remote_port;
|
||||
outMsg.head.msgh_local_port = MACH_PORT_NULL;
|
||||
outMsg.head.msgh_id = inMsg.head.msgh_id + 100;
|
||||
outMsg.head.msgh_size = sizeof(outMsg);
|
||||
outMsg.ndr = inMsg.ndr;
|
||||
|
||||
if(success)
|
||||
{
|
||||
outMsg.result = KERN_SUCCESS;
|
||||
outMsg.flavor = STATE_FLAVOR;
|
||||
outMsg.stateCount = STATE_FLAVOR_COUNT;
|
||||
memcpy(outMsg.state, inMsg.state, STATE_FLAVOR_COUNT * sizeof(natural_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
outMsg.result = KERN_FAILURE;
|
||||
outMsg.flavor = 0;
|
||||
outMsg.stateCount = 0;
|
||||
}
|
||||
|
||||
result = mach_msg(&outMsg.head, MACH_SEND_MSG | MACH_RCV_LARGE, sizeof(outMsg), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
|
||||
assert(result == KERN_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
#include "../MipsExecutor.h"
|
||||
@ -12,6 +15,9 @@ public:
|
||||
CEeExecutor(CMIPS&, uint8*);
|
||||
virtual ~CEeExecutor();
|
||||
|
||||
void AddExceptionHandler();
|
||||
void RemoveExceptionHandler();
|
||||
|
||||
void Reset() override;
|
||||
void ClearActiveBlocksInRange(uint32, uint32) override;
|
||||
|
||||
@ -19,17 +25,23 @@ public:
|
||||
|
||||
private:
|
||||
uint8* m_ram = nullptr;
|
||||
uint32 m_pageSize = 0;
|
||||
size_t m_pageSize = 0;
|
||||
|
||||
bool HandleAccessFault(intptr_t);
|
||||
void SetMemoryProtected(void*, size_t, bool);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if defined(_WIN32)
|
||||
static LONG CALLBACK HandleException(_EXCEPTION_POINTERS*);
|
||||
LONG HandleExceptionInternal(_EXCEPTION_POINTERS*);
|
||||
|
||||
LPVOID m_handler = NULL;
|
||||
#else
|
||||
#elif defined(__ANDROID__)
|
||||
static void HandleException(int, siginfo_t*, void*);
|
||||
void HandleExceptionInternal(int, siginfo_t*, void*);
|
||||
#elif defined(__APPLE__)
|
||||
void HandlerThreadProc();
|
||||
|
||||
mach_port_t m_port = MACH_PORT_NULL;
|
||||
std::thread m_handlerThread;
|
||||
#endif
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
704F23B51B0011C8009FD916 /* Vif.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 704F23AF1B0011C8009FD916 /* Vif.cpp */; };
|
||||
704F23B61B0011C8009FD916 /* Vif1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 704F23B11B0011C8009FD916 /* Vif1.cpp */; };
|
||||
704F23B71B0011C8009FD916 /* Vpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 704F23B31B0011C8009FD916 /* Vpu.cpp */; };
|
||||
7056F2851B2683C700389AFB /* EeExecutor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7056F2831B2683C700389AFB /* EeExecutor.cpp */; };
|
||||
70684979151E882000C9574F /* libCodeGen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 70684976151E880F00C9574F /* libCodeGen.a */; };
|
||||
7068497B151E883D00C9574F /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7068497A151E883D00C9574F /* OpenGL.framework */; };
|
||||
7068497D151E885200C9574F /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7068497C151E885200C9574F /* libz.dylib */; };
|
||||
@ -218,6 +219,8 @@
|
||||
704F23B21B0011C8009FD916 /* Vif1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vif1.h; path = ../Source/ee/Vif1.h; sourceTree = "<group>"; };
|
||||
704F23B31B0011C8009FD916 /* Vpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vpu.cpp; path = ../Source/ee/Vpu.cpp; sourceTree = "<group>"; };
|
||||
704F23B41B0011C8009FD916 /* Vpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vpu.h; path = ../Source/ee/Vpu.h; sourceTree = "<group>"; };
|
||||
7056F2831B2683C700389AFB /* EeExecutor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EeExecutor.cpp; path = ../Source/ee/EeExecutor.cpp; sourceTree = "<group>"; };
|
||||
7056F2841B2683C700389AFB /* EeExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EeExecutor.h; path = ../Source/ee/EeExecutor.h; sourceTree = "<group>"; };
|
||||
705B16BC1B097DD00081B3C6 /* BlockProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlockProvider.h; path = ../Source/ISO9660/BlockProvider.h; sourceTree = "<group>"; };
|
||||
7068496E151E880E00C9574F /* CodeGen.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CodeGen.xcodeproj; path = ../../CodeGen/build_macosx/CodeGen.xcodeproj; sourceTree = "<group>"; };
|
||||
7068497A151E883D00C9574F /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
@ -693,6 +696,8 @@
|
||||
70D9F0F51AFB016900197BBE /* Ee_SubSystem.h */,
|
||||
70D9F0F61AFB016900197BBE /* EEAssembler.cpp */,
|
||||
70D9F0F71AFB016900197BBE /* EEAssembler.h */,
|
||||
7056F2831B2683C700389AFB /* EeExecutor.cpp */,
|
||||
7056F2841B2683C700389AFB /* EeExecutor.h */,
|
||||
70D9F0F81AFB016900197BBE /* FpAddTruncate.cpp */,
|
||||
70D9F0F91AFB016900197BBE /* FpAddTruncate.h */,
|
||||
70D9F0FA1AFB016900197BBE /* FpMulTruncate.cpp */,
|
||||
@ -1154,6 +1159,7 @@
|
||||
70D9F13B1AFB016900197BBE /* IPU_MotionCodeTable.cpp in Sources */,
|
||||
706849FF151E896900C9574F /* Iop_Thevent.cpp in Sources */,
|
||||
70684A00151E896900C9574F /* Iop_Thsema.cpp in Sources */,
|
||||
7056F2851B2683C700389AFB /* EeExecutor.cpp in Sources */,
|
||||
70684A01151E896900C9574F /* Iop_Timrman.cpp in Sources */,
|
||||
70D9F15A1AFB018900197BBE /* GSHandler.cpp in Sources */,
|
||||
70684A02151E896900C9574F /* Iop_Vblank.cpp in Sources */,
|
||||
|
Loading…
x
Reference in New Issue
Block a user