From cc2362aea9c63bf914972bbeda8b2bae114da4f9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 15 Jul 2018 08:38:39 -0700 Subject: [PATCH] Switch: Initial port work --- CMakeLists.txt | 21 +++++++--- include/mgba-util/socket.h | 9 ++++- src/platform/switch/CMakeLists.txt | 24 +++++++++++ src/platform/switch/CMakeToolchain.txt | 56 ++++++++++++++++++++++++++ src/platform/switch/memory.c | 15 +++++++ src/platform/test/perf-main.c | 18 ++++++++- 6 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 src/platform/switch/CMakeLists.txt create mode 100644 src/platform/switch/CMakeToolchain.txt create mode 100644 src/platform/switch/memory.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 851d9ffc7..bf824be50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,9 @@ project(mGBA) set(BINARY_NAME mgba CACHE INTERNAL "Name of output binaries") if(NOT MSVC) set(GCC_STD "c99") - if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.3") + if(SWITCH) + set(GCC_STD "gnu11") + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.3") set(GCC_STD "gnu99") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -std=${GCC_STD}") @@ -65,7 +67,7 @@ file(GLOB GBA_CHEATS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/cheats/*.c) file(GLOB GBA_RR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/rr/*.c) file(GLOB CORE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/*.c) file(GLOB CORE_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/test/*.c) -file(GLOB UTIL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/*.[cSs]) +file(GLOB UTIL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/*.c) file(GLOB UTIL_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/test/*.c) file(GLOB GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/gui/*.c ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/gui/*.c) file(GLOB GBA_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/renderers/*.c) @@ -283,7 +285,7 @@ if(PSP2 OR WII) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format") endif() -if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII) +if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH) set(IS_EMBEDDED ON) set(USE_DEBUGGERS OFF) set(USE_SQLITE3 OFF) @@ -331,7 +333,7 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") check_function_exists(uselocale HAVE_USELOCALE) check_function_exists(setlocale HAVE_SETLOCALE) else() - if(DEFINED 3DS OR DEFINED WII) + if(DEFINED 3DS OR DEFINED WII OR DEFINED SWITCH) set(CMAKE_REQUIRED_FLAGS -Wl,--require-defined,snprintf_l) check_function_exists(snprintf_l HAVE_SNPRINTF_L) set(CMAKE_REQUIRED_FLAGS -Wl,--require-defined,strtof_l) @@ -583,10 +585,13 @@ if(WANT_PNG AND USE_ZLIB AND NOT USE_PNG) set(PNG_SHARED OFF CACHE BOOL "" FORCE) set(PNG_TESTS OFF CACHE BOOL "" FORCE) set(SKIP_INSTALL_ALL ON) + if (SWITCH) + set(PNG_ARM_NEON "off" CACHE STRING "" FORCE) + endif() add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng libpng) - set_property(TARGET png16_static PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/libpng;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng;${ZLIB_INCLUDE_DIRS}) + set_property(TARGET png_static PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/libpng;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng;${ZLIB_INCLUDE_DIRS}) set(PNG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng ${CMAKE_CURRENT_BINARY_DIR}/libpng) - list(APPEND DEPENDENCY_LIB png16_static) + list(APPEND DEPENDENCY_LIB png_static) set(USE_PNG ON) endif() @@ -775,6 +780,10 @@ if(DEFINED PSP2) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/psp2 ${CMAKE_CURRENT_BINARY_DIR}/psp2) endif() +if(DEFINED SWITCH) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/switch ${CMAKE_CURRENT_BINARY_DIR}/switch) +endif() + # Binaries list(APPEND CORE_SRC ${UTIL_SRC} diff --git a/include/mgba-util/socket.h b/include/mgba-util/socket.h index ad00696c0..a2cece335 100644 --- a/include/mgba-util/socket.h +++ b/include/mgba-util/socket.h @@ -55,6 +55,9 @@ struct Address { extern u32* SOCUBuffer; #endif +#ifdef SWITCH +#include +#endif static inline void SocketSubsystemInit() { #ifdef _WIN32 @@ -65,6 +68,8 @@ static inline void SocketSubsystemInit() { SOCUBuffer = memalign(SOCU_ALIGN, SOCU_BUFFERSIZE); socInit(SOCUBuffer, SOCU_BUFFERSIZE); } +#elif defined(SWITCH) + socketInitializeDefault(); #endif } @@ -75,6 +80,8 @@ static inline void SocketSubsystemDeinit() { socExit(); free(SOCUBuffer); SOCUBuffer = NULL; +#elif defined(SWITCH) + socketExit(); #endif } @@ -103,7 +110,7 @@ static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) } static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) { -#ifdef _WIN32 +#if defined(_WIN32) || defined(SWITCH) return recv(socket, (char*) buffer, size, 0); #else return read(socket, buffer, size); diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt new file mode 100644 index 000000000..6b2e80679 --- /dev/null +++ b/src/platform/switch/CMakeLists.txt @@ -0,0 +1,24 @@ +find_program(ELF2NRO elf2nro) + +set(OS_DEFINES USE_VFS_FILE IOAPI_NO_64) +list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-file.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + +file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/wii/wii-*.c) +if(${CMAKE_BUILD_TYPE} STREQUAL Debug OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) + list(APPEND OS_LIB nxd) +else() + list(APPEND OS_LIB nx) +endif() +set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) +set(OS_SRC ${OS_SRC} PARENT_SCOPE) +set(OS_LIB ${OS_LIB} PARENT_SCOPE) + +if(BUILD_PERF) + add_custom_target(${BINARY_NAME}-perf.nro ALL + ${ELF2NRO} ../${BINARY_NAME}-perf ${BINARY_NAME}-perf.nro + DEPENDS ${BINARY_NAME}-perf) + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}-perf.nro + DESTINATION . COMPONENT ${BINARY_NAME}-perf) +endif() diff --git a/src/platform/switch/CMakeToolchain.txt b/src/platform/switch/CMakeToolchain.txt new file mode 100644 index 000000000..bf9db0101 --- /dev/null +++ b/src/platform/switch/CMakeToolchain.txt @@ -0,0 +1,56 @@ +if(DEFINED ENV{DEVKITPRO}) + set(DEVKITPRO $ENV{DEVKITPRO}) +else() + message(FATAL_ERROR "Could not find DEVKITPRO in environment") +endif() + +if(DEFINED ENV{DEVKITA64}) + set(DEVKITA64 $ENV{DEVKITA64}) +else() + set(DEVKITA64 ${DEVKITPRO}/devkitA64) +endif() + +if(DEFINED ENV{LIBNX}) + set(LIBNX $ENV{LIBNX}) +else() + set(LIBNX ${DEVKITPRO}/libnx) +endif() + +set(extension) +if (CMAKE_HOST_WIN32) + set(extension .exe) +endif() + +set(CMAKE_PROGRAM_PATH ${DEVKITA64}/bin) +set(cross_prefix aarch64-none-elf-) +set(arch_flags "-mtune=cortex-a57 -ffunction-sections -march=armv8-a -mtp=soft -fPIC -ftls-model=local-exec") +set(inc_flags "-I${LIBNX}/include ${arch_flags}") +set(link_flags "-L${LIBNX}/lib -lnx -specs=${LIBNX}/switch.specs ${arch_flags}") + +set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name") +set(CMAKE_SYSTEM_PROCESSOR aarch64 CACHE INTERNAL "processor") +set(CMAKE_LIBRARY_ARCHITECTURE aarch64-none-elf CACHE INTERNAL "abi") + +find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension}) +find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension}) +find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension}) +find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension}) +find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension}) +find_program(CMAKE_LINKER ${cross_prefix}ld${extension}) +set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags") +set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags") +set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags") +SET(CMAKE_ASM_COMPILE_OBJECT " -o -c ") + +set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") +set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") +set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared link flags") + +set(CMAKE_FIND_ROOT_PATH ${DEVKITARM}/aarch64-none-elf ${DEVKITPRO}/portlibs/switch) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE INTERNAL "") +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "") +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") +set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) + +set(SWITCH ON) +add_definitions(-DSWITCH) diff --git a/src/platform/switch/memory.c b/src/platform/switch/memory.c new file mode 100644 index 000000000..6459d6abb --- /dev/null +++ b/src/platform/switch/memory.c @@ -0,0 +1,15 @@ +/* Copyright (c) 2013-2018 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include + +void* anonymousMemoryMap(size_t size) { + return malloc(size); +} + +void mappedMemoryFree(void* memory, size_t size) { + UNUSED(size); + free(memory); +} diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index aff3c30d8..29cad8e05 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -19,6 +19,9 @@ #ifdef _3DS #include <3ds.h> #endif +#ifdef SWITCH +#include +#endif #include #include @@ -49,6 +52,9 @@ struct PerfOpts { extern bool allocateRomBuffer(void); FS_Archive sdmcArchive; #endif +#ifdef SWITCH +TimeType __nx_time_type = TimeType_LocalSystemClock; +#endif static void _mPerfRunloop(struct mCore* context, int* frames, bool quiet); static void _mPerfShutdown(int signal); @@ -71,6 +77,10 @@ int main(int argc, char** argv) { if (!allocateRomBuffer()) { return 1; } +#elif defined(SWITCH) + UNUSED(_mPerfShutdown); + gfxInitDefault(); + consoleInit(NULL); #else signal(SIGINT, _mPerfShutdown); #endif @@ -128,6 +138,8 @@ int main(int argc, char** argv) { #ifdef _3DS gfxExit(); acExit(); +#elif defined(SWITCH) + gfxExit(); #endif return didFail; @@ -254,7 +266,10 @@ static bool _mPerfRunServer(const char* listen, const struct mArguments* args, c SocketSend(_socket, header, strlen(header)); } char path[PATH_MAX]; - while (SocketRecv(_socket, path, sizeof(path)) > 0) { + memset(path, 0, sizeof(path)); + ssize_t i; + while ((i = SocketRecv(_socket, path, sizeof(path) - 1)) > 0) { + path[i] = '\0'; char* nl = strchr(path, '\n'); if (nl == path) { break; @@ -265,6 +280,7 @@ static bool _mPerfRunServer(const char* listen, const struct mArguments* args, c if (!_mPerfRunCore(path, args, perfOpts)) { break; } + memset(path, 0, sizeof(path)); } SocketClose(_socket); SocketClose(server);