diff --git a/.gitignore b/.gitignore index 0e0a4700..593826b0 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ obj/ .opk_data PicoDrive PicoDrive.opk +*.a diff --git a/Makefile.libretro b/Makefile.libretro index 535d5c7b..3beb1e7e 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -382,6 +382,17 @@ else ifeq ($(platform), switch) NO_MMAP = 1 ARCH = aarch64 +# Nintendo Switch (libnx) +else ifeq ($(platform), libnx) + include $(DEVKITPRO)/libnx/switch_rules + TARGET := $(TARGET_NAME)_libretro_$(platform).a + ARCH := arm64 + CFLAGS += -O3 -fomit-frame-pointer -ffast-math -I$(DEVKITPRO)/libnx/include/ -fPIE -Wl,--allow-multiple-definition + CFLAGS += -specs=$(DEVKITPRO)/libnx/switch.specs + CFLAGS += -D__SWITCH__ -DHAVE_LIBNX + CFLAGS += -DARM -D__aarch64__=1 -march=armv8-a -mtune=cortex-a57 -mtp=soft -ffast-math -mcpu=cortex-a57+crc+fp+simd -ffunction-sections + CFLAGS += -Ifrontend/switch -ftree-vectorize + STATIC_LINKING=1 # QNX else ifeq ($(platform), qnx) diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index b4bc2571..601f4d36 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -15,8 +15,12 @@ #include #ifndef _WIN32 #ifndef NO_MMAP +#ifdef __SWITCH__ +#include "../switch/mman.h" +#else #include #endif +#endif #else #include #include diff --git a/platform/switch/mman.h b/platform/switch/mman.h new file mode 100644 index 00000000..ae3d4314 --- /dev/null +++ b/platform/switch/mman.h @@ -0,0 +1,125 @@ +#ifndef MMAN_H +#define MMAN_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include +#include + +//#include "3ds_utils.h" + +#define PROT_READ 0b001 +#define PROT_WRITE 0b010 +#define PROT_EXEC 0b100 +#define MAP_PRIVATE 2 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 + +#define MAP_FAILED ((void *)-1) + + static void *dynarec_cache = NULL; + static void *dynarec_cache_mapping = NULL; + + static inline void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) + { + (void)fd; + (void)offset; + + //void* addr_out; + Result rc = svcMapPhysicalMemory(addr, len); + if (R_FAILED(rc)) + { + printf("mmap failed\n"); + return malloc(len); + } + + return addr; + + // if((prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) && + // (flags == (MAP_PRIVATE | MAP_ANONYMOUS))) + // { + // if(true)// __ctr_svchax) + // { + // /* this hack works only for pcsx_rearmed */ + // uint32_t currentHandle; + // + // if(!dynarec_cache) + // dynarec_cache = memalign(0x1000, len); + // + // //svcDuplicateHandle(¤tHandle, 0xFFFF8001); + // //svcControlProcessMemory(currentHandle, addr, dynarec_cache, + // // len, MEMOP_MAP, prot); + // svcCloseHandle(currentHandle); + // dynarec_cache_mapping = addr; + // return addr; + // } + // else + // { + // printf("tried to mmap RWX pages without svcControlProcessMemory access !\n"); + // return MAP_FAILED; + // } + // + // } + + // addr_out = memalign(0x1000, len); + // if(!addr_out) + // return MAP_FAILED; + // + // return addr_out; + } + + static inline int mprotect(void *addr, size_t len, int prot) + { + return 0; + //if(true) // __ctr_svchax) + //{ + // uint32_t currentHandle; + // //svcDuplicateHandle(¤tHandle, 0xFFFF8001); + // //svcControlProcessMemory(currentHandle, addr, NULL, + // // len, MEMOP_PROT, prot); + // svcCloseHandle(currentHandle); + // return 0; + //} + + //printf("mprotect called without svcControlProcessMemory access !\n"); + //return -1; + } + + static inline int munmap(void *addr, size_t len) + { + Result rc = svcUnmapPhysicalMemory(addr, len); + if (R_FAILED(rc)) + { + printf("munmap failed\n"); + free(addr); + } + return 0; + // if((addr == dynarec_cache_mapping) && true)//__ctr_svchax) + // { + // uint32_t currentHandle; + // //svcDuplicateHandle(¤tHandle, 0xFFFF8001); + // //svcControlProcessMemory(currentHandle, + // // dynarec_cache, dynarec_cache_mapping, + // // len, MEMOP_UNMAP, 0b111); + // svcCloseHandle(currentHandle); + // dynarec_cache_mapping = NULL; + // + // } + // else + free(addr); + + return 0; + } + +#ifdef __cplusplus +}; +#endif + +#endif // MMAN_H