diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rwxr-xr-x | .travis/linux-mingw/docker.sh | 10 | ||||
| -rwxr-xr-x | .travis/linux/docker.sh | 2 | ||||
| -rwxr-xr-x | .travis/macos/build.sh | 3 | ||||
| -rw-r--r-- | CMakeLists.txt | 77 | ||||
| -rw-r--r-- | CMakeModules/CopyYuzuUnicornDeps.cmake | 9 | ||||
| m--------- | externals/unicorn | 0 | ||||
| -rw-r--r-- | src/core/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_32.cpp | 1 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.cpp | 29 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic_64.h | 2 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.cpp | 295 | ||||
| -rw-r--r-- | src/core/arm/unicorn/arm_unicorn.h | 63 | ||||
| -rw-r--r-- | src/core/hle/kernel/physical_core.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 17 | ||||
| -rw-r--r-- | src/yuzu/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/yuzu_cmd/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/yuzu_tester/CMakeLists.txt | 2 |
18 files changed, 18 insertions, 519 deletions
diff --git a/.gitmodules b/.gitmodules index 6931a641d..41022615b 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -7,9 +7,6 @@ | |||
| 7 | [submodule "dynarmic"] | 7 | [submodule "dynarmic"] |
| 8 | path = externals/dynarmic | 8 | path = externals/dynarmic |
| 9 | url = https://github.com/MerryMage/dynarmic.git | 9 | url = https://github.com/MerryMage/dynarmic.git |
| 10 | [submodule "unicorn"] | ||
| 11 | path = externals/unicorn | ||
| 12 | url = https://github.com/yuzu-emu/unicorn | ||
| 13 | [submodule "soundtouch"] | 10 | [submodule "soundtouch"] |
| 14 | path = externals/soundtouch | 11 | path = externals/soundtouch |
| 15 | url = https://github.com/citra-emu/ext-soundtouch.git | 12 | url = https://github.com/citra-emu/ext-soundtouch.git |
diff --git a/.travis/linux-mingw/docker.sh b/.travis/linux-mingw/docker.sh index 28033acfb..80d7dfe9b 100755 --- a/.travis/linux-mingw/docker.sh +++ b/.travis/linux-mingw/docker.sh | |||
| @@ -4,16 +4,8 @@ cd /yuzu | |||
| 4 | # override Travis CI unreasonable ccache size | 4 | # override Travis CI unreasonable ccache size |
| 5 | echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf" | 5 | echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf" |
| 6 | 6 | ||
| 7 | # Dirty hack to trick unicorn makefile into believing we are in a MINGW system | ||
| 8 | mv /bin/uname /bin/uname1 && echo -e '#!/bin/sh\necho MINGW64' >> /bin/uname | ||
| 9 | chmod +x /bin/uname | ||
| 10 | |||
| 11 | # Dirty hack to trick unicorn makefile into believing we have cmd | ||
| 12 | echo '' >> /bin/cmd | ||
| 13 | chmod +x /bin/cmd | ||
| 14 | |||
| 15 | mkdir build && cd build | 7 | mkdir build && cd build |
| 16 | cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DYUZU_USE_BUNDLED_UNICORN=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release | 8 | cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCMAKE_BUILD_TYPE=Release |
| 17 | ninja | 9 | ninja |
| 18 | 10 | ||
| 19 | # Clean up the dirty hacks | 11 | # Clean up the dirty hacks |
diff --git a/.travis/linux/docker.sh b/.travis/linux/docker.sh index 3a9970384..166fb6d4c 100755 --- a/.travis/linux/docker.sh +++ b/.travis/linux/docker.sh | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | cd /yuzu | 3 | cd /yuzu |
| 4 | 4 | ||
| 5 | mkdir build && cd build | 5 | mkdir build && cd build |
| 6 | cmake .. -G Ninja -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON | 6 | cmake .. -G Ninja -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON |
| 7 | ninja | 7 | ninja |
| 8 | 8 | ||
| 9 | ccache -s | 9 | ccache -s |
diff --git a/.travis/macos/build.sh b/.travis/macos/build.sh index 0abd1a93a..db1c7cae7 100755 --- a/.travis/macos/build.sh +++ b/.travis/macos/build.sh | |||
| @@ -4,13 +4,12 @@ set -o pipefail | |||
| 4 | 4 | ||
| 5 | export MACOSX_DEPLOYMENT_TARGET=10.14 | 5 | export MACOSX_DEPLOYMENT_TARGET=10.14 |
| 6 | export Qt5_DIR=$(brew --prefix)/opt/qt5 | 6 | export Qt5_DIR=$(brew --prefix)/opt/qt5 |
| 7 | export UNICORNDIR=$(pwd)/externals/unicorn | ||
| 8 | export PATH="/usr/local/opt/ccache/libexec:$PATH" | 7 | export PATH="/usr/local/opt/ccache/libexec:$PATH" |
| 9 | 8 | ||
| 10 | # TODO: Build using ninja instead of make | 9 | # TODO: Build using ninja instead of make |
| 11 | mkdir build && cd build | 10 | mkdir build && cd build |
| 12 | cmake --version | 11 | cmake --version |
| 13 | cmake .. -DYUZU_USE_BUNDLED_UNICORN=ON -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DUSE_DISCORD_PRESENCE=ON | 12 | cmake .. -DYUZU_USE_QT_WEB_ENGINE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DUSE_DISCORD_PRESENCE=ON |
| 14 | make -j4 | 13 | make -j4 |
| 15 | 14 | ||
| 16 | ccache -s | 15 | ccache -s |
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bd9d2aa7..8fc2de042 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -18,8 +18,6 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "EN | |||
| 18 | 18 | ||
| 19 | option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) | 19 | option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) |
| 20 | 20 | ||
| 21 | option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON) | ||
| 22 | |||
| 23 | option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) | 21 | option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) |
| 24 | 22 | ||
| 25 | option(YUZU_ENABLE_BOXCAT "Enable the Boxcat service, a yuzu high-level implementation of BCAT" ON) | 23 | option(YUZU_ENABLE_BOXCAT "Enable the Boxcat service, a yuzu high-level implementation of BCAT" ON) |
| @@ -372,81 +370,6 @@ endif() | |||
| 372 | set(THREADS_PREFER_PTHREAD_FLAG ON) | 370 | set(THREADS_PREFER_PTHREAD_FLAG ON) |
| 373 | find_package(Threads REQUIRED) | 371 | find_package(Threads REQUIRED) |
| 374 | 372 | ||
| 375 | # If unicorn isn't found, msvc -> download bundled unicorn; everyone else -> build external | ||
| 376 | if (YUZU_USE_BUNDLED_UNICORN) | ||
| 377 | if (MSVC) | ||
| 378 | message(STATUS "unicorn not found, falling back to bundled") | ||
| 379 | # Detect toolchain and platform | ||
| 380 | if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64) | ||
| 381 | set(UNICORN_VER "unicorn-yuzu") | ||
| 382 | else() | ||
| 383 | message(FATAL_ERROR "No bundled Unicorn binaries for your toolchain. Disable YUZU_USE_BUNDLED_UNICORN and provide your own.") | ||
| 384 | endif() | ||
| 385 | |||
| 386 | if (DEFINED UNICORN_VER) | ||
| 387 | download_bundled_external("unicorn/" ${UNICORN_VER} UNICORN_PREFIX) | ||
| 388 | endif() | ||
| 389 | |||
| 390 | if (DEFINED UNICORN_VER) | ||
| 391 | download_bundled_external("unicorn/" ${UNICORN_VER} UNICORN_PREFIX) | ||
| 392 | endif() | ||
| 393 | |||
| 394 | set(UNICORN_FOUND YES) | ||
| 395 | set(LIBUNICORN_INCLUDE_DIR "${UNICORN_PREFIX}/include" CACHE PATH "Path to Unicorn headers" FORCE) | ||
| 396 | set(LIBUNICORN_LIBRARY "${UNICORN_PREFIX}/lib/x64/unicorn_dynload.lib" CACHE PATH "Path to Unicorn library" FORCE) | ||
| 397 | set(UNICORN_DLL_DIR "${UNICORN_PREFIX}/lib/x64/" CACHE PATH "Path to unicorn.dll" FORCE) | ||
| 398 | else() | ||
| 399 | message(STATUS "unicorn not found, falling back to externals") | ||
| 400 | if (MINGW) | ||
| 401 | set(UNICORN_LIB_NAME "unicorn.a") | ||
| 402 | else() | ||
| 403 | set(UNICORN_LIB_NAME "libunicorn.a") | ||
| 404 | endif() | ||
| 405 | |||
| 406 | set(UNICORN_FOUND YES) | ||
| 407 | set(UNICORN_PREFIX ${PROJECT_SOURCE_DIR}/externals/unicorn) | ||
| 408 | set(LIBUNICORN_LIBRARY "${UNICORN_PREFIX}/${UNICORN_LIB_NAME}" CACHE PATH "Path to Unicorn library" FORCE) | ||
| 409 | set(LIBUNICORN_INCLUDE_DIR "${UNICORN_PREFIX}/include" CACHE PATH "Path to Unicorn headers" FORCE) | ||
| 410 | set(UNICORN_DLL_DIR "${UNICORN_PREFIX}/" CACHE PATH "Path to unicorn dynamic library" FORCE) | ||
| 411 | |||
| 412 | find_package(PythonInterp 2.7 REQUIRED) | ||
| 413 | |||
| 414 | if (MINGW) | ||
| 415 | # Intentionally call the unicorn makefile directly instead of using make.sh so that we can override the | ||
| 416 | # UNAME_S makefile variable to MINGW. This way we don't have to hack at the uname binary to build | ||
| 417 | # Additionally, overriding DO_WINDOWS_EXPORT prevents unicorn from patching the static unicorn.a by using msvc and cmd, | ||
| 418 | # which are both things we don't have in a mingw cross compiling environment. | ||
| 419 | add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY} | ||
| 420 | COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-gcc-ar RANLIB=x86_64-w64-mingw32-gcc-ranlib make UNAME_S=MINGW DO_WINDOWS_EXPORT=0 | ||
| 421 | WORKING_DIRECTORY ${UNICORN_PREFIX} | ||
| 422 | ) | ||
| 423 | else() | ||
| 424 | add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY} | ||
| 425 | COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh macos-universal-no | ||
| 426 | WORKING_DIRECTORY ${UNICORN_PREFIX} | ||
| 427 | ) | ||
| 428 | endif() | ||
| 429 | |||
| 430 | # ALL makes this custom target build every time | ||
| 431 | # but it won't actually build if LIBUNICORN_LIBRARY is up to date | ||
| 432 | add_custom_target(unicorn-build ALL | ||
| 433 | DEPENDS ${LIBUNICORN_LIBRARY} | ||
| 434 | ) | ||
| 435 | unset(UNICORN_LIB_NAME) | ||
| 436 | endif() | ||
| 437 | else() | ||
| 438 | find_package(Unicorn REQUIRED) | ||
| 439 | endif() | ||
| 440 | |||
| 441 | if (UNICORN_FOUND) | ||
| 442 | add_library(unicorn INTERFACE) | ||
| 443 | add_dependencies(unicorn unicorn-build) | ||
| 444 | target_link_libraries(unicorn INTERFACE "${LIBUNICORN_LIBRARY}") | ||
| 445 | target_include_directories(unicorn INTERFACE "${LIBUNICORN_INCLUDE_DIR}") | ||
| 446 | else() | ||
| 447 | message(FATAL_ERROR "Could not find or build unicorn which is required.") | ||
| 448 | endif() | ||
| 449 | |||
| 450 | # Platform-specific library requirements | 373 | # Platform-specific library requirements |
| 451 | # ====================================== | 374 | # ====================================== |
| 452 | 375 | ||
diff --git a/CMakeModules/CopyYuzuUnicornDeps.cmake b/CMakeModules/CopyYuzuUnicornDeps.cmake deleted file mode 100644 index 7af0ef023..000000000 --- a/CMakeModules/CopyYuzuUnicornDeps.cmake +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | function(copy_yuzu_unicorn_deps target_dir) | ||
| 2 | include(WindowsCopyFiles) | ||
| 3 | set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/") | ||
| 4 | windows_copy_files(${target_dir} ${UNICORN_DLL_DIR} ${DLL_DEST} | ||
| 5 | libgcc_s_seh-1.dll | ||
| 6 | libwinpthread-1.dll | ||
| 7 | unicorn.dll | ||
| 8 | ) | ||
| 9 | endfunction(copy_yuzu_unicorn_deps) | ||
diff --git a/externals/unicorn b/externals/unicorn deleted file mode 160000 | |||
| Subproject 73f45735354396766a4bfb26d0b96b06e5cf31b | |||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e0f207f3e..19c926662 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -13,8 +13,6 @@ add_library(core STATIC | |||
| 13 | arm/dynarmic/arm_exclusive_monitor.h | 13 | arm/dynarmic/arm_exclusive_monitor.h |
| 14 | arm/exclusive_monitor.cpp | 14 | arm/exclusive_monitor.cpp |
| 15 | arm/exclusive_monitor.h | 15 | arm/exclusive_monitor.h |
| 16 | arm/unicorn/arm_unicorn.cpp | ||
| 17 | arm/unicorn/arm_unicorn.h | ||
| 18 | constants.cpp | 16 | constants.cpp |
| 19 | constants.h | 17 | constants.h |
| 20 | core.cpp | 18 | core.cpp |
| @@ -644,7 +642,7 @@ endif() | |||
| 644 | create_target_directory_groups(core) | 642 | create_target_directory_groups(core) |
| 645 | 643 | ||
| 646 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | 644 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) |
| 647 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls opus unicorn zip) | 645 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls opus zip) |
| 648 | 646 | ||
| 649 | if (YUZU_ENABLE_BOXCAT) | 647 | if (YUZU_ENABLE_BOXCAT) |
| 650 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) | 648 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index b5f28a86e..6dc03f3b1 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <dynarmic/A32/a32.h> | 7 | #include <dynarmic/A32/a32.h> |
| 8 | #include <dynarmic/A32/config.h> | 8 | #include <dynarmic/A32/config.h> |
| 9 | #include <dynarmic/A32/context.h> | 9 | #include <dynarmic/A32/context.h> |
| 10 | #include "common/assert.h" | ||
| 10 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 11 | #include "common/page_table.h" | 12 | #include "common/page_table.h" |
| 12 | #include "core/arm/cpu_interrupt_handler.h" | 13 | #include "core/arm/cpu_interrupt_handler.h" |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index ce9968724..9f170a224 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <memory> | 6 | #include <memory> |
| 7 | #include <dynarmic/A64/a64.h> | 7 | #include <dynarmic/A64/a64.h> |
| 8 | #include <dynarmic/A64/config.h> | 8 | #include <dynarmic/A64/config.h> |
| 9 | #include "common/assert.h" | ||
| 9 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 10 | #include "common/page_table.h" | 11 | #include "common/page_table.h" |
| 11 | #include "core/arm/cpu_interrupt_handler.h" | 12 | #include "core/arm/cpu_interrupt_handler.h" |
| @@ -13,7 +14,6 @@ | |||
| 13 | #include "core/arm/dynarmic/arm_exclusive_monitor.h" | 14 | #include "core/arm/dynarmic/arm_exclusive_monitor.h" |
| 14 | #include "core/core.h" | 15 | #include "core/core.h" |
| 15 | #include "core/core_timing.h" | 16 | #include "core/core_timing.h" |
| 16 | #include "core/core_timing_util.h" | ||
| 17 | #include "core/gdbstub/gdbstub.h" | 17 | #include "core/gdbstub/gdbstub.h" |
| 18 | #include "core/hardware_properties.h" | 18 | #include "core/hardware_properties.h" |
| 19 | #include "core/hle/kernel/process.h" | 19 | #include "core/hle/kernel/process.h" |
| @@ -82,16 +82,9 @@ public: | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { | 84 | void InterpreterFallback(u64 pc, std::size_t num_instructions) override { |
| 85 | LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, | 85 | LOG_ERROR(Core_ARM, |
| 86 | num_instructions, MemoryReadCode(pc)); | 86 | "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, |
| 87 | 87 | num_instructions, MemoryReadCode(pc)); | |
| 88 | ARM_Interface::ThreadContext64 ctx; | ||
| 89 | parent.SaveContext(ctx); | ||
| 90 | parent.inner_unicorn.LoadContext(ctx); | ||
| 91 | parent.inner_unicorn.ExecuteInstructions(num_instructions); | ||
| 92 | parent.inner_unicorn.SaveContext(ctx); | ||
| 93 | parent.LoadContext(ctx); | ||
| 94 | num_interpreted_instructions += num_instructions; | ||
| 95 | } | 88 | } |
| 96 | 89 | ||
| 97 | void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { | 90 | void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { |
| @@ -127,18 +120,17 @@ public: | |||
| 127 | if (parent.uses_wall_clock) { | 120 | if (parent.uses_wall_clock) { |
| 128 | return; | 121 | return; |
| 129 | } | 122 | } |
| 123 | |||
| 130 | // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a | 124 | // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a |
| 131 | // rough approximation of the amount of executed ticks in the system, it may be thrown off | 125 | // rough approximation of the amount of executed ticks in the system, it may be thrown off |
| 132 | // if not all cores are doing a similar amount of work. Instead of doing this, we should | 126 | // if not all cores are doing a similar amount of work. Instead of doing this, we should |
| 133 | // device a way so that timing is consistent across all cores without increasing the ticks 4 | 127 | // device a way so that timing is consistent across all cores without increasing the ticks 4 |
| 134 | // times. | 128 | // times. |
| 135 | u64 amortized_ticks = | 129 | u64 amortized_ticks = ticks / Core::Hardware::NUM_CPU_CORES; |
| 136 | (ticks - num_interpreted_instructions) / Core::Hardware::NUM_CPU_CORES; | ||
| 137 | // Always execute at least one tick. | 130 | // Always execute at least one tick. |
| 138 | amortized_ticks = std::max<u64>(amortized_ticks, 1); | 131 | amortized_ticks = std::max<u64>(amortized_ticks, 1); |
| 139 | 132 | ||
| 140 | parent.system.CoreTiming().AddTicks(amortized_ticks); | 133 | parent.system.CoreTiming().AddTicks(amortized_ticks); |
| 141 | num_interpreted_instructions = 0; | ||
| 142 | } | 134 | } |
| 143 | 135 | ||
| 144 | u64 GetTicksRemaining() override { | 136 | u64 GetTicksRemaining() override { |
| @@ -156,7 +148,6 @@ public: | |||
| 156 | } | 148 | } |
| 157 | 149 | ||
| 158 | ARM_Dynarmic_64& parent; | 150 | ARM_Dynarmic_64& parent; |
| 159 | std::size_t num_interpreted_instructions = 0; | ||
| 160 | u64 tpidrro_el0 = 0; | 151 | u64 tpidrro_el0 = 0; |
| 161 | u64 tpidr_el0 = 0; | 152 | u64 tpidr_el0 = 0; |
| 162 | static constexpr u64 minimum_run_cycles = 1000U; | 153 | static constexpr u64 minimum_run_cycles = 1000U; |
| @@ -248,12 +239,8 @@ ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handle | |||
| 248 | bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor, | 239 | bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor, |
| 249 | std::size_t core_index) | 240 | std::size_t core_index) |
| 250 | : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, | 241 | : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, |
| 251 | cb(std::make_unique<DynarmicCallbacks64>(*this)), inner_unicorn{system, interrupt_handlers, | 242 | cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index}, |
| 252 | uses_wall_clock, | 243 | exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} |
| 253 | ARM_Unicorn::Arch::AArch64, | ||
| 254 | core_index}, | ||
| 255 | core_index{core_index}, exclusive_monitor{ | ||
| 256 | dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {} | ||
| 257 | 244 | ||
| 258 | ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; | 245 | ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; |
| 259 | 246 | ||
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h index 403c55961..28e11a17d 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.h +++ b/src/core/arm/dynarmic/arm_dynarmic_64.h | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include "common/hash.h" | 12 | #include "common/hash.h" |
| 13 | #include "core/arm/arm_interface.h" | 13 | #include "core/arm/arm_interface.h" |
| 14 | #include "core/arm/exclusive_monitor.h" | 14 | #include "core/arm/exclusive_monitor.h" |
| 15 | #include "core/arm/unicorn/arm_unicorn.h" | ||
| 16 | 15 | ||
| 17 | namespace Core::Memory { | 16 | namespace Core::Memory { |
| 18 | class Memory; | 17 | class Memory; |
| @@ -71,7 +70,6 @@ private: | |||
| 71 | std::unique_ptr<DynarmicCallbacks64> cb; | 70 | std::unique_ptr<DynarmicCallbacks64> cb; |
| 72 | JitCacheType jit_cache; | 71 | JitCacheType jit_cache; |
| 73 | std::shared_ptr<Dynarmic::A64::Jit> jit; | 72 | std::shared_ptr<Dynarmic::A64::Jit> jit; |
| 74 | ARM_Unicorn inner_unicorn; | ||
| 75 | 73 | ||
| 76 | std::size_t core_index; | 74 | std::size_t core_index; |
| 77 | DynarmicExclusiveMonitor& exclusive_monitor; | 75 | DynarmicExclusiveMonitor& exclusive_monitor; |
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp deleted file mode 100644 index 1df3f3ed1..000000000 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ /dev/null | |||
| @@ -1,295 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <unicorn/arm64.h> | ||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/microprofile.h" | ||
| 9 | #include "core/arm/cpu_interrupt_handler.h" | ||
| 10 | #include "core/arm/unicorn/arm_unicorn.h" | ||
| 11 | #include "core/core.h" | ||
| 12 | #include "core/core_timing.h" | ||
| 13 | #include "core/hle/kernel/scheduler.h" | ||
| 14 | #include "core/hle/kernel/svc.h" | ||
| 15 | #include "core/memory.h" | ||
| 16 | |||
| 17 | namespace Core { | ||
| 18 | |||
| 19 | // Load Unicorn DLL once on Windows using RAII | ||
| 20 | #ifdef _MSC_VER | ||
| 21 | #include <unicorn_dynload.h> | ||
| 22 | struct LoadDll { | ||
| 23 | private: | ||
| 24 | LoadDll() { | ||
| 25 | ASSERT(uc_dyn_load(NULL, 0)); | ||
| 26 | } | ||
| 27 | ~LoadDll() { | ||
| 28 | ASSERT(uc_dyn_free()); | ||
| 29 | } | ||
| 30 | static LoadDll g_load_dll; | ||
| 31 | }; | ||
| 32 | LoadDll LoadDll::g_load_dll; | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #define CHECKED(expr) \ | ||
| 36 | do { \ | ||
| 37 | if (auto _cerr = (expr)) { \ | ||
| 38 | ASSERT_MSG(false, "Call " #expr " failed with error: {} ({})\n", _cerr, \ | ||
| 39 | uc_strerror(_cerr)); \ | ||
| 40 | } \ | ||
| 41 | } while (0) | ||
| 42 | |||
| 43 | static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) { | ||
| 44 | GDBStub::BreakpointAddress bkpt = | ||
| 45 | GDBStub::GetNextBreakpointFromAddress(address, GDBStub::BreakpointType::Execute); | ||
| 46 | if (GDBStub::IsMemoryBreak() || | ||
| 47 | (bkpt.type != GDBStub::BreakpointType::None && address == bkpt.address)) { | ||
| 48 | auto core = static_cast<ARM_Unicorn*>(user_data); | ||
| 49 | core->RecordBreak(bkpt); | ||
| 50 | uc_emu_stop(uc); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int size, u64 value, | ||
| 55 | void* user_data) { | ||
| 56 | auto* const system = static_cast<System*>(user_data); | ||
| 57 | |||
| 58 | ARM_Interface::ThreadContext64 ctx{}; | ||
| 59 | system->CurrentArmInterface().SaveContext(ctx); | ||
| 60 | ASSERT_MSG(false, "Attempted to read from unmapped memory: 0x{:X}, pc=0x{:X}, lr=0x{:X}", addr, | ||
| 61 | ctx.pc, ctx.cpu_registers[30]); | ||
| 62 | |||
| 63 | return false; | ||
| 64 | } | ||
| 65 | |||
| 66 | ARM_Unicorn::ARM_Unicorn(System& system, CPUInterrupts& interrupt_handlers, bool uses_wall_clock, | ||
| 67 | Arch architecture, std::size_t core_index) | ||
| 68 | : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, core_index{core_index} { | ||
| 69 | const auto arch = architecture == Arch::AArch32 ? UC_ARCH_ARM : UC_ARCH_ARM64; | ||
| 70 | CHECKED(uc_open(arch, UC_MODE_ARM, &uc)); | ||
| 71 | |||
| 72 | auto fpv = 3 << 20; | ||
| 73 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_CPACR_EL1, &fpv)); | ||
| 74 | |||
| 75 | uc_hook hook{}; | ||
| 76 | CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, UINT64_MAX)); | ||
| 77 | CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, &system, 0, | ||
| 78 | UINT64_MAX)); | ||
| 79 | if (GDBStub::IsServerEnabled()) { | ||
| 80 | CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, UINT64_MAX)); | ||
| 81 | last_bkpt_hit = false; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | ARM_Unicorn::~ARM_Unicorn() { | ||
| 86 | CHECKED(uc_close(uc)); | ||
| 87 | } | ||
| 88 | |||
| 89 | void ARM_Unicorn::SetPC(u64 pc) { | ||
| 90 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &pc)); | ||
| 91 | } | ||
| 92 | |||
| 93 | u64 ARM_Unicorn::GetPC() const { | ||
| 94 | u64 val{}; | ||
| 95 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &val)); | ||
| 96 | return val; | ||
| 97 | } | ||
| 98 | |||
| 99 | u64 ARM_Unicorn::GetReg(int regn) const { | ||
| 100 | u64 val{}; | ||
| 101 | auto treg = UC_ARM64_REG_SP; | ||
| 102 | if (regn <= 28) { | ||
| 103 | treg = (uc_arm64_reg)(UC_ARM64_REG_X0 + regn); | ||
| 104 | } else if (regn < 31) { | ||
| 105 | treg = (uc_arm64_reg)(UC_ARM64_REG_X29 + regn - 29); | ||
| 106 | } | ||
| 107 | CHECKED(uc_reg_read(uc, treg, &val)); | ||
| 108 | return val; | ||
| 109 | } | ||
| 110 | |||
| 111 | void ARM_Unicorn::SetReg(int regn, u64 val) { | ||
| 112 | auto treg = UC_ARM64_REG_SP; | ||
| 113 | if (regn <= 28) { | ||
| 114 | treg = (uc_arm64_reg)(UC_ARM64_REG_X0 + regn); | ||
| 115 | } else if (regn < 31) { | ||
| 116 | treg = (uc_arm64_reg)(UC_ARM64_REG_X29 + regn - 29); | ||
| 117 | } | ||
| 118 | CHECKED(uc_reg_write(uc, treg, &val)); | ||
| 119 | } | ||
| 120 | |||
| 121 | u128 ARM_Unicorn::GetVectorReg(int /*index*/) const { | ||
| 122 | UNIMPLEMENTED(); | ||
| 123 | static constexpr u128 res{}; | ||
| 124 | return res; | ||
| 125 | } | ||
| 126 | |||
| 127 | void ARM_Unicorn::SetVectorReg(int /*index*/, u128 /*value*/) { | ||
| 128 | UNIMPLEMENTED(); | ||
| 129 | } | ||
| 130 | |||
| 131 | u32 ARM_Unicorn::GetPSTATE() const { | ||
| 132 | u64 nzcv{}; | ||
| 133 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &nzcv)); | ||
| 134 | return static_cast<u32>(nzcv); | ||
| 135 | } | ||
| 136 | |||
| 137 | void ARM_Unicorn::SetPSTATE(u32 pstate) { | ||
| 138 | u64 nzcv = pstate; | ||
| 139 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &nzcv)); | ||
| 140 | } | ||
| 141 | |||
| 142 | VAddr ARM_Unicorn::GetTlsAddress() const { | ||
| 143 | u64 base{}; | ||
| 144 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); | ||
| 145 | return base; | ||
| 146 | } | ||
| 147 | |||
| 148 | void ARM_Unicorn::SetTlsAddress(VAddr base) { | ||
| 149 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); | ||
| 150 | } | ||
| 151 | |||
| 152 | u64 ARM_Unicorn::GetTPIDR_EL0() const { | ||
| 153 | u64 value{}; | ||
| 154 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_TPIDR_EL0, &value)); | ||
| 155 | return value; | ||
| 156 | } | ||
| 157 | |||
| 158 | void ARM_Unicorn::SetTPIDR_EL0(u64 value) { | ||
| 159 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDR_EL0, &value)); | ||
| 160 | } | ||
| 161 | |||
| 162 | void ARM_Unicorn::ChangeProcessorID(std::size_t new_core_id) { | ||
| 163 | core_index = new_core_id; | ||
| 164 | } | ||
| 165 | |||
| 166 | void ARM_Unicorn::Run() { | ||
| 167 | if (GDBStub::IsServerEnabled()) { | ||
| 168 | ExecuteInstructions(std::max(4000000U, 0U)); | ||
| 169 | } else { | ||
| 170 | while (true) { | ||
| 171 | if (interrupt_handlers[core_index].IsInterrupted()) { | ||
| 172 | return; | ||
| 173 | } | ||
| 174 | ExecuteInstructions(10); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | void ARM_Unicorn::Step() { | ||
| 180 | ExecuteInstructions(1); | ||
| 181 | } | ||
| 182 | |||
| 183 | MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64)); | ||
| 184 | |||
| 185 | void ARM_Unicorn::ExecuteInstructions(std::size_t num_instructions) { | ||
| 186 | MICROPROFILE_SCOPE(ARM_Jit_Unicorn); | ||
| 187 | |||
| 188 | // Temporarily map the code page for Unicorn | ||
| 189 | u64 map_addr{GetPC() & ~Memory::PAGE_MASK}; | ||
| 190 | std::vector<u8> page_buffer(Memory::PAGE_SIZE); | ||
| 191 | system.Memory().ReadBlock(map_addr, page_buffer.data(), page_buffer.size()); | ||
| 192 | |||
| 193 | CHECKED(uc_mem_map_ptr(uc, map_addr, page_buffer.size(), | ||
| 194 | UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC, page_buffer.data())); | ||
| 195 | CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions)); | ||
| 196 | CHECKED(uc_mem_unmap(uc, map_addr, page_buffer.size())); | ||
| 197 | if (GDBStub::IsServerEnabled()) { | ||
| 198 | if (last_bkpt_hit && last_bkpt.type == GDBStub::BreakpointType::Execute) { | ||
| 199 | uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address); | ||
| 200 | } | ||
| 201 | |||
| 202 | Kernel::Thread* const thread = system.CurrentScheduler().GetCurrentThread(); | ||
| 203 | SaveContext(thread->GetContext64()); | ||
| 204 | if (last_bkpt_hit || GDBStub::IsMemoryBreak() || GDBStub::GetCpuStepFlag()) { | ||
| 205 | last_bkpt_hit = false; | ||
| 206 | GDBStub::Break(); | ||
| 207 | GDBStub::SendTrap(thread, 5); | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | void ARM_Unicorn::SaveContext(ThreadContext64& ctx) { | ||
| 213 | int uregs[32]; | ||
| 214 | void* tregs[32]; | ||
| 215 | |||
| 216 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_SP, &ctx.sp)); | ||
| 217 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_PC, &ctx.pc)); | ||
| 218 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_NZCV, &ctx.pstate)); | ||
| 219 | |||
| 220 | for (auto i = 0; i < 29; ++i) { | ||
| 221 | uregs[i] = UC_ARM64_REG_X0 + i; | ||
| 222 | tregs[i] = &ctx.cpu_registers[i]; | ||
| 223 | } | ||
| 224 | uregs[29] = UC_ARM64_REG_X29; | ||
| 225 | tregs[29] = (void*)&ctx.cpu_registers[29]; | ||
| 226 | uregs[30] = UC_ARM64_REG_X30; | ||
| 227 | tregs[30] = (void*)&ctx.cpu_registers[30]; | ||
| 228 | |||
| 229 | CHECKED(uc_reg_read_batch(uc, uregs, tregs, 31)); | ||
| 230 | |||
| 231 | for (int i = 0; i < 32; ++i) { | ||
| 232 | uregs[i] = UC_ARM64_REG_Q0 + i; | ||
| 233 | tregs[i] = &ctx.vector_registers[i]; | ||
| 234 | } | ||
| 235 | |||
| 236 | CHECKED(uc_reg_read_batch(uc, uregs, tregs, 32)); | ||
| 237 | } | ||
| 238 | |||
| 239 | void ARM_Unicorn::LoadContext(const ThreadContext64& ctx) { | ||
| 240 | int uregs[32]; | ||
| 241 | void* tregs[32]; | ||
| 242 | |||
| 243 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_SP, &ctx.sp)); | ||
| 244 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_PC, &ctx.pc)); | ||
| 245 | CHECKED(uc_reg_write(uc, UC_ARM64_REG_NZCV, &ctx.pstate)); | ||
| 246 | |||
| 247 | for (int i = 0; i < 29; ++i) { | ||
| 248 | uregs[i] = UC_ARM64_REG_X0 + i; | ||
| 249 | tregs[i] = (void*)&ctx.cpu_registers[i]; | ||
| 250 | } | ||
| 251 | uregs[29] = UC_ARM64_REG_X29; | ||
| 252 | tregs[29] = (void*)&ctx.cpu_registers[29]; | ||
| 253 | uregs[30] = UC_ARM64_REG_X30; | ||
| 254 | tregs[30] = (void*)&ctx.cpu_registers[30]; | ||
| 255 | |||
| 256 | CHECKED(uc_reg_write_batch(uc, uregs, tregs, 31)); | ||
| 257 | |||
| 258 | for (auto i = 0; i < 32; ++i) { | ||
| 259 | uregs[i] = UC_ARM64_REG_Q0 + i; | ||
| 260 | tregs[i] = (void*)&ctx.vector_registers[i]; | ||
| 261 | } | ||
| 262 | |||
| 263 | CHECKED(uc_reg_write_batch(uc, uregs, tregs, 32)); | ||
| 264 | } | ||
| 265 | |||
| 266 | void ARM_Unicorn::PrepareReschedule() { | ||
| 267 | CHECKED(uc_emu_stop(uc)); | ||
| 268 | } | ||
| 269 | |||
| 270 | void ARM_Unicorn::ClearExclusiveState() {} | ||
| 271 | |||
| 272 | void ARM_Unicorn::ClearInstructionCache() {} | ||
| 273 | |||
| 274 | void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) { | ||
| 275 | last_bkpt = bkpt; | ||
| 276 | last_bkpt_hit = true; | ||
| 277 | } | ||
| 278 | |||
| 279 | void ARM_Unicorn::InterruptHook(uc_engine* uc, u32 int_no, void* user_data) { | ||
| 280 | u32 esr{}; | ||
| 281 | CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr)); | ||
| 282 | |||
| 283 | const auto ec = esr >> 26; | ||
| 284 | const auto iss = esr & 0xFFFFFF; | ||
| 285 | |||
| 286 | auto* const arm_instance = static_cast<ARM_Unicorn*>(user_data); | ||
| 287 | |||
| 288 | switch (ec) { | ||
| 289 | case 0x15: // SVC | ||
| 290 | Kernel::Svc::Call(arm_instance->system, iss); | ||
| 291 | break; | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | } // namespace Core | ||
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h deleted file mode 100644 index 810aff311..000000000 --- a/src/core/arm/unicorn/arm_unicorn.h +++ /dev/null | |||
| @@ -1,63 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <unicorn/unicorn.h> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/arm/arm_interface.h" | ||
| 10 | #include "core/gdbstub/gdbstub.h" | ||
| 11 | |||
| 12 | namespace Core { | ||
| 13 | |||
| 14 | class System; | ||
| 15 | |||
| 16 | class ARM_Unicorn final : public ARM_Interface { | ||
| 17 | public: | ||
| 18 | enum class Arch { | ||
| 19 | AArch32, // 32-bit ARM | ||
| 20 | AArch64, // 64-bit ARM | ||
| 21 | }; | ||
| 22 | |||
| 23 | explicit ARM_Unicorn(System& system, CPUInterrupts& interrupt_handlers, bool uses_wall_clock, | ||
| 24 | Arch architecture, std::size_t core_index); | ||
| 25 | ~ARM_Unicorn() override; | ||
| 26 | |||
| 27 | void SetPC(u64 pc) override; | ||
| 28 | u64 GetPC() const override; | ||
| 29 | u64 GetReg(int index) const override; | ||
| 30 | void SetReg(int index, u64 value) override; | ||
| 31 | u128 GetVectorReg(int index) const override; | ||
| 32 | void SetVectorReg(int index, u128 value) override; | ||
| 33 | u32 GetPSTATE() const override; | ||
| 34 | void SetPSTATE(u32 pstate) override; | ||
| 35 | VAddr GetTlsAddress() const override; | ||
| 36 | void SetTlsAddress(VAddr address) override; | ||
| 37 | void SetTPIDR_EL0(u64 value) override; | ||
| 38 | u64 GetTPIDR_EL0() const override; | ||
| 39 | void ChangeProcessorID(std::size_t new_core_id) override; | ||
| 40 | void PrepareReschedule() override; | ||
| 41 | void ClearExclusiveState() override; | ||
| 42 | void ExecuteInstructions(std::size_t num_instructions); | ||
| 43 | void Run() override; | ||
| 44 | void Step() override; | ||
| 45 | void ClearInstructionCache() override; | ||
| 46 | void PageTableChanged(Common::PageTable&, std::size_t) override {} | ||
| 47 | void RecordBreak(GDBStub::BreakpointAddress bkpt); | ||
| 48 | |||
| 49 | void SaveContext(ThreadContext32& ctx) override {} | ||
| 50 | void SaveContext(ThreadContext64& ctx) override; | ||
| 51 | void LoadContext(const ThreadContext32& ctx) override {} | ||
| 52 | void LoadContext(const ThreadContext64& ctx) override; | ||
| 53 | |||
| 54 | private: | ||
| 55 | static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data); | ||
| 56 | |||
| 57 | uc_engine* uc{}; | ||
| 58 | GDBStub::BreakpointAddress last_bkpt{}; | ||
| 59 | bool last_bkpt_hit = false; | ||
| 60 | std::size_t core_index; | ||
| 61 | }; | ||
| 62 | |||
| 63 | } // namespace Core | ||
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index c6bbdb080..6e04d025f 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp | |||
| @@ -2,30 +2,18 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/assert.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "common/spin_lock.h" | 5 | #include "common/spin_lock.h" |
| 8 | #include "core/arm/arm_interface.h" | ||
| 9 | #ifdef ARCHITECTURE_x86_64 | ||
| 10 | #include "core/arm/dynarmic/arm_dynarmic_32.h" | ||
| 11 | #include "core/arm/dynarmic/arm_dynarmic_64.h" | ||
| 12 | #endif | ||
| 13 | #include "core/arm/cpu_interrupt_handler.h" | 6 | #include "core/arm/cpu_interrupt_handler.h" |
| 14 | #include "core/arm/exclusive_monitor.h" | ||
| 15 | #include "core/arm/unicorn/arm_unicorn.h" | ||
| 16 | #include "core/core.h" | 7 | #include "core/core.h" |
| 17 | #include "core/hle/kernel/physical_core.h" | 8 | #include "core/hle/kernel/physical_core.h" |
| 18 | #include "core/hle/kernel/scheduler.h" | 9 | #include "core/hle/kernel/scheduler.h" |
| 19 | #include "core/hle/kernel/thread.h" | ||
| 20 | 10 | ||
| 21 | namespace Kernel { | 11 | namespace Kernel { |
| 22 | 12 | ||
| 23 | PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, | 13 | PhysicalCore::PhysicalCore(Core::System& system, std::size_t id, Kernel::Scheduler& scheduler, |
| 24 | Core::CPUInterruptHandler& interrupt_handler) | 14 | Core::CPUInterruptHandler& interrupt_handler) |
| 25 | : interrupt_handler{interrupt_handler}, core_index{id}, scheduler{scheduler} { | 15 | : interrupt_handler{interrupt_handler}, |
| 26 | 16 | core_index{id}, scheduler{scheduler}, guard{std::make_unique<Common::SpinLock>()} {} | |
| 27 | guard = std::make_unique<Common::SpinLock>(); | ||
| 28 | } | ||
| 29 | 17 | ||
| 30 | PhysicalCore::~PhysicalCore() = default; | 18 | PhysicalCore::~PhysicalCore() = default; |
| 31 | 19 | ||
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index d132aba34..da0cb26b6 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include "common/logging/log.h" | 13 | #include "common/logging/log.h" |
| 14 | #include "common/thread_queue_list.h" | 14 | #include "common/thread_queue_list.h" |
| 15 | #include "core/arm/arm_interface.h" | 15 | #include "core/arm/arm_interface.h" |
| 16 | #include "core/arm/unicorn/arm_unicorn.h" | ||
| 17 | #include "core/core.h" | 16 | #include "core/core.h" |
| 18 | #include "core/cpu_manager.h" | 17 | #include "core/cpu_manager.h" |
| 19 | #include "core/hardware_properties.h" | 18 | #include "core/hardware_properties.h" |
| @@ -217,8 +216,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy | |||
| 217 | } else { | 216 | } else { |
| 218 | thread->tls_address = 0; | 217 | thread->tls_address = 0; |
| 219 | } | 218 | } |
| 220 | // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used | 219 | |
| 221 | // to initialize the context | ||
| 222 | thread->arm_interface.reset(); | 220 | thread->arm_interface.reset(); |
| 223 | if ((type_flags & THREADTYPE_HLE) == 0) { | 221 | if ((type_flags & THREADTYPE_HLE) == 0) { |
| 224 | #ifdef ARCHITECTURE_x86_64 | 222 | #ifdef ARCHITECTURE_x86_64 |
| @@ -231,19 +229,10 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy | |||
| 231 | system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(), | 229 | system, kernel.Interrupts(), kernel.IsMulticore(), kernel.GetExclusiveMonitor(), |
| 232 | processor_id); | 230 | processor_id); |
| 233 | } | 231 | } |
| 234 | |||
| 235 | #else | 232 | #else |
| 236 | if (owner_process && !owner_process->Is64BitProcess()) { | 233 | #error Platform not supported yet. |
| 237 | thread->arm_interface = std::make_shared<Core::ARM_Unicorn>( | ||
| 238 | system, kernel.Interrupts(), kernel.IsMulticore(), ARM_Unicorn::Arch::AArch32, | ||
| 239 | processor_id); | ||
| 240 | } else { | ||
| 241 | thread->arm_interface = std::make_shared<Core::ARM_Unicorn>( | ||
| 242 | system, kernel.Interrupts(), kernel.IsMulticore(), ARM_Unicorn::Arch::AArch64, | ||
| 243 | processor_id); | ||
| 244 | } | ||
| 245 | LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); | ||
| 246 | #endif | 234 | #endif |
| 235 | |||
| 247 | ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top), | 236 | ResetThreadContext32(thread->context_32, static_cast<u32>(stack_top), |
| 248 | static_cast<u32>(entry_point), static_cast<u32>(arg)); | 237 | static_cast<u32>(entry_point), static_cast<u32>(arg)); |
| 249 | ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); | 238 | ResetThreadContext64(thread->context_64, stack_top, entry_point, arg); |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 4659e1f89..8abb74d56 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -264,11 +264,9 @@ endif() | |||
| 264 | if (MSVC) | 264 | if (MSVC) |
| 265 | include(CopyYuzuQt5Deps) | 265 | include(CopyYuzuQt5Deps) |
| 266 | include(CopyYuzuSDLDeps) | 266 | include(CopyYuzuSDLDeps) |
| 267 | include(CopyYuzuUnicornDeps) | ||
| 268 | include(CopyYuzuFFmpegDeps) | 267 | include(CopyYuzuFFmpegDeps) |
| 269 | copy_yuzu_Qt5_deps(yuzu) | 268 | copy_yuzu_Qt5_deps(yuzu) |
| 270 | copy_yuzu_SDL_deps(yuzu) | 269 | copy_yuzu_SDL_deps(yuzu) |
| 271 | copy_yuzu_unicorn_deps(yuzu) | ||
| 272 | copy_yuzu_FFmpeg_deps(yuzu) | 270 | copy_yuzu_FFmpeg_deps(yuzu) |
| 273 | endif() | 271 | endif() |
| 274 | 272 | ||
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index a15719a0f..57f9916f6 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt | |||
| @@ -39,7 +39,5 @@ endif() | |||
| 39 | 39 | ||
| 40 | if (MSVC) | 40 | if (MSVC) |
| 41 | include(CopyYuzuSDLDeps) | 41 | include(CopyYuzuSDLDeps) |
| 42 | include(CopyYuzuUnicornDeps) | ||
| 43 | copy_yuzu_SDL_deps(yuzu-cmd) | 42 | copy_yuzu_SDL_deps(yuzu-cmd) |
| 44 | copy_yuzu_unicorn_deps(yuzu-cmd) | ||
| 45 | endif() | 43 | endif() |
diff --git a/src/yuzu_tester/CMakeLists.txt b/src/yuzu_tester/CMakeLists.txt index 06c2ee011..d8a2a1511 100644 --- a/src/yuzu_tester/CMakeLists.txt +++ b/src/yuzu_tester/CMakeLists.txt | |||
| @@ -28,7 +28,5 @@ endif() | |||
| 28 | 28 | ||
| 29 | if (MSVC) | 29 | if (MSVC) |
| 30 | include(CopyYuzuSDLDeps) | 30 | include(CopyYuzuSDLDeps) |
| 31 | include(CopyYuzuUnicornDeps) | ||
| 32 | copy_yuzu_SDL_deps(yuzu-tester) | 31 | copy_yuzu_SDL_deps(yuzu-tester) |
| 33 | copy_yuzu_unicorn_deps(yuzu-tester) | ||
| 34 | endif() | 32 | endif() |