2015-05-16 08:23:31 +00:00
|
|
|
#include "types.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
#include "cfg/cfg.h"
|
|
|
|
|
2015-05-16 05:12:19 +00:00
|
|
|
#if HOST_OS==OS_LINUX || HOST_OS == OS_DARWIN
|
|
|
|
#if HOST_OS == OS_DARWIN
|
|
|
|
#define _XOPEN_SOURCE 1
|
|
|
|
#define __USE_GNU 1
|
2018-08-25 17:03:07 +00:00
|
|
|
#include <TargetConditionals.h>
|
2015-05-16 05:12:19 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
#include <poll.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <semaphore.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/time.h>
|
2019-08-25 16:38:36 +00:00
|
|
|
#if !defined(TARGET_BSD) && !defined(__ANDROID__) && !defined(TARGET_IPHONE) && !defined(TARGET_EMSCRIPTEN) && !defined(TARGET_OSX) && !defined(TARGET_OSX_X64)
|
2015-07-08 08:15:37 +00:00
|
|
|
#include <sys/personality.h>
|
2015-07-28 11:09:27 +00:00
|
|
|
#include <dlfcn.h>
|
2015-07-08 08:15:37 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include "hw/sh4/dyna/blockmanager.h"
|
2019-04-29 16:23:00 +00:00
|
|
|
#include "hw/mem/vmem32.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2015-05-16 01:05:11 +00:00
|
|
|
#include "linux/context.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
#include "hw/sh4/dyna/ngen.h"
|
|
|
|
|
2015-07-28 22:30:24 +00:00
|
|
|
#if !defined(TARGET_NO_EXCEPTIONS)
|
2015-05-08 16:59:20 +00:00
|
|
|
bool ngen_Rewrite(unat& addr,unat retadr,unat acc);
|
2013-12-19 17:10:14 +00:00
|
|
|
u32* ngen_readm_fail_v2(u32* ptr,u32* regs,u32 saddr);
|
|
|
|
bool VramLockedWrite(u8* address);
|
|
|
|
bool BM_LockedWrite(u8* address);
|
|
|
|
|
2015-05-16 05:12:19 +00:00
|
|
|
#if HOST_OS == OS_DARWIN
|
2015-05-16 08:04:30 +00:00
|
|
|
void sigill_handler(int sn, siginfo_t * si, void *segfault_ctx) {
|
2015-05-16 05:12:19 +00:00
|
|
|
|
2015-05-16 08:04:30 +00:00
|
|
|
rei_host_context_t ctx;
|
|
|
|
|
|
|
|
context_from_segfault(&ctx, segfault_ctx);
|
|
|
|
|
|
|
|
unat pc = (unat)ctx.pc;
|
2019-04-29 16:23:00 +00:00
|
|
|
bool dyna_cde = (pc>(unat)CodeCache) && (pc<(unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE));
|
2015-05-16 05:12:19 +00:00
|
|
|
|
2019-06-30 19:06:46 +00:00
|
|
|
ERROR_LOG(COMMON, "SIGILL @ %lx -> %p was not in vram, dynacode:%d", pc, si->si_addr, dyna_cde);
|
2015-05-16 05:12:19 +00:00
|
|
|
|
2018-07-24 11:26:31 +00:00
|
|
|
//printf("PC is used here %08X\n", pc);
|
|
|
|
kill(getpid(), SIGABRT);
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
}
|
2015-05-16 05:12:19 +00:00
|
|
|
#endif
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
|
2015-05-16 01:05:11 +00:00
|
|
|
void fault_handler (int sn, siginfo_t * si, void *segfault_ctx)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2015-05-16 01:05:11 +00:00
|
|
|
rei_host_context_t ctx;
|
|
|
|
context_from_segfault(&ctx, segfault_ctx);
|
|
|
|
|
2019-05-22 12:13:00 +00:00
|
|
|
bool dyna_cde = ((unat)CC_RX2RW(ctx.pc) > (unat)CodeCache) && ((unat)CC_RX2RW(ctx.pc) < (unat)(CodeCache + CODE_SIZE + TEMP_CODE_SIZE));
|
2015-05-16 01:05:11 +00:00
|
|
|
|
2019-05-24 16:19:33 +00:00
|
|
|
#if !defined(NO_MMU) && defined(HOST_64BIT_CPU)
|
2019-04-29 16:23:00 +00:00
|
|
|
#if HOST_CPU == CPU_ARM64
|
|
|
|
u32 op = *(u32*)ctx.pc;
|
|
|
|
bool write = (op & 0x00400000) == 0;
|
2019-06-18 13:07:32 +00:00
|
|
|
u32 exception_pc = ctx.x2;
|
2019-04-29 16:23:00 +00:00
|
|
|
#elif HOST_CPU == CPU_X64
|
|
|
|
bool write = false; // TODO?
|
2019-05-26 11:30:05 +00:00
|
|
|
u32 exception_pc = 0;
|
2019-04-29 16:23:00 +00:00
|
|
|
#endif
|
2019-05-26 11:30:05 +00:00
|
|
|
if (vmem32_handle_signal(si->si_addr, write, exception_pc))
|
2019-04-29 16:23:00 +00:00
|
|
|
return;
|
|
|
|
#endif
|
2019-06-19 20:55:47 +00:00
|
|
|
if (bm_RamWriteAccess(si->si_addr))
|
2019-06-19 09:01:33 +00:00
|
|
|
return;
|
2013-12-19 17:10:14 +00:00
|
|
|
if (VramLockedWrite((u8*)si->si_addr) || BM_LockedWrite((u8*)si->si_addr))
|
|
|
|
return;
|
2015-08-05 19:04:17 +00:00
|
|
|
#if FEAT_SHREC == DYNAREC_JIT
|
2015-05-08 16:59:20 +00:00
|
|
|
#if HOST_CPU==CPU_ARM
|
|
|
|
else if (dyna_cde)
|
|
|
|
{
|
2015-05-16 05:12:19 +00:00
|
|
|
ctx.pc = (u32)ngen_readm_fail_v2((u32*)ctx.pc, ctx.r, (unat)si->si_addr);
|
2015-05-16 01:05:11 +00:00
|
|
|
|
|
|
|
context_to_segfault(&ctx, segfault_ctx);
|
2015-05-08 16:59:20 +00:00
|
|
|
}
|
|
|
|
#elif HOST_CPU==CPU_X86
|
2015-05-16 01:05:11 +00:00
|
|
|
else if (ngen_Rewrite((unat&)ctx.pc, *(unat*)ctx.esp, ctx.eax))
|
2015-05-08 16:59:20 +00:00
|
|
|
{
|
|
|
|
//remove the call from call stack
|
2015-05-16 01:05:11 +00:00
|
|
|
ctx.esp += 4;
|
|
|
|
//restore the addr from eax to ecx so it's valid again
|
|
|
|
ctx.ecx = ctx.eax;
|
|
|
|
|
|
|
|
context_to_segfault(&ctx, segfault_ctx);
|
2015-05-08 16:59:20 +00:00
|
|
|
}
|
2015-07-14 01:35:34 +00:00
|
|
|
#elif HOST_CPU == CPU_X64
|
2019-04-29 16:23:00 +00:00
|
|
|
else if (dyna_cde && ngen_Rewrite((unat&)ctx.pc, 0, 0))
|
|
|
|
{
|
|
|
|
context_to_segfault(&ctx, segfault_ctx);
|
|
|
|
}
|
2019-01-07 20:50:46 +00:00
|
|
|
#elif HOST_CPU == CPU_ARM64
|
2019-01-16 12:04:16 +00:00
|
|
|
else if (dyna_cde && ngen_Rewrite(ctx.pc, 0, 0))
|
|
|
|
{
|
|
|
|
context_to_segfault(&ctx, segfault_ctx);
|
|
|
|
}
|
2015-05-08 16:59:20 +00:00
|
|
|
#else
|
|
|
|
#error JIT: Not supported arch
|
|
|
|
#endif
|
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
else
|
|
|
|
{
|
2019-07-28 15:37:04 +00:00
|
|
|
ERROR_LOG(COMMON, "SIGSEGV @ %zx -> %p was not in vram, dynacode:%d", ctx.pc, si->si_addr, dyna_cde);
|
2013-12-19 17:10:14 +00:00
|
|
|
die("segfault");
|
|
|
|
signal(SIGSEGV, SIG_DFL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 16:57:28 +00:00
|
|
|
void install_fault_handler(void)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2013-12-24 00:56:44 +00:00
|
|
|
struct sigaction act, segv_oact;
|
|
|
|
memset(&act, 0, sizeof(act));
|
|
|
|
act.sa_sigaction = fault_handler;
|
|
|
|
sigemptyset(&act.sa_mask);
|
|
|
|
act.sa_flags = SA_SIGINFO;
|
|
|
|
sigaction(SIGSEGV, &act, &segv_oact);
|
2015-05-16 05:12:19 +00:00
|
|
|
#if HOST_OS == OS_DARWIN
|
2014-12-17 18:13:05 +00:00
|
|
|
//this is broken on osx/ios/mach in general
|
Partially working dyna for iOS. Very few games working atm.
This works, but is extremelly hacky. Must be started without attached debugger, lldb doesn't want to let go of EXC_BAD_ADDRESS, but reicast really depends on it getting delivered as SIGSEGV/SIGBUS. Also xcode has a really bad day upon seeing the jit code. Oh well.
There's some dynarec bug that causes color corruption on bios logo/boot triagles, TA crash on ikaruga and infinitive loop on crazy taxi. I'd guess some fp-memory-write thingy, abi, or smth. Too bad.
- Force code to compile in arm mode (arm jit -> thumb mem functions is complicated)
- SIGILL, SIGBUS. Works w/o Mach exceptions and EXC_BAD_ADDRESS
- Code buffers move to __TEXT, munmapped && memmapped to actually work
- Primitive input. Button + start, or left (works to get out of bios date screen)
- Fixup emitter for thumb2/interworking (didn't work though, reverted to arm cc)
- Block Manager: Disable mem saving / page fault alloc-on-demand logic
- Move cycle counter to r11, r9 is not clean on iOS. Remove r11 from reg alloc list
- Cache flushes for iOS
- log to log.txt
- load game.chd
2015-01-19 07:52:12 +00:00
|
|
|
sigaction(SIGBUS, &act, &segv_oact);
|
|
|
|
|
|
|
|
act.sa_sigaction = sigill_handler;
|
|
|
|
sigaction(SIGILL, &act, &segv_oact);
|
2015-05-16 05:12:19 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2019-05-11 20:09:52 +00:00
|
|
|
#else // !defined(TARGET_NO_EXCEPTIONS)
|
2019-05-10 16:57:28 +00:00
|
|
|
// No exceptions/nvmem dummy handlers.
|
|
|
|
void install_fault_handler(void) {}
|
2019-05-11 20:09:52 +00:00
|
|
|
#endif // !defined(TARGET_NO_EXCEPTIONS)
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
double os_GetSeconds()
|
|
|
|
{
|
|
|
|
timeval a;
|
|
|
|
gettimeofday (&a,0);
|
|
|
|
static u64 tvs_base=a.tv_sec;
|
|
|
|
return a.tv_sec-tvs_base+a.tv_usec/1000000.0;
|
|
|
|
}
|
|
|
|
|
2019-07-24 16:24:58 +00:00
|
|
|
#ifdef TARGET_IPHONE
|
2015-06-23 06:48:29 +00:00
|
|
|
void os_DebugBreak() {
|
|
|
|
__asm__("trap");
|
|
|
|
}
|
|
|
|
#elif HOST_OS != OS_LINUX
|
2014-09-30 09:00:46 +00:00
|
|
|
void os_DebugBreak()
|
|
|
|
{
|
|
|
|
__builtin_trap();
|
|
|
|
}
|
2015-05-16 05:12:19 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
void enable_runfast()
|
|
|
|
{
|
|
|
|
#if HOST_CPU==CPU_ARM && !defined(ARMCC)
|
|
|
|
static const unsigned int x = 0x04086060;
|
|
|
|
static const unsigned int y = 0x03000000;
|
|
|
|
int r;
|
|
|
|
asm volatile (
|
|
|
|
"fmrx %0, fpscr \n\t" //r0 = FPSCR
|
|
|
|
"and %0, %0, %1 \n\t" //r0 = r0 & 0x04086060
|
|
|
|
"orr %0, %0, %2 \n\t" //r0 = r0 | 0x03000000
|
|
|
|
"fmxr fpscr, %0 \n\t" //FPSCR = r0
|
|
|
|
: "=r"(r)
|
|
|
|
: "r"(x), "r"(y)
|
|
|
|
);
|
|
|
|
|
2019-06-30 19:06:46 +00:00
|
|
|
DEBUG_LOG(BOOT, "ARM VFP-Run Fast (NFP) enabled !");
|
2013-12-19 17:10:14 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-07-07 14:20:14 +00:00
|
|
|
void linux_fix_personality() {
|
2019-08-25 16:38:36 +00:00
|
|
|
#if !defined(TARGET_BSD) && !defined(__ANDROID__) && !defined(TARGET_OS_MAC) && !defined(TARGET_EMSCRIPTEN)
|
2019-06-30 19:06:46 +00:00
|
|
|
DEBUG_LOG(BOOT, "Personality: %08X", personality(0xFFFFFFFF));
|
2015-07-08 08:15:37 +00:00
|
|
|
personality(~READ_IMPLIES_EXEC & personality(0xFFFFFFFF));
|
2019-06-30 19:06:46 +00:00
|
|
|
DEBUG_LOG(BOOT, "Updated personality: %08X", personality(0xFFFFFFFF));
|
2015-07-08 08:15:37 +00:00
|
|
|
#endif
|
2015-07-07 14:20:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void linux_rpi2_init() {
|
2019-08-25 16:38:36 +00:00
|
|
|
#if !defined(TARGET_BSD) && !defined(__ANDROID__) && !defined(TARGET_EMSCRIPTEN) && defined(TARGET_VIDEOCORE)
|
2015-07-07 14:20:14 +00:00
|
|
|
void* handle;
|
|
|
|
void (*rpi_bcm_init)(void);
|
|
|
|
|
|
|
|
handle = dlopen("libbcm_host.so", RTLD_LAZY);
|
|
|
|
|
|
|
|
if (handle) {
|
2019-06-30 19:06:46 +00:00
|
|
|
DEBUG_LOG(BOOT, "found libbcm_host");
|
2015-07-07 14:20:14 +00:00
|
|
|
*(void**) (&rpi_bcm_init) = dlsym(handle, "bcm_host_init");
|
|
|
|
if (rpi_bcm_init) {
|
2019-06-30 19:06:46 +00:00
|
|
|
DEBUG_LOG(BOOT, "rpi2: bcm_init");
|
2015-07-07 14:20:14 +00:00
|
|
|
rpi_bcm_init();
|
|
|
|
}
|
|
|
|
}
|
2015-07-28 11:09:27 +00:00
|
|
|
#endif
|
2015-07-07 14:20:14 +00:00
|
|
|
}
|
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
void common_linux_setup()
|
|
|
|
{
|
2015-07-07 14:20:14 +00:00
|
|
|
linux_fix_personality();
|
|
|
|
linux_rpi2_init();
|
2015-07-07 14:00:50 +00:00
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
enable_runfast();
|
|
|
|
install_fault_handler();
|
|
|
|
signal(SIGINT, exit);
|
|
|
|
|
|
|
|
settings.profile.run_counts=0;
|
|
|
|
|
2019-06-30 19:06:46 +00:00
|
|
|
DEBUG_LOG(BOOT, "Linux paging: %ld %08X %08X", sysconf(_SC_PAGESIZE), PAGE_SIZE, PAGE_MASK);
|
2013-12-19 17:10:14 +00:00
|
|
|
verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1));
|
|
|
|
}
|
|
|
|
#endif
|