Merge pull request #9441 from skylersaleh/master
Apple M1 Support for MacOS
This commit is contained in:
22 files changed
+598
-38
No files matched your search
@@ -289,11 +289,17 @@ void DolphinAnalytics::MakeBaseBuilder()
|
||||
s64 minor_version; // NSInteger minorVersion
|
||||
s64 patch_version; // NSInteger patchVersion
|
||||
};
|
||||
|
||||
// Under arm64, we need to call objc_msgSend to recieve a struct.
|
||||
// On x86_64, we need to explicitly call objc_msgSend_stret for a struct.
|
||||
#if _M_ARM_64
|
||||
#define msgSend objc_msgSend
|
||||
#else
|
||||
#define msgSend objc_msgSend_stret
|
||||
#endif
|
||||
// NSOperatingSystemVersion version = [processInfo operatingSystemVersion]
|
||||
OSVersion version = reinterpret_cast<OSVersion (*)(id, SEL)>(objc_msgSend_stret)(
|
||||
OSVersion version = reinterpret_cast<OSVersion (*)(id, SEL)>(msgSend)(
|
||||
processInfo, sel_getUid("operatingSystemVersion"));
|
||||
|
||||
#undef msgSend
|
||||
builder.AddData("osx-ver-major", version.major_version);
|
||||
builder.AddData("osx-ver-minor", version.minor_version);
|
||||
builder.AddData("osx-ver-bugfix", version.patch_version);
|
||||
|
||||
@@ -67,6 +67,12 @@ typedef x86_thread_state64_t SContext;
|
||||
#define CTX_R14 __r14
|
||||
#define CTX_R15 __r15
|
||||
#define CTX_RIP __rip
|
||||
#elif _M_ARM_64
|
||||
typedef arm_thread_state64_t SContext;
|
||||
#define CTX_REG(x) __x[x]
|
||||
#define CTX_LR __x[30]
|
||||
#define CTX_SP __sp
|
||||
#define CTX_PC __pc
|
||||
#else
|
||||
#error No context definition for architecture
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,20 @@
|
||||
#include <unistd.h> // Needed for _POSIX_VERSION
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#ifdef _M_X86_64
|
||||
#define THREAD_STATE64_COUNT x86_THREAD_STATE64_COUNT
|
||||
#define THREAD_STATE64 x86_THREAD_STATE64
|
||||
#define thread_state64_t x86_thread_state64_t
|
||||
#elif defined(_M_ARM_64)
|
||||
#define THREAD_STATE64_COUNT ARM_THREAD_STATE64_COUNT
|
||||
#define THREAD_STATE64 ARM_THREAD_STATE64
|
||||
#define thread_state64_t arm_thread_state64_t
|
||||
#else
|
||||
#error Unsupported architecture
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace EMM
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -123,7 +137,7 @@ static void ExceptionThread(mach_port_t port)
|
||||
int64_t code[2];
|
||||
int flavor;
|
||||
mach_msg_type_number_t old_stateCnt;
|
||||
natural_t old_state[x86_THREAD_STATE64_COUNT];
|
||||
natural_t old_state[THREAD_STATE64_COUNT];
|
||||
mach_msg_trailer_t trailer;
|
||||
} msg_in;
|
||||
|
||||
@@ -134,7 +148,7 @@ static void ExceptionThread(mach_port_t port)
|
||||
kern_return_t RetCode;
|
||||
int flavor;
|
||||
mach_msg_type_number_t new_stateCnt;
|
||||
natural_t new_state[x86_THREAD_STATE64_COUNT];
|
||||
natural_t new_state[THREAD_STATE64_COUNT];
|
||||
} msg_out;
|
||||
#pragma pack()
|
||||
memset(&msg_in, 0xee, sizeof(msg_in));
|
||||
@@ -165,13 +179,13 @@ static void ExceptionThread(mach_port_t port)
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg_in.flavor != x86_THREAD_STATE64)
|
||||
if (msg_in.flavor != THREAD_STATE64)
|
||||
{
|
||||
PanicAlertFmt("unknown flavor {} (expected {})", msg_in.flavor, x86_THREAD_STATE64);
|
||||
PanicAlertFmt("unknown flavor {} (expected {})", msg_in.flavor, THREAD_STATE64);
|
||||
return;
|
||||
}
|
||||
|
||||
x86_thread_state64_t* state = (x86_thread_state64_t*)msg_in.old_state;
|
||||
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
|
||||
|
||||
bool ok = JitInterface::HandleFault((uintptr_t)msg_in.code[1], state);
|
||||
|
||||
@@ -184,9 +198,9 @@ static void ExceptionThread(mach_port_t port)
|
||||
if (ok)
|
||||
{
|
||||
msg_out.RetCode = KERN_SUCCESS;
|
||||
msg_out.flavor = x86_THREAD_STATE64;
|
||||
msg_out.new_stateCnt = x86_THREAD_STATE64_COUNT;
|
||||
memcpy(msg_out.new_state, msg_in.old_state, x86_THREAD_STATE64_COUNT * sizeof(natural_t));
|
||||
msg_out.flavor = THREAD_STATE64;
|
||||
msg_out.new_stateCnt = THREAD_STATE64_COUNT;
|
||||
memcpy(msg_out.new_state, msg_in.old_state, THREAD_STATE64_COUNT * sizeof(natural_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -218,7 +232,7 @@ void InstallExceptionHandler()
|
||||
// Debuggers set the task port, so we grab the thread port.
|
||||
CheckKR("thread_set_exception_ports",
|
||||
thread_set_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS, port,
|
||||
EXCEPTION_STATE | MACH_EXCEPTION_CODES, x86_THREAD_STATE64));
|
||||
EXCEPTION_STATE | MACH_EXCEPTION_CODES, THREAD_STATE64));
|
||||
// ...and get rid of our copy so that MACH_NOTIFY_NO_SENDERS works.
|
||||
CheckKR("mach_port_mod_refs",
|
||||
mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND, -1));
|
||||
|
||||
@@ -73,6 +73,8 @@ void JitArm64::Init()
|
||||
|
||||
bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx)
|
||||
{
|
||||
// Ifdef this since the exception handler runs on a separate thread on macOS (ARM)
|
||||
#if !(defined(__APPLE__) && defined(_M_ARM_64))
|
||||
// We can't handle any fault from other threads.
|
||||
if (!Core::IsCPUThread())
|
||||
{
|
||||
@@ -80,6 +82,7 @@ bool JitArm64::HandleFault(uintptr_t access_address, SContext* ctx)
|
||||
DoBacktrace(access_address, ctx);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool success = false;
|
||||
|
||||
@@ -124,6 +127,7 @@ void JitArm64::ClearCache()
|
||||
m_handler_to_loc.clear();
|
||||
|
||||
blocks.Clear();
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
ClearCodeSpace();
|
||||
farcode.ClearCodeSpace();
|
||||
UpdateMemoryOptions();
|
||||
@@ -596,6 +600,7 @@ void JitArm64::Jit(u32)
|
||||
{
|
||||
ClearCache();
|
||||
}
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
|
||||
std::size_t block_size = m_code_buffer.size();
|
||||
const u32 em_address = PowerPC::ppcState.pc;
|
||||
|
||||
@@ -59,11 +59,11 @@ void JitArm64BlockCache::WriteLinkBlock(Arm64Gen::ARM64XEmitter& emit,
|
||||
|
||||
void JitArm64BlockCache::WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest)
|
||||
{
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
u8* location = source.exitPtrs;
|
||||
ARM64XEmitter emit(location);
|
||||
|
||||
WriteLinkBlock(emit, source, dest);
|
||||
|
||||
emit.FlushIcache();
|
||||
}
|
||||
|
||||
@@ -71,9 +71,8 @@ void JitArm64BlockCache::WriteDestroyBlock(const JitBlock& block)
|
||||
{
|
||||
// Only clear the entry points as we might still be within this block.
|
||||
ARM64XEmitter emit(block.checkedEntry);
|
||||
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
while (emit.GetWritableCodePtr() <= block.normalEntry)
|
||||
emit.BRK(0x123);
|
||||
|
||||
emit.FlushIcache();
|
||||
}
|
||||
@@ -289,6 +289,7 @@ bool JitArm64::HandleFastmemFault(uintptr_t access_address, SContext* ctx)
|
||||
if ((const u8*)ctx->CTX_PC - fault_location > fastmem_area_length)
|
||||
return false;
|
||||
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
ARM64XEmitter emitter((u8*)fault_location);
|
||||
|
||||
emitter.BL(slow_handler_iter->second.slowmem_code);
|
||||
@@ -300,6 +301,7 @@ bool JitArm64::HandleFastmemFault(uintptr_t access_address, SContext* ctx)
|
||||
m_fault_to_handler.erase(slow_handler_iter);
|
||||
|
||||
emitter.FlushIcache();
|
||||
|
||||
ctx->CTX_PC = reinterpret_cast<std::uintptr_t>(fault_location);
|
||||
return true;
|
||||
}
|
||||
@@ -25,6 +25,8 @@ using namespace Arm64Gen;
|
||||
|
||||
void JitArm64::GenerateAsm()
|
||||
{
|
||||
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
|
||||
|
||||
// This value is all of the callee saved registers that we are required to save.
|
||||
// According to the AACPS64 we need to save R19 ~ R30 and Q8 ~ Q15.
|
||||
const u32 ALL_CALLEE_SAVED = 0x7FF80000;
|
||||
|
||||
@@ -71,9 +71,8 @@ CPUCoreBase* InitJitCore(PowerPC::CPUCore core)
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlertFmtT("The selected CPU emulation core ({0}) is not available. "
|
||||
"Please select a different CPU emulation core in the settings.",
|
||||
core);
|
||||
// Under this case the caller overrides the CPU core to the default and logs that
|
||||
// it performed the override.
|
||||
g_jit = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user