Compare commits
117 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06d2e1bd23 | ||
|
|
687a17acae | ||
|
|
4c07dde472 | ||
|
|
ee024eb0a2 | ||
|
|
1bcc233245 | ||
|
|
425a78ec1b | ||
|
|
add8d40f3f | ||
|
|
bba785d643 | ||
|
|
af871f8966 | ||
|
|
d904b0db58 | ||
|
|
defaaf4519 | ||
|
|
602cd3886d | ||
|
|
9d6339b887 | ||
|
|
07cfab72e0 | ||
|
|
3315af8f09 | ||
|
|
557b2496d7 | ||
|
|
96f446ff65 | ||
|
|
425b3923d2 | ||
|
|
096be16636 | ||
|
|
1e662e6e9a | ||
|
|
1a4e429d9e | ||
|
|
c3e22a2f6c | ||
|
|
6cccbf0eb3 | ||
|
|
ff883cc563 | ||
|
|
de7aa3106a | ||
|
|
386df282a3 | ||
|
|
e75aba3ed0 | ||
|
|
023aef053c | ||
|
|
2dafd0d287 | ||
|
|
c8a094e164 | ||
|
|
0b6da0c1ab | ||
|
|
dd62f125c3 | ||
|
|
7b219539a9 | ||
|
|
c457f34eb2 | ||
|
|
d9ca9d3472 | ||
|
|
0f363d37e6 | ||
|
|
c3005ee4d1 | ||
|
|
deec326ddf | ||
|
|
1d49680613 | ||
|
|
e27accc15d | ||
|
|
de646cef2d | ||
|
|
e1ee8f4657 | ||
|
|
d80991977a | ||
|
|
c85d04ebe1 | ||
|
|
8f13499bb8 | ||
|
|
952dba9c2b | ||
|
|
1a5098e8b8 | ||
|
|
6b4f37b544 | ||
|
|
5e46a9bb2b | ||
|
|
cb3ab6ec77 | ||
|
|
da3e13fea5 | ||
|
|
3a409d5c8f | ||
|
|
0e7749a500 | ||
|
|
59575d5cae | ||
|
|
463356f0a7 | ||
|
|
195b4b5129 | ||
|
|
378cea2ae2 | ||
|
|
c7c180fdf1 | ||
|
|
2ff1cebfbe | ||
|
|
b5bc94bce0 | ||
|
|
da21545a77 | ||
|
|
be0e14ab3e | ||
|
|
4ca5f0c145 | ||
|
|
22465c8722 | ||
|
|
ed788742bf | ||
|
|
cf0daed0b8 | ||
|
|
32eb620ef4 | ||
|
|
01b3bf119e | ||
|
|
3ebe56524c | ||
|
|
138c03d565 | ||
|
|
5d38bb36c3 | ||
|
|
36dc44fb22 | ||
|
|
e710a1b989 | ||
|
|
6a36ffb86c | ||
|
|
18507b09b2 | ||
|
|
73c0ef7453 | ||
|
|
4497eb4528 | ||
|
|
c81ed5eb33 | ||
|
|
62a8c61e36 | ||
|
|
3d19102c48 | ||
|
|
14069e6ec4 | ||
|
|
b16c89bf65 | ||
|
|
01f379baa7 | ||
|
|
501d1cc33d | ||
|
|
94a6515b71 | ||
|
|
15318b6601 | ||
|
|
33eba9b96e | ||
|
|
ed296e47f1 | ||
|
|
2b3ee30a46 | ||
|
|
e50188374f | ||
|
|
ee08c39b72 | ||
|
|
d3e63e4220 | ||
|
|
e2f06dbc17 | ||
|
|
b17763e3d4 | ||
|
|
5fcf8d530a | ||
|
|
6f22471a72 | ||
|
|
c65ac49238 | ||
|
|
c7452bab90 | ||
|
|
f2b4b668e3 | ||
|
|
0568346cc3 | ||
|
|
8bff9c9152 | ||
|
|
10955d72ef | ||
|
|
66388f7576 | ||
|
|
7fa32af1c7 | ||
|
|
30d2ba9de3 | ||
|
|
1998a16557 | ||
|
|
7172ff4d9a | ||
|
|
b2386fc712 | ||
|
|
b588cbcb1d | ||
|
|
1c98f3a9b3 | ||
|
|
60d650cc4e | ||
|
|
d92636d424 | ||
|
|
d05dc3f4dd | ||
|
|
30cb98f874 | ||
|
|
d15cadd760 | ||
|
|
9a9d33a741 | ||
|
|
0a8d13801a |
10
.travis.yml
10
.travis.yml
@@ -6,8 +6,12 @@ matrix:
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
- sourceline: 'deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main'
|
||||
packages:
|
||||
- clang-format-3.9
|
||||
- clang-format-6.0
|
||||
script: "./.travis/clang-format/script.sh"
|
||||
- os: linux
|
||||
env: NAME="linux build"
|
||||
@@ -24,7 +28,7 @@ matrix:
|
||||
- os: osx
|
||||
env: NAME="macos build"
|
||||
sudo: false
|
||||
osx_image: xcode7.3
|
||||
osx_image: xcode9.2
|
||||
install: "./.travis/macos/deps.sh"
|
||||
script: "./.travis/macos/build.sh"
|
||||
after_success: "./.travis/macos/upload.sh"
|
||||
@@ -32,7 +36,7 @@ matrix:
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: IuTT8DjxzNgOtaEsyOpz1JaSmtDtHSsWZnJKmSBwXAzgP2ZU4Ja3/q0z5PwbC5Ql7kuFahuYTE5oi7lbJBuu2P3y1Wj2zvFozGUkA3JUvEXDNOPS9QTJ1EYd6O+wenZoj7d/Pn+ZeIgyEafnnZsGBb8lMQnV9MfIHgYlZQ5EyF3n4XikT2h1UbDBYx74ciXZIxFEulx68kDr9Q4/U+zIYQmYv2N+lgXSLDkFrCJ046gRcujPYGPqE6jVw0kKni80CTTpuDF5prU8yIBeiffjkJ3Qx1a17G07eZ4r83P4XUOlaHbRBmA/8ywZvLF2Gep3wGKfSFgMWbPxBJk5ZSYcOOAgMsEcg0+gBK9gLTwO4pbmc2GvqP21yRQBzgtbFoEtAHLu5lVPBkZU7kZuRMJtRdqvFIwOLhpnRS8IknFOD5vjtaFiNdGWaK9ePdsGvplijnXcPafkumakc4+eVEiXb6/KzdX1zXdur5tuUPFytm0Oy6IJcGIf8FHXGvUlmWsnPzwfusij9JgeQOP+uegc9PdBfL+h7L5rk+ilELt3cXD5K7wgov/4hkl5istNJ2bm0IioIstWss8QQQTkyscGoeh/oXmUpOL4FdsTvsWhDR3QKeq8nSzgDkqLe0iSbplQGnC7o7ytNbldmxJvf3nylwglA8w3HlqLHtZLkUOcuQ0=
|
||||
secure: ElsIAlbvVXBNKsP31nVPysh+mf0GQA4DiL/y5iJeQxKQYR6iRoNo+RfzOBmdswdo0bE/PGeBAlfzCkp15gjhWf6Je0N6dRpczmcmLq6SSQFn1Mpq00xMJB2AgQIlaHs6KFgoUA173EBKbPwgU/NubTFpJFm/Wa+NcSWAHQXKL9KT2M3qKpxNkPl3mKEVsbch4REP+T/46vsa+ikw0VE0kIs6V93LqUQZpI2F0Dhihx8Cxr5iedkE1QsNK+QSX9iItMHbfek9OH980gP7L3lkZltyAA1Pk0c37OAgz2PwczwNKwCT8jg9PMzdcKmWouvLyAkZFuA806ElzwHY3oEd91Zm6+Bk5n24yBKZ9027AZzw38NK2Z2m9Akb8+ar8PdsKU6N5pDutX9qSLayr0oMgJ0s7/xnGBGdL3gfkPCFc50xO/2DxlsOR+zAhPNM9Y76hhGy6A7/40+9uzrJvd4nAuDvIXRzi2Yl2L7mKBE4suMKbFLtk2LlgM0qY5JMVTQ8NliaEtqopfPur2KWFVJUpWDNLtNX8xGqhfwg7cLjIiGmnxSaJBTDuZI6dpEjkWkU0n1xYhGqEqit8DbehYzazozMJ+Vsr8hku7jGlUtlw+U6HG1e19O2y4aGeSwYPROcCNz+BLwmVM8oZE3Roy3qoaa2yiFf+sy6rUHznrhsfEM=
|
||||
file_glob: true
|
||||
file: "artifacts/*"
|
||||
skip_cleanup: true
|
||||
|
||||
@@ -7,7 +7,7 @@ if grep -nr '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .travis*
|
||||
fi
|
||||
|
||||
# Default clang-format points to default 3.5 version one
|
||||
CLANG_FORMAT=clang-format-3.9
|
||||
CLANG_FORMAT=clang-format-6.0
|
||||
$CLANG_FORMAT --version
|
||||
|
||||
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
|
||||
|
||||
@@ -3,14 +3,19 @@ cmake_minimum_required(VERSION 3.6)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
||||
include(DownloadExternals)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
project(yuzu)
|
||||
|
||||
# Set bundled sdl2/qt as dependent options.
|
||||
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
|
||||
option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON)
|
||||
|
||||
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||
message(STATUS "Copying pre-commit hook")
|
||||
@@ -54,15 +59,18 @@ function(detect_architecture symbol arch)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if (MSVC)
|
||||
detect_architecture("_M_AMD64" x86_64)
|
||||
detect_architecture("_M_IX86" x86)
|
||||
detect_architecture("_M_ARM" ARM)
|
||||
else()
|
||||
detect_architecture("__x86_64__" x86_64)
|
||||
detect_architecture("__i386__" x86)
|
||||
detect_architecture("__arm__" ARM)
|
||||
if (NOT ENABLE_GENERIC)
|
||||
if (MSVC)
|
||||
detect_architecture("_M_AMD64" x86_64)
|
||||
detect_architecture("_M_IX86" x86)
|
||||
detect_architecture("_M_ARM" ARM)
|
||||
else()
|
||||
detect_architecture("__x86_64__" x86_64)
|
||||
detect_architecture("__i386__" x86)
|
||||
detect_architecture("__arm__" ARM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED ARCHITECTURE)
|
||||
set(ARCHITECTURE "GENERIC")
|
||||
set(ARCHITECTURE_GENERIC 1)
|
||||
@@ -203,8 +211,7 @@ else()
|
||||
endif()
|
||||
|
||||
# If unicorn isn't found, msvc -> download bundled unicorn; everyone else -> build external
|
||||
find_package(Unicorn QUIET)
|
||||
if (NOT UNICORN_FOUND)
|
||||
if (YUZU_USE_BUNDLED_UNICORN)
|
||||
if (MSVC)
|
||||
message(STATUS "unicorn not found, falling back to bundled")
|
||||
# Detect toolchain and platform
|
||||
@@ -243,7 +250,7 @@ if (NOT UNICORN_FOUND)
|
||||
find_package(PythonInterp 2.7 REQUIRED)
|
||||
|
||||
add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY}
|
||||
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh
|
||||
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh macos-universal-no
|
||||
WORKING_DIRECTORY ${UNICORN_PREFIX}
|
||||
)
|
||||
# ALL makes this custom target build every time
|
||||
@@ -253,6 +260,8 @@ if (NOT UNICORN_FOUND)
|
||||
)
|
||||
unset(UNICORN_LIB_NAME)
|
||||
endif()
|
||||
else()
|
||||
find_package(Unicorn REQUIRED)
|
||||
endif()
|
||||
|
||||
if (UNICORN_FOUND)
|
||||
@@ -316,6 +325,53 @@ if (UNIX OR MINGW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Setup a custom clang-format target (if clang-format can be found) that will run
|
||||
# against all the src files. This should be used before making a pull request.
|
||||
# =======================================================================
|
||||
|
||||
set(CLANG_FORMAT_POSTFIX "-6.0")
|
||||
find_program(CLANG_FORMAT
|
||||
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
||||
clang-format
|
||||
PATHS ${CMAKE_BINARY_DIR}/externals)
|
||||
# if find_program doesn't find it, try to download from externals
|
||||
if (NOT CLANG_FORMAT)
|
||||
if (WIN32)
|
||||
message(STATUS "Clang format not found! Downloading...")
|
||||
set(CLANG_FORMAT "${CMAKE_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe")
|
||||
file(DOWNLOAD
|
||||
https://github.com/yuzu-emu/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe
|
||||
"${CLANG_FORMAT}" SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_SUCCESS)
|
||||
if (NOT DOWNLOAD_SUCCESS EQUAL 0)
|
||||
message(WARNING "Could not download clang format! Disabling the clang format target")
|
||||
file(REMOVE ${CLANG_FORMAT})
|
||||
unset(CLANG_FORMAT)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Clang format not found! Disabling the clang format target")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CLANG_FORMAT)
|
||||
set(SRCS ${CMAKE_SOURCE_DIR}/src)
|
||||
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
|
||||
if (WIN32)
|
||||
add_custom_target(clang-format
|
||||
COMMAND powershell.exe -Command "${CLANG_FORMAT} -i @(Get-ChildItem -Recurse ${SRCS}/* -Include \'*.h\', \'*.cpp\')"
|
||||
COMMENT ${CCOMMENT})
|
||||
elseif(MINGW)
|
||||
add_custom_target(clang-format
|
||||
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp | xargs `cygpath -u ${CLANG_FORMAT}` -i
|
||||
COMMENT ${CCOMMENT})
|
||||
else()
|
||||
add_custom_target(clang-format
|
||||
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp | xargs ${CLANG_FORMAT} -i
|
||||
COMMENT ${CCOMMENT})
|
||||
endif()
|
||||
unset(SRCS)
|
||||
unset(CCOMMENT)
|
||||
endif()
|
||||
|
||||
# Include source code
|
||||
# ===================
|
||||
@@ -323,12 +379,14 @@ endif()
|
||||
# This function should be passed a list of all files in a target. It will automatically generate
|
||||
# file groups following the directory hierarchy, so that the layout of the files in IDEs matches the
|
||||
# one in the filesystem.
|
||||
function(create_directory_groups)
|
||||
function(create_target_directory_groups target_name)
|
||||
# Place any files that aren't in the source list in a separate group so that they don't get in
|
||||
# the way.
|
||||
source_group("Other Files" REGULAR_EXPRESSION ".")
|
||||
|
||||
foreach(file_name ${ARGV})
|
||||
get_target_property(target_sources "${target_name}" SOURCES)
|
||||
|
||||
foreach(file_name IN LISTS target_sources)
|
||||
get_filename_component(dir_name "${file_name}" PATH)
|
||||
# Group names use '\' as a separator even though the entire rest of CMake uses '/'...
|
||||
string(REPLACE "/" "\\" group_name "${dir_name}")
|
||||
|
||||
@@ -5,7 +5,16 @@
|
||||
If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside yuzu) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
|
||||
|
||||
# Contributing
|
||||
yuzu is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible:
|
||||
yuzu is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible.
|
||||
|
||||
# Using clang format (version 6.0)
|
||||
When generating the native build script for your toolset, cmake will try to find the correct version of clang format (or will download it on windows). Before running cmake, please install clang format version 6.0 for your platform as follows:
|
||||
|
||||
* Windows: do nothing; cmake will download a pre built binary for MSVC and MINGW. MSVC users can additionally install a clang format Visual Studio extension to add features like format on save.
|
||||
* OSX: run `brew install clang-format`.
|
||||
* Linux: use your package manager to get an appropriate binary.
|
||||
|
||||
If clang format is found, then cmake will add a custom build target that can be run at any time to run clang format against *all* source files and update the formatting in them. This should be used before making a pull request so that the reviewers can spend more time reviewing the code instead of having to worry about minor style violations. On MSVC, you can run clang format by building the clang-format project in the solution. On OSX, you can either use the Makefile target `make clang-format` or by building the clang-format target in XCode. For Makefile builds, you can use the clang-format target with `make clang-format`
|
||||
|
||||
### General Rules
|
||||
* A lot of code was taken from other projects (e.g. Citra, Dolphin, PPSSPP, Gekko). In general, when editing other people's code, follow the style of the module you're in (or better yet, fix the style if it drastically differs from our guide).
|
||||
|
||||
15
appveyor.yml
15
appveyor.yml
@@ -13,8 +13,8 @@ environment:
|
||||
# Tell msys2 to inherit the current directory when starting the shell
|
||||
CHERE_INVOKING: 1
|
||||
matrix:
|
||||
- BUILD_TYPE: mingw
|
||||
- BUILD_TYPE: msvc
|
||||
- BUILD_TYPE: mingw
|
||||
|
||||
platform:
|
||||
- x64
|
||||
@@ -80,12 +80,19 @@ after_build:
|
||||
$env:BUILD_SYMBOLS = $MSVC_BUILD_PDB
|
||||
$env:BUILD_UPDATE = $MSVC_SEVENZIP
|
||||
|
||||
$BUILD_DIR = ".\msvc_build\bin\Release"
|
||||
|
||||
# Make a debug symbol upload
|
||||
mkdir pdb
|
||||
Get-ChildItem ".\msvc_build\bin\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
|
||||
Get-ChildItem "$BUILD_DIR\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
|
||||
7z a -tzip $MSVC_BUILD_PDB .\pdb\*.pdb
|
||||
rm "$BUILD_DIR\*.pdb"
|
||||
|
||||
mkdir $RELEASE_DIST
|
||||
Get-ChildItem ".\msvc_build\bin\" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
# get rid of extra exes by copying everything over, then deleting all the exes, then copying just the exes we want
|
||||
Copy-Item "$BUILD_DIR\*" -Destination $RELEASE_DIST -Recurse
|
||||
rm "$RELEASE_DIST\*.exe"
|
||||
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
Copy-Item .\license.txt -Destination $RELEASE_DIST
|
||||
Copy-Item .\README.md -Destination $RELEASE_DIST
|
||||
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_DIST\*
|
||||
@@ -163,7 +170,7 @@ deploy:
|
||||
provider: GitHub
|
||||
release: $(appveyor_repo_tag_name)
|
||||
auth_token:
|
||||
secure: "argb6oi2TYLB4wDy+HoCC8PuGAmsnocSk12CQ5614XAPO+NVPndlkLv1utnDFfg2"
|
||||
secure: QqePPnXbkzmXct5c8hZ2X5AbsthbI6cS1Sr+VBzcD8oUOIjfWJJKXVAQGUbQAbb0
|
||||
artifact: update,build
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
2
externals/catch
vendored
2
externals/catch
vendored
Submodule externals/catch updated: 3dcc923351...cd76f5730c
14
externals/getopt/CMakeLists.txt
vendored
14
externals/getopt/CMakeLists.txt
vendored
@@ -1,11 +1,9 @@
|
||||
set(SRCS
|
||||
getopt.c
|
||||
)
|
||||
set(HEADERS
|
||||
getopt.h
|
||||
)
|
||||
add_library(getopt
|
||||
getopt.c
|
||||
getopt.h
|
||||
)
|
||||
|
||||
create_target_directory_groups(getopt)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(getopt ${SRCS} ${HEADERS})
|
||||
target_compile_definitions(getopt PUBLIC STATIC_GETOPT)
|
||||
target_include_directories(getopt INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
15
externals/glad/CMakeLists.txt
vendored
15
externals/glad/CMakeLists.txt
vendored
@@ -1,13 +1,10 @@
|
||||
set(SRCS
|
||||
src/glad.c
|
||||
)
|
||||
set(HEADERS
|
||||
include/KHR/khrplatform.h
|
||||
include/glad/glad.h
|
||||
)
|
||||
add_library(glad STATIC
|
||||
src/glad.c
|
||||
include/KHR/khrplatform.h
|
||||
include/glad/glad.h
|
||||
)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(glad STATIC ${SRCS} ${HEADERS})
|
||||
create_target_directory_groups(glad)
|
||||
target_include_directories(glad PUBLIC "include/")
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
|
||||
17
externals/inih/CMakeLists.txt
vendored
17
externals/inih/CMakeLists.txt
vendored
@@ -1,12 +1,9 @@
|
||||
set(SRCS
|
||||
inih/ini.c
|
||||
inih/cpp/INIReader.cpp
|
||||
)
|
||||
set(HEADERS
|
||||
inih/ini.h
|
||||
inih/cpp/INIReader.h
|
||||
)
|
||||
add_library(inih
|
||||
inih/ini.c
|
||||
inih/ini.h
|
||||
inih/cpp/INIReader.cpp
|
||||
inih/cpp/INIReader.h
|
||||
)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(inih ${SRCS} ${HEADERS})
|
||||
create_target_directory_groups(inih)
|
||||
target_include_directories(inih INTERFACE .)
|
||||
|
||||
@@ -17,85 +17,79 @@ if ($ENV{CI})
|
||||
string(SUBSTRING ${WORD} 1 -1 REMAINDER)
|
||||
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
|
||||
# this leaves a trailing space on the last word, but we actually want that
|
||||
# because of how its styled in the title bar.
|
||||
# because of how it's styled in the title bar.
|
||||
set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER} ")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY)
|
||||
|
||||
set(SRCS
|
||||
break_points.cpp
|
||||
file_util.cpp
|
||||
hash.cpp
|
||||
logging/filter.cpp
|
||||
logging/text_formatter.cpp
|
||||
logging/backend.cpp
|
||||
memory_util.cpp
|
||||
microprofile.cpp
|
||||
misc.cpp
|
||||
param_package.cpp
|
||||
scm_rev.cpp
|
||||
string_util.cpp
|
||||
telemetry.cpp
|
||||
thread.cpp
|
||||
timer.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
alignment.h
|
||||
assert.h
|
||||
bit_field.h
|
||||
bit_set.h
|
||||
break_points.h
|
||||
chunk_file.h
|
||||
code_block.h
|
||||
color.h
|
||||
common_funcs.h
|
||||
common_paths.h
|
||||
common_types.h
|
||||
file_util.h
|
||||
hash.h
|
||||
linear_disk_cache.h
|
||||
logging/text_formatter.h
|
||||
logging/filter.h
|
||||
logging/log.h
|
||||
logging/backend.h
|
||||
math_util.h
|
||||
memory_util.h
|
||||
microprofile.h
|
||||
microprofileui.h
|
||||
param_package.h
|
||||
platform.h
|
||||
quaternion.h
|
||||
scm_rev.h
|
||||
scope_exit.h
|
||||
string_util.h
|
||||
swap.h
|
||||
synchronized_wrapper.h
|
||||
telemetry.h
|
||||
thread.h
|
||||
thread_queue_list.h
|
||||
threadsafe_queue.h
|
||||
timer.h
|
||||
vector_math.h
|
||||
)
|
||||
add_library(common STATIC
|
||||
alignment.h
|
||||
assert.h
|
||||
bit_field.h
|
||||
bit_set.h
|
||||
break_points.cpp
|
||||
break_points.h
|
||||
chunk_file.h
|
||||
code_block.h
|
||||
color.h
|
||||
common_funcs.h
|
||||
common_paths.h
|
||||
common_types.h
|
||||
file_util.cpp
|
||||
file_util.h
|
||||
hash.cpp
|
||||
hash.h
|
||||
linear_disk_cache.h
|
||||
logging/backend.cpp
|
||||
logging/backend.h
|
||||
logging/filter.cpp
|
||||
logging/filter.h
|
||||
logging/log.h
|
||||
logging/text_formatter.cpp
|
||||
logging/text_formatter.h
|
||||
math_util.h
|
||||
memory_util.cpp
|
||||
memory_util.h
|
||||
microprofile.cpp
|
||||
microprofile.h
|
||||
microprofileui.h
|
||||
misc.cpp
|
||||
param_package.cpp
|
||||
param_package.h
|
||||
platform.h
|
||||
quaternion.h
|
||||
scm_rev.cpp
|
||||
scm_rev.h
|
||||
scope_exit.h
|
||||
string_util.cpp
|
||||
string_util.h
|
||||
swap.h
|
||||
synchronized_wrapper.h
|
||||
telemetry.cpp
|
||||
telemetry.h
|
||||
thread.cpp
|
||||
thread.h
|
||||
thread_queue_list.h
|
||||
threadsafe_queue.h
|
||||
timer.cpp
|
||||
timer.h
|
||||
vector_math.h
|
||||
)
|
||||
|
||||
if(ARCHITECTURE_x86_64)
|
||||
set(SRCS ${SRCS}
|
||||
target_sources(common
|
||||
PRIVATE
|
||||
x64/cpu_detect.cpp
|
||||
)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
x64/cpu_detect.h
|
||||
x64/xbyak_abi.h
|
||||
x64/xbyak_util.h
|
||||
)
|
||||
)
|
||||
endif()
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
create_target_directory_groups(common)
|
||||
|
||||
add_library(common STATIC ${SRCS} ${HEADERS})
|
||||
target_link_libraries(common PUBLIC Boost::boost microprofile)
|
||||
if (ARCHITECTURE_x86_64)
|
||||
target_link_libraries(common PRIVATE xbyak)
|
||||
|
||||
@@ -236,7 +236,7 @@ public:
|
||||
IntTy m_val;
|
||||
};
|
||||
|
||||
} // Common
|
||||
} // namespace Common
|
||||
|
||||
typedef Common::BitSet<u8> BitSet8;
|
||||
typedef Common::BitSet<u16> BitSet16;
|
||||
|
||||
@@ -607,8 +607,9 @@ public:
|
||||
u32 cookie = arbitraryNumber;
|
||||
Do(cookie);
|
||||
if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) {
|
||||
LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
|
||||
"Aborting savestate load...",
|
||||
LOG_ERROR(Common,
|
||||
"After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
|
||||
"Aborting savestate load...",
|
||||
prevName, cookie, cookie, arbitraryNumber, arbitraryNumber);
|
||||
SetError(ERROR_FAILURE);
|
||||
}
|
||||
|
||||
@@ -256,4 +256,4 @@ inline void EncodeX24S8(u8 stencil, u8* bytes) {
|
||||
bytes[3] = stencil;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Color
|
||||
|
||||
@@ -873,20 +873,19 @@ bool IOFile::Flush() {
|
||||
}
|
||||
|
||||
bool IOFile::Resize(u64 size) {
|
||||
if (!IsOpen() ||
|
||||
0 !=
|
||||
if (!IsOpen() || 0 !=
|
||||
#ifdef _WIN32
|
||||
// ector: _chsize sucks, not 64-bit safe
|
||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||
_chsize_s(_fileno(m_file), size)
|
||||
// ector: _chsize sucks, not 64-bit safe
|
||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||
_chsize_s(_fileno(m_file), size)
|
||||
#else
|
||||
// TODO: handle 64bit and growing
|
||||
ftruncate(fileno(m_file), size)
|
||||
// TODO: handle 64bit and growing
|
||||
ftruncate(fileno(m_file), size)
|
||||
#endif
|
||||
)
|
||||
)
|
||||
m_good = false;
|
||||
|
||||
return m_good;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace FileUtil
|
||||
|
||||
@@ -253,7 +253,7 @@ private:
|
||||
bool m_good = true;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace FileUtil
|
||||
|
||||
// To deal with Windows being dumb at unicode:
|
||||
template <typename T>
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Log {
|
||||
SUB(HW, LCD) \
|
||||
SUB(HW, GPU) \
|
||||
SUB(HW, AES) \
|
||||
CLS(IPC) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Software) \
|
||||
@@ -91,8 +92,8 @@ const char* GetLevelName(Level log_level) {
|
||||
|
||||
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
|
||||
const char* function, const char* format, va_list args) {
|
||||
using std::chrono::steady_clock;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::steady_clock;
|
||||
|
||||
static steady_clock::time_point time_origin = steady_clock::now();
|
||||
|
||||
@@ -131,4 +132,4 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
|
||||
|
||||
PrintColoredMessage(entry);
|
||||
}
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -47,4 +47,4 @@ Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsign
|
||||
const char* function, const char* format, va_list args);
|
||||
|
||||
void SetFilter(Filter* filter);
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -94,4 +94,4 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
|
||||
bool Filter::CheckMessage(Class log_class, Level level) const {
|
||||
return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]);
|
||||
}
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -50,4 +50,4 @@ public:
|
||||
private:
|
||||
std::array<Level, (size_t)Class::Count> class_levels;
|
||||
};
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -60,6 +60,7 @@ enum class Class : ClassType {
|
||||
HW_LCD, ///< LCD register emulation
|
||||
HW_GPU, ///< GPU control emulation
|
||||
HW_AES, ///< AES engine emulation
|
||||
IPC, ///< IPC interface
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Emulator video output and hardware acceleration
|
||||
Render_Software, ///< Software renderer backend
|
||||
|
||||
@@ -129,4 +129,4 @@ void PrintColoredMessage(const Entry& entry) {
|
||||
#undef ESC
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -28,4 +28,4 @@ void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len);
|
||||
void PrintMessage(const Entry& entry);
|
||||
/// Prints the same message as `PrintMessage`, but colored acoording to the severity level.
|
||||
void PrintColoredMessage(const Entry& entry);
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -40,11 +40,12 @@ void* AllocateExecutableMemory(size_t size, bool low) {
|
||||
if (low && (!map_hint))
|
||||
map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */
|
||||
#endif
|
||||
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE
|
||||
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE
|
||||
#if defined(ARCHITECTURE_X64) && defined(MAP_32BIT)
|
||||
| (low ? MAP_32BIT : 0)
|
||||
| (low ? MAP_32BIT : 0)
|
||||
#endif
|
||||
,
|
||||
,
|
||||
-1, 0);
|
||||
#endif /* defined(_WIN32) */
|
||||
|
||||
|
||||
@@ -46,4 +46,4 @@ inline Quaternion<float> MakeQuaternion(const Math::Vec3<float>& axis, float ang
|
||||
return {axis * std::sin(angle / 2), std::cos(angle / 2)};
|
||||
}
|
||||
|
||||
} // namspace Math
|
||||
} // namespace Math
|
||||
|
||||
@@ -12,4 +12,4 @@ extern const char g_scm_desc[];
|
||||
extern const char g_build_name[];
|
||||
extern const char g_build_date[];
|
||||
|
||||
} // namespace
|
||||
} // namespace Common
|
||||
|
||||
@@ -22,7 +22,7 @@ template <typename Func>
|
||||
ScopeExitHelper<Func> ScopeExit(Func&& func) {
|
||||
return ScopeExitHelper<Func>(std::move(func));
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* This macro allows you to conveniently specify a block of code that will run on scope exit. Handy
|
||||
|
||||
@@ -202,7 +202,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||
#ifdef _WIN32
|
||||
":"
|
||||
#endif
|
||||
);
|
||||
);
|
||||
if (std::string::npos == dir_end)
|
||||
dir_end = 0;
|
||||
else
|
||||
@@ -462,4 +462,4 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_l
|
||||
|
||||
return std::string(buffer, len);
|
||||
}
|
||||
}
|
||||
} // namespace Common
|
||||
|
||||
@@ -134,4 +134,4 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) {
|
||||
* NUL-terminated then the string ends at max_len characters.
|
||||
*/
|
||||
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len);
|
||||
}
|
||||
} // namespace Common
|
||||
|
||||
@@ -53,10 +53,10 @@ template <typename T>
|
||||
class Field : public FieldInterface {
|
||||
public:
|
||||
Field(FieldType type, std::string name, const T& value)
|
||||
: type(type), name(std::move(name)), value(value) {}
|
||||
: name(std::move(name)), type(type), value(value) {}
|
||||
|
||||
Field(FieldType type, std::string name, T&& value)
|
||||
: type(type), name(std::move(name)), value(std::move(value)) {}
|
||||
: name(std::move(name)), type(type), value(std::move(value)) {}
|
||||
|
||||
Field(const Field& other) : Field(other.type, other.name, other.value) {}
|
||||
|
||||
|
||||
@@ -158,4 +158,4 @@ private:
|
||||
std::array<Queue, NUM_QUEUES> queues;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Common
|
||||
|
||||
@@ -60,20 +60,41 @@ const Xbyak::Reg ABI_PARAM4 = Xbyak::util::r9;
|
||||
|
||||
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rcx, Xbyak::util::rdx, Xbyak::util::r8, Xbyak::util::r9, Xbyak::util::r10,
|
||||
Xbyak::util::rcx,
|
||||
Xbyak::util::rdx,
|
||||
Xbyak::util::r8,
|
||||
Xbyak::util::r9,
|
||||
Xbyak::util::r10,
|
||||
Xbyak::util::r11,
|
||||
// XMMs
|
||||
Xbyak::util::xmm0, Xbyak::util::xmm1, Xbyak::util::xmm2, Xbyak::util::xmm3, Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm0,
|
||||
Xbyak::util::xmm1,
|
||||
Xbyak::util::xmm2,
|
||||
Xbyak::util::xmm3,
|
||||
Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm5,
|
||||
});
|
||||
|
||||
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rbx, Xbyak::util::rsi, Xbyak::util::rdi, Xbyak::util::rbp, Xbyak::util::r12,
|
||||
Xbyak::util::r13, Xbyak::util::r14, Xbyak::util::r15,
|
||||
Xbyak::util::rbx,
|
||||
Xbyak::util::rsi,
|
||||
Xbyak::util::rdi,
|
||||
Xbyak::util::rbp,
|
||||
Xbyak::util::r12,
|
||||
Xbyak::util::r13,
|
||||
Xbyak::util::r14,
|
||||
Xbyak::util::r15,
|
||||
// XMMs
|
||||
Xbyak::util::xmm6, Xbyak::util::xmm7, Xbyak::util::xmm8, Xbyak::util::xmm9, Xbyak::util::xmm10,
|
||||
Xbyak::util::xmm11, Xbyak::util::xmm12, Xbyak::util::xmm13, Xbyak::util::xmm14,
|
||||
Xbyak::util::xmm6,
|
||||
Xbyak::util::xmm7,
|
||||
Xbyak::util::xmm8,
|
||||
Xbyak::util::xmm9,
|
||||
Xbyak::util::xmm10,
|
||||
Xbyak::util::xmm11,
|
||||
Xbyak::util::xmm12,
|
||||
Xbyak::util::xmm13,
|
||||
Xbyak::util::xmm14,
|
||||
Xbyak::util::xmm15,
|
||||
});
|
||||
|
||||
@@ -90,18 +111,40 @@ const Xbyak::Reg ABI_PARAM4 = Xbyak::util::rcx;
|
||||
|
||||
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rcx, Xbyak::util::rdx, Xbyak::util::rdi, Xbyak::util::rsi, Xbyak::util::r8,
|
||||
Xbyak::util::r9, Xbyak::util::r10, Xbyak::util::r11,
|
||||
Xbyak::util::rcx,
|
||||
Xbyak::util::rdx,
|
||||
Xbyak::util::rdi,
|
||||
Xbyak::util::rsi,
|
||||
Xbyak::util::r8,
|
||||
Xbyak::util::r9,
|
||||
Xbyak::util::r10,
|
||||
Xbyak::util::r11,
|
||||
// XMMs
|
||||
Xbyak::util::xmm0, Xbyak::util::xmm1, Xbyak::util::xmm2, Xbyak::util::xmm3, Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm5, Xbyak::util::xmm6, Xbyak::util::xmm7, Xbyak::util::xmm8, Xbyak::util::xmm9,
|
||||
Xbyak::util::xmm10, Xbyak::util::xmm11, Xbyak::util::xmm12, Xbyak::util::xmm13,
|
||||
Xbyak::util::xmm14, Xbyak::util::xmm15,
|
||||
Xbyak::util::xmm0,
|
||||
Xbyak::util::xmm1,
|
||||
Xbyak::util::xmm2,
|
||||
Xbyak::util::xmm3,
|
||||
Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm5,
|
||||
Xbyak::util::xmm6,
|
||||
Xbyak::util::xmm7,
|
||||
Xbyak::util::xmm8,
|
||||
Xbyak::util::xmm9,
|
||||
Xbyak::util::xmm10,
|
||||
Xbyak::util::xmm11,
|
||||
Xbyak::util::xmm12,
|
||||
Xbyak::util::xmm13,
|
||||
Xbyak::util::xmm14,
|
||||
Xbyak::util::xmm15,
|
||||
});
|
||||
|
||||
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rbx, Xbyak::util::rbp, Xbyak::util::r12, Xbyak::util::r13, Xbyak::util::r14,
|
||||
Xbyak::util::rbx,
|
||||
Xbyak::util::rbp,
|
||||
Xbyak::util::r12,
|
||||
Xbyak::util::r13,
|
||||
Xbyak::util::r14,
|
||||
Xbyak::util::r15,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,175 +1,190 @@
|
||||
set(SRCS
|
||||
arm/dynarmic/arm_dynarmic.cpp
|
||||
arm/unicorn/arm_unicorn.cpp
|
||||
core.cpp
|
||||
core_timing.cpp
|
||||
file_sys/archive_backend.cpp
|
||||
file_sys/disk_archive.cpp
|
||||
file_sys/ivfc_archive.cpp
|
||||
file_sys/path_parser.cpp
|
||||
file_sys/savedata_archive.cpp
|
||||
file_sys/title_metadata.cpp
|
||||
frontend/emu_window.cpp
|
||||
frontend/framebuffer_layout.cpp
|
||||
gdbstub/gdbstub.cpp
|
||||
hle/config_mem.cpp
|
||||
hle/kernel/address_arbiter.cpp
|
||||
hle/kernel/client_port.cpp
|
||||
hle/kernel/client_session.cpp
|
||||
hle/kernel/condition_variable.cpp
|
||||
hle/kernel/domain.cpp
|
||||
hle/kernel/event.cpp
|
||||
hle/kernel/handle_table.cpp
|
||||
hle/kernel/hle_ipc.cpp
|
||||
hle/kernel/kernel.cpp
|
||||
hle/kernel/memory.cpp
|
||||
hle/kernel/mutex.cpp
|
||||
hle/kernel/object_address_table.cpp
|
||||
hle/kernel/process.cpp
|
||||
hle/kernel/resource_limit.cpp
|
||||
hle/kernel/server_port.cpp
|
||||
hle/kernel/server_session.cpp
|
||||
hle/kernel/shared_memory.cpp
|
||||
hle/kernel/svc.cpp
|
||||
hle/kernel/thread.cpp
|
||||
hle/kernel/timer.cpp
|
||||
hle/kernel/vm_manager.cpp
|
||||
hle/kernel/wait_object.cpp
|
||||
hle/lock.cpp
|
||||
hle/romfs.cpp
|
||||
hle/service/acc/acc.cpp
|
||||
hle/service/acc/acc_u0.cpp
|
||||
hle/service/am/am.cpp
|
||||
hle/service/am/applet_oe.cpp
|
||||
hle/service/aoc/aoc_u.cpp
|
||||
hle/service/apm/apm.cpp
|
||||
hle/service/audio/audio.cpp
|
||||
hle/service/audio/audout_u.cpp
|
||||
hle/service/hid/hid.cpp
|
||||
hle/service/lm/lm.cpp
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.cpp
|
||||
hle/service/nvdrv/devices/nvmap.cpp
|
||||
hle/service/nvdrv/interface.cpp
|
||||
hle/service/nvdrv/nvdrv.cpp
|
||||
hle/service/pctl/pctl.cpp
|
||||
hle/service/pctl/pctl_a.cpp
|
||||
hle/service/service.cpp
|
||||
hle/service/sm/controller.cpp
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/time/time.cpp
|
||||
hle/service/time/time_s.cpp
|
||||
hle/service/vi/vi.cpp
|
||||
hle/service/vi/vi_m.cpp
|
||||
hle/shared_page.cpp
|
||||
hw/hw.cpp
|
||||
hw/lcd.cpp
|
||||
loader/elf.cpp
|
||||
loader/linker.cpp
|
||||
loader/loader.cpp
|
||||
loader/nro.cpp
|
||||
loader/nso.cpp
|
||||
tracer/recorder.cpp
|
||||
memory.cpp
|
||||
perf_stats.cpp
|
||||
settings.cpp
|
||||
telemetry_session.cpp
|
||||
)
|
||||
add_library(core STATIC
|
||||
arm/arm_interface.h
|
||||
arm/unicorn/arm_unicorn.cpp
|
||||
arm/unicorn/arm_unicorn.h
|
||||
core.cpp
|
||||
core.h
|
||||
core_timing.cpp
|
||||
core_timing.h
|
||||
file_sys/archive_backend.cpp
|
||||
file_sys/archive_backend.h
|
||||
file_sys/directory_backend.h
|
||||
file_sys/disk_archive.cpp
|
||||
file_sys/disk_archive.h
|
||||
file_sys/errors.h
|
||||
file_sys/file_backend.h
|
||||
file_sys/ivfc_archive.cpp
|
||||
file_sys/ivfc_archive.h
|
||||
file_sys/path_parser.cpp
|
||||
file_sys/path_parser.h
|
||||
file_sys/savedata_archive.cpp
|
||||
file_sys/savedata_archive.h
|
||||
file_sys/title_metadata.cpp
|
||||
file_sys/title_metadata.h
|
||||
frontend/emu_window.cpp
|
||||
frontend/emu_window.h
|
||||
frontend/framebuffer_layout.cpp
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/input.h
|
||||
gdbstub/gdbstub.cpp
|
||||
gdbstub/gdbstub.h
|
||||
hle/config_mem.cpp
|
||||
hle/config_mem.h
|
||||
hle/ipc.h
|
||||
hle/ipc_helpers.h
|
||||
hle/kernel/address_arbiter.cpp
|
||||
hle/kernel/address_arbiter.h
|
||||
hle/kernel/client_port.cpp
|
||||
hle/kernel/client_port.h
|
||||
hle/kernel/client_session.cpp
|
||||
hle/kernel/client_session.h
|
||||
hle/kernel/condition_variable.cpp
|
||||
hle/kernel/condition_variable.h
|
||||
hle/kernel/domain.cpp
|
||||
hle/kernel/domain.h
|
||||
hle/kernel/errors.h
|
||||
hle/kernel/event.cpp
|
||||
hle/kernel/event.h
|
||||
hle/kernel/handle_table.cpp
|
||||
hle/kernel/handle_table.h
|
||||
hle/kernel/hle_ipc.cpp
|
||||
hle/kernel/hle_ipc.h
|
||||
hle/kernel/kernel.cpp
|
||||
hle/kernel/kernel.h
|
||||
hle/kernel/memory.cpp
|
||||
hle/kernel/memory.h
|
||||
hle/kernel/mutex.cpp
|
||||
hle/kernel/mutex.h
|
||||
hle/kernel/object_address_table.cpp
|
||||
hle/kernel/object_address_table.h
|
||||
hle/kernel/process.cpp
|
||||
hle/kernel/process.h
|
||||
hle/kernel/resource_limit.cpp
|
||||
hle/kernel/resource_limit.h
|
||||
hle/kernel/server_port.cpp
|
||||
hle/kernel/server_port.h
|
||||
hle/kernel/server_session.cpp
|
||||
hle/kernel/server_session.h
|
||||
hle/kernel/session.h
|
||||
hle/kernel/shared_memory.cpp
|
||||
hle/kernel/shared_memory.h
|
||||
hle/kernel/svc.cpp
|
||||
hle/kernel/svc.h
|
||||
hle/kernel/svc_wrap.h
|
||||
hle/kernel/sync_object.h
|
||||
hle/kernel/thread.cpp
|
||||
hle/kernel/thread.h
|
||||
hle/kernel/timer.cpp
|
||||
hle/kernel/timer.h
|
||||
hle/kernel/vm_manager.cpp
|
||||
hle/kernel/vm_manager.h
|
||||
hle/kernel/wait_object.cpp
|
||||
hle/kernel/wait_object.h
|
||||
hle/lock.cpp
|
||||
hle/lock.h
|
||||
hle/result.h
|
||||
hle/romfs.cpp
|
||||
hle/romfs.h
|
||||
hle/service/acc/acc.cpp
|
||||
hle/service/acc/acc.h
|
||||
hle/service/acc/acc_u0.cpp
|
||||
hle/service/acc/acc_u0.h
|
||||
hle/service/am/am.cpp
|
||||
hle/service/am/am.h
|
||||
hle/service/am/applet_oe.cpp
|
||||
hle/service/am/applet_oe.h
|
||||
hle/service/aoc/aoc_u.cpp
|
||||
hle/service/aoc/aoc_u.h
|
||||
hle/service/apm/apm.cpp
|
||||
hle/service/apm/apm.h
|
||||
hle/service/audio/audio.cpp
|
||||
hle/service/audio/audio.h
|
||||
hle/service/audio/audout_u.cpp
|
||||
hle/service/audio/audout_u.h
|
||||
hle/service/hid/hid.cpp
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.cpp
|
||||
hle/service/lm/lm.h
|
||||
hle/service/nvdrv/devices/nvdevice.h
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.h
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.cpp
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.h
|
||||
hle/service/nvdrv/devices/nvmap.cpp
|
||||
hle/service/nvdrv/devices/nvmap.h
|
||||
hle/service/nvdrv/interface.cpp
|
||||
hle/service/nvdrv/interface.h
|
||||
hle/service/nvdrv/nvdrv.cpp
|
||||
hle/service/nvdrv/nvdrv.h
|
||||
hle/service/pctl/pctl.cpp
|
||||
hle/service/pctl/pctl.h
|
||||
hle/service/pctl/pctl_a.cpp
|
||||
hle/service/pctl/pctl_a.h
|
||||
hle/service/service.cpp
|
||||
hle/service/service.h
|
||||
hle/service/set/set.cpp
|
||||
hle/service/set/set.h
|
||||
hle/service/sm/controller.cpp
|
||||
hle/service/sm/controller.h
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/sm/sm.h
|
||||
hle/service/sockets/bsd_u.cpp
|
||||
hle/service/sockets/bsd_u.h
|
||||
hle/service/sockets/sfdnsres.h
|
||||
hle/service/sockets/sockets.cpp
|
||||
hle/service/sockets/sockets.h
|
||||
hle/service/time/time.cpp
|
||||
hle/service/time/time.h
|
||||
hle/service/time/time_s.cpp
|
||||
hle/service/time/time_s.h
|
||||
hle/service/time/time_u.cpp
|
||||
hle/service/time/time_u.h
|
||||
hle/service/vi/vi.cpp
|
||||
hle/service/vi/vi.h
|
||||
hle/service/vi/vi_m.cpp
|
||||
hle/service/vi/vi_m.h
|
||||
hle/shared_page.cpp
|
||||
hle/shared_page.h
|
||||
hw/hw.cpp
|
||||
hw/hw.h
|
||||
hw/lcd.cpp
|
||||
hw/lcd.h
|
||||
loader/deconstructed_rom_directory.cpp
|
||||
loader/deconstructed_rom_directory.h
|
||||
loader/elf.cpp
|
||||
loader/elf.h
|
||||
loader/linker.cpp
|
||||
loader/linker.h
|
||||
loader/loader.cpp
|
||||
loader/loader.h
|
||||
loader/nro.cpp
|
||||
loader/nro.h
|
||||
loader/nso.cpp
|
||||
loader/nso.h
|
||||
memory.cpp
|
||||
memory.h
|
||||
memory_setup.h
|
||||
mmio.h
|
||||
perf_stats.cpp
|
||||
perf_stats.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
telemetry_session.cpp
|
||||
telemetry_session.h
|
||||
tracer/citrace.h
|
||||
tracer/recorder.cpp
|
||||
tracer/recorder.h
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
arm/arm_interface.h
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
arm/unicorn/arm_unicorn.h
|
||||
core.h
|
||||
core_timing.h
|
||||
file_sys/archive_backend.h
|
||||
file_sys/directory_backend.h
|
||||
file_sys/disk_archive.h
|
||||
file_sys/errors.h
|
||||
file_sys/file_backend.h
|
||||
file_sys/ivfc_archive.h
|
||||
file_sys/path_parser.h
|
||||
file_sys/savedata_archive.h
|
||||
frontend/emu_window.h
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/input.h
|
||||
gdbstub/gdbstub.h
|
||||
hle/config_mem.h
|
||||
hle/ipc.h
|
||||
hle/ipc_helpers.h
|
||||
hle/kernel/address_arbiter.h
|
||||
hle/kernel/client_port.h
|
||||
hle/kernel/client_session.h
|
||||
hle/kernel/condition_variable.h
|
||||
hle/kernel/domain.h
|
||||
hle/kernel/errors.h
|
||||
hle/kernel/event.h
|
||||
hle/kernel/handle_table.h
|
||||
hle/kernel/hle_ipc.h
|
||||
hle/kernel/kernel.h
|
||||
hle/kernel/memory.h
|
||||
hle/kernel/mutex.h
|
||||
hle/kernel/object_address_table.h
|
||||
hle/kernel/process.h
|
||||
hle/kernel/resource_limit.h
|
||||
hle/kernel/server_port.h
|
||||
hle/kernel/server_session.h
|
||||
hle/kernel/session.h
|
||||
hle/kernel/shared_memory.h
|
||||
hle/kernel/sync_object.h
|
||||
hle/kernel/svc.h
|
||||
hle/kernel/svc_wrap.h
|
||||
hle/kernel/thread.h
|
||||
hle/kernel/timer.h
|
||||
hle/kernel/vm_manager.h
|
||||
hle/kernel/wait_object.h
|
||||
hle/lock.h
|
||||
hle/result.h
|
||||
hle/romfs.h
|
||||
hle/service/acc/acc.h
|
||||
hle/service/acc/acc_u0.h
|
||||
hle/service/am/am.h
|
||||
hle/service/am/applet_oe.h
|
||||
hle/service/aoc/aoc_u.h
|
||||
hle/service/apm/apm.h
|
||||
hle/service/audio/audio.h
|
||||
hle/service/audio/audout_u.h
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.h
|
||||
hle/service/nvdrv/devices/nvdevice.h
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.h
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.h
|
||||
hle/service/nvdrv/devices/nvmap.h
|
||||
hle/service/nvdrv/interface.h
|
||||
hle/service/nvdrv/nvdrv.h
|
||||
hle/service/pctl/pctl.h
|
||||
hle/service/pctl/pctl_a.h
|
||||
hle/service/service.h
|
||||
hle/service/sm/controller.h
|
||||
hle/service/sm/sm.h
|
||||
hle/service/time/time.h
|
||||
hle/service/time/time_s.h
|
||||
hle/service/vi/vi.h
|
||||
hle/service/vi/vi_m.h
|
||||
hle/shared_page.h
|
||||
hw/hw.h
|
||||
hw/lcd.h
|
||||
loader/elf.h
|
||||
loader/linker.h
|
||||
loader/loader.h
|
||||
loader/nro.h
|
||||
loader/nso.h
|
||||
tracer/recorder.h
|
||||
tracer/citrace.h
|
||||
memory.h
|
||||
memory_setup.h
|
||||
mmio.h
|
||||
perf_stats.h
|
||||
settings.h
|
||||
telemetry_session.h
|
||||
)
|
||||
create_target_directory_groups(core)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(core STATIC ${SRCS} ${HEADERS})
|
||||
target_link_libraries(core PUBLIC common PRIVATE dynarmic video_core)
|
||||
target_link_libraries(core PUBLIC common PRIVATE video_core)
|
||||
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn)
|
||||
|
||||
if (ARCHITECTURE_x86_64)
|
||||
target_sources(core PRIVATE
|
||||
arm/dynarmic/arm_dynarmic.cpp
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
)
|
||||
target_link_libraries(core PRIVATE dynarmic)
|
||||
endif()
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
ARM_Interface::ThreadContext ctx;
|
||||
parent.SaveContext(ctx);
|
||||
parent.inner_unicorn.LoadContext(ctx);
|
||||
parent.inner_unicorn.ExecuteInstructions(num_instructions);
|
||||
parent.inner_unicorn.ExecuteInstructions(static_cast<int>(num_instructions));
|
||||
parent.inner_unicorn.SaveContext(ctx);
|
||||
parent.LoadContext(ctx);
|
||||
num_interpreted_instructions += num_instructions;
|
||||
@@ -163,9 +163,9 @@ void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
|
||||
jit.SetRegisters(ctx.cpu_registers);
|
||||
jit.SetSP(ctx.sp);
|
||||
jit.SetPC(ctx.pc);
|
||||
jit.SetPstate(ctx.cpsr);
|
||||
jit.SetPstate(static_cast<u32>(ctx.cpsr));
|
||||
jit.SetVectors(ctx.fpu_registers);
|
||||
jit.SetFpcr(ctx.fpscr);
|
||||
jit.SetFpcr(static_cast<u32>(ctx.fpscr));
|
||||
cb->tpidrr0_el0 = ctx.tls_address;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include "common/logging/log.h"
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#include "core/arm/dynarmic/arm_dynarmic.h"
|
||||
#endif
|
||||
#include "core/arm/unicorn/arm_unicorn.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
@@ -80,7 +82,6 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
||||
if (system_mode.second != Loader::ResultStatus::Success) {
|
||||
LOG_CRITICAL(Core, "Failed to determine system mode (Error %i)!",
|
||||
static_cast<int>(system_mode.second));
|
||||
System::Shutdown();
|
||||
|
||||
switch (system_mode.second) {
|
||||
case Loader::ResultStatus::ErrorEncrypted:
|
||||
@@ -144,7 +145,12 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
break;
|
||||
case Settings::CpuCore::Dynarmic:
|
||||
default:
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
cpu_core = std::make_unique<ARM_Dynarmic>();
|
||||
#else
|
||||
cpu_core = std::make_unique<ARM_Unicorn>();
|
||||
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ u64 GetTicks() {
|
||||
}
|
||||
|
||||
void AddTicks(u64 ticks) {
|
||||
downcount -= ticks;
|
||||
downcount -= static_cast<int>(ticks);
|
||||
}
|
||||
|
||||
u64 GetIdleTicks() {
|
||||
@@ -208,7 +208,7 @@ void Advance() {
|
||||
Event evt = std::move(event_queue.front());
|
||||
std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
|
||||
event_queue.pop_back();
|
||||
evt.type->callback(evt.userdata, global_timer - evt.time);
|
||||
evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time));
|
||||
}
|
||||
|
||||
is_global_timer_sane = false;
|
||||
|
||||
@@ -119,4 +119,4 @@ std::vector<u8> Path::AsBinary() const {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "common/common_types.h"
|
||||
|
||||
@@ -57,9 +57,10 @@ const u32 SIGTERM = 15;
|
||||
const u32 MSG_WAITALL = 8;
|
||||
#endif
|
||||
|
||||
const u32 R15_REGISTER = 15;
|
||||
const u32 CPSR_REGISTER = 25;
|
||||
const u32 FPSCR_REGISTER = 58;
|
||||
const u32 X30_REGISTER = 30;
|
||||
const u32 SP_REGISTER = 31;
|
||||
const u32 PC_REGISTER = 32;
|
||||
const u32 CPSR_REGISTER = 33;
|
||||
|
||||
// For sample XML files see the GDB source /gdb/features
|
||||
// GDB also wants the l character at the start
|
||||
@@ -68,48 +69,62 @@ static const char* target_xml =
|
||||
R"(l<?xml version="1.0"?>
|
||||
<!DOCTYPE target SYSTEM "gdb-target.dtd">
|
||||
<target version="1.0">
|
||||
<feature name="org.gnu.gdb.arm.core">
|
||||
<reg name="r0" bitsize="32"/>
|
||||
<reg name="r1" bitsize="32"/>
|
||||
<reg name="r2" bitsize="32"/>
|
||||
<reg name="r3" bitsize="32"/>
|
||||
<reg name="r4" bitsize="32"/>
|
||||
<reg name="r5" bitsize="32"/>
|
||||
<reg name="r6" bitsize="32"/>
|
||||
<reg name="r7" bitsize="32"/>
|
||||
<reg name="r8" bitsize="32"/>
|
||||
<reg name="r9" bitsize="32"/>
|
||||
<reg name="r10" bitsize="32"/>
|
||||
<reg name="r11" bitsize="32"/>
|
||||
<reg name="r12" bitsize="32"/>
|
||||
<reg name="sp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="lr" bitsize="32"/>
|
||||
<reg name="pc" bitsize="32" type="code_ptr"/>
|
||||
<feature name="org.gnu.gdb.aarch64.core">
|
||||
<reg name="x0" bitsize="64"/>
|
||||
<reg name="x1" bitsize="64"/>
|
||||
<reg name="x2" bitsize="64"/>
|
||||
<reg name="x3" bitsize="64"/>
|
||||
<reg name="x4" bitsize="64"/>
|
||||
<reg name="x5" bitsize="64"/>
|
||||
<reg name="x6" bitsize="64"/>
|
||||
<reg name="x7" bitsize="64"/>
|
||||
<reg name="x8" bitsize="64"/>
|
||||
<reg name="x9" bitsize="64"/>
|
||||
<reg name="x10" bitsize="64"/>
|
||||
<reg name="x11" bitsize="64"/>
|
||||
<reg name="x12" bitsize="64"/>
|
||||
<reg name="x13" bitsize="64"/>
|
||||
<reg name="x14" bitsize="64"/>
|
||||
<reg name="x15" bitsize="64"/>
|
||||
<reg name="x16" bitsize="64"/>
|
||||
<reg name="x17" bitsize="64"/>
|
||||
<reg name="x18" bitsize="64"/>
|
||||
<reg name="x19" bitsize="64"/>
|
||||
<reg name="x20" bitsize="64"/>
|
||||
<reg name="x21" bitsize="64"/>
|
||||
<reg name="x22" bitsize="64"/>
|
||||
<reg name="x23" bitsize="64"/>
|
||||
<reg name="x24" bitsize="64"/>
|
||||
<reg name="x25" bitsize="64"/>
|
||||
<reg name="x26" bitsize="64"/>
|
||||
<reg name="x27" bitsize="64"/>
|
||||
<reg name="x28" bitsize="64"/>
|
||||
<reg name="x29" bitsize="64"/>
|
||||
<reg name="x30" bitsize="64"/>
|
||||
<reg name="sp" bitsize="64" type="data_ptr"/>
|
||||
|
||||
<!-- The CPSR is register 25, rather than register 16, because
|
||||
the FPA registers historically were placed between the PC
|
||||
and the CPSR in the "g" packet. -->
|
||||
<reg name="pc" bitsize="64" type="code_ptr"/>
|
||||
|
||||
<reg name="cpsr" bitsize="32" regnum="25"/>
|
||||
</feature>
|
||||
<feature name="org.gnu.gdb.arm.vfp">
|
||||
<reg name="d0" bitsize="64" type="float"/>
|
||||
<reg name="d1" bitsize="64" type="float"/>
|
||||
<reg name="d2" bitsize="64" type="float"/>
|
||||
<reg name="d3" bitsize="64" type="float"/>
|
||||
<reg name="d4" bitsize="64" type="float"/>
|
||||
<reg name="d5" bitsize="64" type="float"/>
|
||||
<reg name="d6" bitsize="64" type="float"/>
|
||||
<reg name="d7" bitsize="64" type="float"/>
|
||||
<reg name="d8" bitsize="64" type="float"/>
|
||||
<reg name="d9" bitsize="64" type="float"/>
|
||||
<reg name="d10" bitsize="64" type="float"/>
|
||||
<reg name="d11" bitsize="64" type="float"/>
|
||||
<reg name="d12" bitsize="64" type="float"/>
|
||||
<reg name="d13" bitsize="64" type="float"/>
|
||||
<reg name="d14" bitsize="64" type="float"/>
|
||||
<reg name="d15" bitsize="64" type="float"/>
|
||||
<reg name="fpscr" bitsize="32" type="int" group="float"/>
|
||||
<flags id="cpsr_flags" size="4">
|
||||
<field name="SP" start="0" end="0"/>
|
||||
<field name="" start="1" end="1"/>
|
||||
<field name="EL" start="2" end="3"/>
|
||||
<field name="nRW" start="4" end="4"/>
|
||||
<field name="" start="5" end="5"/>
|
||||
<field name="F" start="6" end="6"/>
|
||||
<field name="I" start="7" end="7"/>
|
||||
<field name="A" start="8" end="8"/>
|
||||
<field name="D" start="9" end="9"/>
|
||||
|
||||
<field name="IL" start="20" end="20"/>
|
||||
<field name="SS" start="21" end="21"/>
|
||||
|
||||
<field name="V" start="28" end="28"/>
|
||||
<field name="C" start="29" end="29"/>
|
||||
<field name="Z" start="30" end="30"/>
|
||||
<field name="N" start="31" end="31"/>
|
||||
</flags>
|
||||
<reg name="cpsr" bitsize="32" type="cpsr_flags"/>
|
||||
</feature>
|
||||
</target>
|
||||
)";
|
||||
@@ -143,12 +158,12 @@ WSADATA InitData;
|
||||
struct Breakpoint {
|
||||
bool active;
|
||||
PAddr addr;
|
||||
u32 len;
|
||||
u64 len;
|
||||
};
|
||||
|
||||
static std::map<u32, Breakpoint> breakpoints_execute;
|
||||
static std::map<u32, Breakpoint> breakpoints_read;
|
||||
static std::map<u32, Breakpoint> breakpoints_write;
|
||||
static std::map<u64, Breakpoint> breakpoints_execute;
|
||||
static std::map<u64, Breakpoint> breakpoints_read;
|
||||
static std::map<u64, Breakpoint> breakpoints_write;
|
||||
|
||||
/**
|
||||
* Turns hex string character into the equivalent byte.
|
||||
@@ -183,11 +198,11 @@ static u8 NibbleToHex(u8 n) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts input hex string characters into an array of equivalent of u8 bytes.
|
||||
*
|
||||
* @param src Pointer to array of output hex string characters.
|
||||
* @param len Length of src array.
|
||||
*/
|
||||
* Converts input hex string characters into an array of equivalent of u8 bytes.
|
||||
*
|
||||
* @param src Pointer to array of output hex string characters.
|
||||
* @param len Length of src array.
|
||||
*/
|
||||
static u32 HexToInt(const u8* src, size_t len) {
|
||||
u32 output = 0;
|
||||
while (len-- > 0) {
|
||||
@@ -197,6 +212,21 @@ static u32 HexToInt(const u8* src, size_t len) {
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts input hex string characters into an array of equivalent of u8 bytes.
|
||||
*
|
||||
* @param src Pointer to array of output hex string characters.
|
||||
* @param len Length of src array.
|
||||
*/
|
||||
static u64 HexToLong(const u8* src, size_t len) {
|
||||
u64 output = 0;
|
||||
while (len-- > 0) {
|
||||
output = (output << 4) | HexCharToValue(src[0]);
|
||||
src++;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts input array of u8 bytes into their equivalent hex string characters.
|
||||
*
|
||||
@@ -234,8 +264,21 @@ static void GdbHexToMem(u8* dest, const u8* src, size_t len) {
|
||||
*/
|
||||
static void IntToGdbHex(u8* dest, u32 v) {
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
dest[i + 1] = NibbleToHex(v >> (4 * i));
|
||||
dest[i] = NibbleToHex(v >> (4 * (i + 1)));
|
||||
dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
|
||||
dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a u64 into a gdb-formatted hex string.
|
||||
*
|
||||
* @param dest Pointer to buffer to store output hex string characters.
|
||||
* @param v Value to convert.
|
||||
*/
|
||||
static void LongToGdbHex(u8* dest, u64 v) {
|
||||
for (int i = 0; i < 16; i += 2) {
|
||||
dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
|
||||
dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +298,22 @@ static u32 GdbHexToInt(const u8* src) {
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a gdb-formatted hex string into a u64.
|
||||
*
|
||||
* @param src Pointer to hex string.
|
||||
*/
|
||||
static u64 GdbHexToLong(const u8* src) {
|
||||
u64 output = 0;
|
||||
|
||||
for (int i = 0; i < 16; i += 2) {
|
||||
output = (output << 4) | HexCharToValue(src[15 - i - 1]);
|
||||
output = (output << 4) | HexCharToValue(src[15 - i]);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/// Read a byte from the gdb client.
|
||||
static u8 ReadByte() {
|
||||
u8 c;
|
||||
@@ -277,7 +336,7 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
|
||||
*
|
||||
* @param type Type of breakpoint list.
|
||||
*/
|
||||
static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) {
|
||||
static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
|
||||
switch (type) {
|
||||
case BreakpointType::Execute:
|
||||
return breakpoints_execute;
|
||||
@@ -297,19 +356,19 @@ static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) {
|
||||
* @param addr Address of breakpoint.
|
||||
*/
|
||||
static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
||||
|
||||
auto bp = p.find(addr);
|
||||
auto bp = p.find(static_cast<u64>(addr));
|
||||
if (bp != p.end()) {
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n",
|
||||
bp->second.len, bp->second.addr, type);
|
||||
p.erase(addr);
|
||||
p.erase(static_cast<u64>(addr));
|
||||
}
|
||||
}
|
||||
|
||||
BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) {
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
auto next_breakpoint = p.lower_bound(addr);
|
||||
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
||||
auto next_breakpoint = p.lower_bound(static_cast<u64>(addr));
|
||||
BreakpointAddress breakpoint;
|
||||
|
||||
if (next_breakpoint != p.end()) {
|
||||
@@ -328,11 +387,11 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
||||
|
||||
auto bp = p.find(addr);
|
||||
auto bp = p.find(static_cast<u64>(addr));
|
||||
if (bp != p.end()) {
|
||||
u32 len = bp->second.len;
|
||||
u64 len = bp->second.len;
|
||||
|
||||
// IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
|
||||
// no matter if it's a 4-byte or 2-byte instruction. When you execute a
|
||||
@@ -419,7 +478,7 @@ static void HandleQuery() {
|
||||
SendReply("T0");
|
||||
} else if (strncmp(query, "Supported", strlen("Supported")) == 0) {
|
||||
// PacketSize needs to be large enough for target xml
|
||||
SendReply("PacketSize=800;qXfer:features:read+");
|
||||
SendReply("PacketSize=2000;qXfer:features:read+");
|
||||
} else if (strncmp(query, "Xfer:features:read:target.xml:",
|
||||
strlen("Xfer:features:read:target.xml:")) == 0) {
|
||||
SendReply(target_xml);
|
||||
@@ -450,9 +509,7 @@ static void SendSignal(u32 signal) {
|
||||
|
||||
latest_signal = signal;
|
||||
|
||||
std::string buffer =
|
||||
Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
|
||||
htonl(Core::CPU().GetPC()), 13, htonl(Core::CPU().GetReg(13)));
|
||||
std::string buffer = Common::StringFromFormat("T%02x", latest_signal);
|
||||
LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str());
|
||||
SendReply(buffer.c_str());
|
||||
}
|
||||
@@ -538,16 +595,12 @@ static void ReadRegister() {
|
||||
id |= HexCharToValue(command_buffer[2]);
|
||||
}
|
||||
|
||||
if (id <= R15_REGISTER) {
|
||||
IntToGdbHex(reply, Core::CPU().GetReg(id));
|
||||
if (id <= SP_REGISTER) {
|
||||
LongToGdbHex(reply, Core::CPU().GetReg(static_cast<int>(id)));
|
||||
} else if (id == PC_REGISTER) {
|
||||
LongToGdbHex(reply, Core::CPU().GetPC());
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::CPU().GetCPSR());
|
||||
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::CPU().GetVFPReg(
|
||||
id - CPSR_REGISTER -
|
||||
1)); // VFP registers should start at 26, so one after CSPR_REGISTER
|
||||
} else if (id == FPSCR_REGISTER) {
|
||||
UNIMPLEMENTED();
|
||||
} else {
|
||||
return SendReply("E01");
|
||||
}
|
||||
@@ -562,21 +615,19 @@ static void ReadRegisters() {
|
||||
|
||||
u8* bufptr = buffer;
|
||||
|
||||
for (int reg = 0; reg <= R15_REGISTER; reg++) {
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetReg(reg));
|
||||
for (int reg = 0; reg <= SP_REGISTER; reg++) {
|
||||
LongToGdbHex(bufptr + reg * 16, Core::CPU().GetReg(reg));
|
||||
}
|
||||
|
||||
bufptr += (16 * CHAR_BIT);
|
||||
bufptr += (32 * 16);
|
||||
|
||||
LongToGdbHex(bufptr, Core::CPU().GetPC());
|
||||
|
||||
bufptr += 16;
|
||||
|
||||
IntToGdbHex(bufptr, Core::CPU().GetCPSR());
|
||||
|
||||
bufptr += CHAR_BIT;
|
||||
|
||||
for (int reg = 0; reg <= 31; reg++) {
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetVFPReg(reg));
|
||||
}
|
||||
|
||||
bufptr += (32 * CHAR_BIT);
|
||||
bufptr += 8;
|
||||
|
||||
SendReply(reinterpret_cast<char*>(buffer));
|
||||
}
|
||||
@@ -592,14 +643,12 @@ static void WriteRegister() {
|
||||
id |= HexCharToValue(command_buffer[2]);
|
||||
}
|
||||
|
||||
if (id <= R15_REGISTER) {
|
||||
Core::CPU().SetReg(id, GdbHexToInt(buffer_ptr));
|
||||
if (id <= SP_REGISTER) {
|
||||
Core::CPU().SetReg(id, GdbHexToLong(buffer_ptr));
|
||||
} else if (id == PC_REGISTER) {
|
||||
Core::CPU().SetPC(GdbHexToLong(buffer_ptr));
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr));
|
||||
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
|
||||
Core::CPU().SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
|
||||
} else if (id == FPSCR_REGISTER) {
|
||||
UNIMPLEMENTED();
|
||||
} else {
|
||||
return SendReply("E01");
|
||||
}
|
||||
@@ -614,20 +663,14 @@ static void WriteRegisters() {
|
||||
if (command_buffer[0] != 'G')
|
||||
return SendReply("E01");
|
||||
|
||||
for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
|
||||
if (reg <= R15_REGISTER) {
|
||||
Core::CPU().SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
for (int i = 0, reg = 0; reg <= CPSR_REGISTER; i++, reg++) {
|
||||
if (reg <= SP_REGISTER) {
|
||||
Core::CPU().SetReg(reg, GdbHexToLong(buffer_ptr + i * 16));
|
||||
} else if (reg == PC_REGISTER) {
|
||||
Core::CPU().SetPC(GdbHexToLong(buffer_ptr + i * 16));
|
||||
} else if (reg == CPSR_REGISTER) {
|
||||
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
} else if (reg == CPSR_REGISTER - 1) {
|
||||
// Dummy FPA register, ignore
|
||||
} else if (reg < CPSR_REGISTER) {
|
||||
// Dummy FPA registers, ignore
|
||||
i += 2;
|
||||
} else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
|
||||
Core::CPU().SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
|
||||
i++; // Skip padding
|
||||
} else if (reg == FPSCR_REGISTER) {
|
||||
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * 16));
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
@@ -641,13 +684,13 @@ static void ReadMemory() {
|
||||
|
||||
auto start_offset = command_buffer + 1;
|
||||
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
|
||||
VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
|
||||
VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
|
||||
|
||||
start_offset = addr_pos + 1;
|
||||
u32 len =
|
||||
HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
|
||||
u64 len =
|
||||
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
|
||||
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %08x len: %08x\n", addr, len);
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016llx len: %016llx\n", addr, len);
|
||||
|
||||
if (len * 2 > sizeof(reply)) {
|
||||
SendReply("E01");
|
||||
@@ -669,11 +712,11 @@ static void ReadMemory() {
|
||||
static void WriteMemory() {
|
||||
auto start_offset = command_buffer + 1;
|
||||
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
|
||||
VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
|
||||
VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
|
||||
|
||||
start_offset = addr_pos + 1;
|
||||
auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
|
||||
u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
|
||||
u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset));
|
||||
|
||||
if (!Memory::IsValidVirtualAddress(addr)) {
|
||||
return SendReply("E00");
|
||||
@@ -726,8 +769,8 @@ static void Continue() {
|
||||
* @param addr Address of breakpoint.
|
||||
* @param len Length of breakpoint.
|
||||
*/
|
||||
static bool CommitBreakpoint(BreakpointType type, PAddr addr, u32 len) {
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) {
|
||||
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
|
||||
|
||||
Breakpoint breakpoint;
|
||||
breakpoint.active = true;
|
||||
@@ -766,11 +809,11 @@ static void AddBreakpoint() {
|
||||
|
||||
auto start_offset = command_buffer + 3;
|
||||
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
|
||||
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
|
||||
PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
|
||||
|
||||
start_offset = addr_pos + 1;
|
||||
u32 len =
|
||||
HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
|
||||
u64 len =
|
||||
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
|
||||
|
||||
if (type == BreakpointType::Access) {
|
||||
// Access is made up of Read and Write types, so add both breakpoints
|
||||
@@ -815,7 +858,7 @@ static void RemoveBreakpoint() {
|
||||
|
||||
auto start_offset = command_buffer + 3;
|
||||
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
|
||||
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
|
||||
PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
|
||||
|
||||
if (type == BreakpointType::Access) {
|
||||
// Access is made up of Read and Write types, so add both breakpoints
|
||||
@@ -905,7 +948,7 @@ void ToggleServer(bool status) {
|
||||
server_enabled = status;
|
||||
|
||||
// Start server
|
||||
if (!IsConnected() && Core::System().GetInstance().IsPoweredOn()) {
|
||||
if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
|
||||
Init();
|
||||
}
|
||||
} else {
|
||||
@@ -1034,4 +1077,4 @@ bool GetCpuStepFlag() {
|
||||
void SetCpuStepFlag(bool is_step) {
|
||||
step_loop = is_step;
|
||||
}
|
||||
};
|
||||
}; // namespace GDBStub
|
||||
|
||||
@@ -91,4 +91,4 @@ bool GetCpuStepFlag();
|
||||
* @param is_step
|
||||
*/
|
||||
void SetCpuStepFlag(bool is_step);
|
||||
}
|
||||
} // namespace GDBStub
|
||||
|
||||
@@ -28,4 +28,4 @@ void Init() {
|
||||
config_mem.firm_ctr_sdk_ver = 0x0000F297;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace ConfigMem
|
||||
|
||||
@@ -53,4 +53,4 @@ extern ConfigMemDef config_mem;
|
||||
|
||||
void Init();
|
||||
|
||||
} // namespace
|
||||
} // namespace ConfigMem
|
||||
|
||||
@@ -133,6 +133,10 @@ struct BufferDescriptorC {
|
||||
address |= static_cast<VAddr>(address_bits_32_47) << 32;
|
||||
return address;
|
||||
}
|
||||
|
||||
u64 Size() const {
|
||||
return static_cast<u64>(size);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(BufferDescriptorC) == 8, "BufferDescriptorC size is incorrect");
|
||||
|
||||
@@ -143,6 +147,11 @@ struct DataPayloadHeader {
|
||||
static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect");
|
||||
|
||||
struct DomainMessageHeader {
|
||||
enum class CommandType : u32_le {
|
||||
SendMessage = 1,
|
||||
CloseVirtualHandle = 2,
|
||||
};
|
||||
|
||||
union {
|
||||
// Used when responding to an IPC request, Server -> Client.
|
||||
struct {
|
||||
@@ -153,7 +162,7 @@ struct DomainMessageHeader {
|
||||
// Used when performing an IPC request, Client -> Server.
|
||||
struct {
|
||||
union {
|
||||
BitField<0, 8, u32_le> command;
|
||||
BitField<0, 8, CommandType> command;
|
||||
BitField<16, 16, u32_le> size;
|
||||
};
|
||||
u32_le object_id;
|
||||
|
||||
@@ -54,6 +54,10 @@ public:
|
||||
unsigned GetCurrentOffset() const {
|
||||
return static_cast<unsigned>(index);
|
||||
}
|
||||
|
||||
void SetCurrentOffset(unsigned offset) {
|
||||
index = static_cast<ptrdiff_t>(offset);
|
||||
}
|
||||
};
|
||||
|
||||
class RequestBuilder : public RequestHelperBase {
|
||||
|
||||
@@ -57,4 +57,4 @@ private:
|
||||
~AddressArbiter() override;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -39,4 +39,4 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
||||
return MakeResult(std::get<SharedPtr<ClientSession>>(sessions));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -47,4 +47,4 @@ private:
|
||||
~ClientPort() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -48,4 +48,4 @@ ResultCode ClientSession::SendSyncRequest(SharedPtr<Thread> thread) {
|
||||
return server->HandleSyncRequest(std::move(thread));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -45,4 +45,4 @@ private:
|
||||
~ClientSession() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -43,7 +43,7 @@ void ConditionVariable::Acquire(Thread* thread) {
|
||||
ResultCode ConditionVariable::Release(s32 target) {
|
||||
if (target == -1) {
|
||||
// When -1, wake up all waiting threads
|
||||
SetAvailableCount(GetWaitingThreads().size());
|
||||
SetAvailableCount(static_cast<s32>(GetWaitingThreads().size()));
|
||||
WakeupAllWaitingThreads();
|
||||
} else {
|
||||
// Otherwise, wake up just a single thread
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/wait_object.h"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/domain.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
@@ -36,7 +38,24 @@ ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) {
|
||||
if (domain_message_header) {
|
||||
// If there is a DomainMessageHeader, then this is CommandType "Request"
|
||||
const u32 object_id{context.GetDomainMessageHeader()->object_id};
|
||||
return request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||
switch (domain_message_header->command) {
|
||||
case IPC::DomainMessageHeader::CommandType::SendMessage:
|
||||
return request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||
|
||||
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
|
||||
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id);
|
||||
|
||||
request_handlers[object_id - 1] = nullptr;
|
||||
|
||||
IPC::RequestBuilder rb{context, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value());
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
return request_handlers.front()->HandleSyncRequest(context);
|
||||
}
|
||||
|
||||
@@ -52,4 +52,4 @@ void Event::WakeupAllWaitingThreads() {
|
||||
signaled = false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -49,4 +49,4 @@ private:
|
||||
~Event() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -104,4 +104,4 @@ void HandleTable::Clear() {
|
||||
next_free_slot = 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -130,4 +130,4 @@ private:
|
||||
|
||||
extern HandleTable g_handle_table;
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -81,13 +81,8 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
|
||||
for (unsigned i = 0; i < command_header->num_buf_w_descriptors; ++i) {
|
||||
buffer_w_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
|
||||
}
|
||||
if (command_header->buf_c_descriptor_flags !=
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::Disabled) {
|
||||
if (command_header->buf_c_descriptor_flags !=
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
|
||||
|
||||
// Padding to align to 16 bytes
|
||||
rp.AlignWithPadding();
|
||||
@@ -102,13 +97,45 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
|
||||
data_payload_header =
|
||||
std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
|
||||
|
||||
data_payload_offset = rp.GetCurrentOffset();
|
||||
|
||||
if (domain_message_header && domain_message_header->command ==
|
||||
IPC::DomainMessageHeader::CommandType::CloseVirtualHandle) {
|
||||
// CloseVirtualHandle command does not have SFC* or any data
|
||||
return;
|
||||
}
|
||||
|
||||
if (incoming) {
|
||||
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'I'));
|
||||
} else {
|
||||
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O'));
|
||||
}
|
||||
|
||||
data_payload_offset = rp.GetCurrentOffset();
|
||||
rp.SetCurrentOffset(buffer_c_offset);
|
||||
|
||||
// For Inline buffers, the response data is written directly to buffer_c_offset
|
||||
// and in this case we don't have any BufferDescriptorC on the request.
|
||||
if (command_header->buf_c_descriptor_flags >
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::InlineDescriptor) {
|
||||
if (command_header->buf_c_descriptor_flags ==
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
|
||||
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
|
||||
} else {
|
||||
unsigned num_buf_c_descriptors =
|
||||
static_cast<unsigned>(command_header->buf_c_descriptor_flags.Value()) - 2;
|
||||
|
||||
// This is used to detect possible underflows, in case something is broken
|
||||
// with the two ifs above and the flags value is == 0 || == 1.
|
||||
ASSERT(num_buf_c_descriptors < 14);
|
||||
|
||||
for (unsigned i = 0; i < num_buf_c_descriptors; ++i) {
|
||||
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rp.SetCurrentOffset(data_payload_offset);
|
||||
|
||||
command = rp.Pop<u32_le>();
|
||||
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
|
||||
}
|
||||
@@ -182,7 +209,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
|
||||
|
||||
for (auto& object : domain_objects) {
|
||||
request_handlers.emplace_back(object);
|
||||
dst_cmdbuf[domain_offset++] = request_handlers.size();
|
||||
dst_cmdbuf[domain_offset++] = static_cast<u32_le>(request_handlers.size());
|
||||
}
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
|
||||
@@ -143,6 +143,10 @@ public:
|
||||
return buffer_b_desciptors;
|
||||
}
|
||||
|
||||
const std::vector<IPC::BufferDescriptorC>& BufferDescriptorC() const {
|
||||
return buffer_c_desciptors;
|
||||
}
|
||||
|
||||
const std::unique_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
|
||||
return domain_message_header;
|
||||
}
|
||||
@@ -200,8 +204,10 @@ private:
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_w_desciptors;
|
||||
std::vector<IPC::BufferDescriptorC> buffer_c_desciptors;
|
||||
|
||||
unsigned data_payload_offset{};
|
||||
unsigned buffer_c_offset{};
|
||||
u32_le command{};
|
||||
};
|
||||
|
||||
|
||||
@@ -151,4 +151,4 @@ void ResourceLimitsInit() {
|
||||
|
||||
void ResourceLimitsShutdown() {}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -123,4 +123,4 @@ void ResourceLimitsInit();
|
||||
// Destroys the resource limits
|
||||
void ResourceLimitsShutdown();
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -50,4 +50,4 @@ std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortP
|
||||
return std::make_tuple(std::move(server_port), std::move(client_port));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -72,4 +72,4 @@ private:
|
||||
~ServerPort() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -113,4 +113,4 @@ private:
|
||||
* in the command buffer.
|
||||
*/
|
||||
ResultCode TranslateHLERequest(ServerSession* server_session);
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -9,4 +9,4 @@ namespace Kernel {
|
||||
|
||||
Session::Session() {}
|
||||
Session::~Session() {}
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -24,4 +24,4 @@ public:
|
||||
ServerSession* server = nullptr; ///< The server endpoint of the session.
|
||||
SharedPtr<ClientPort> port; ///< The port that this session is associated with (optional).
|
||||
};
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -98,10 +98,10 @@ public:
|
||||
ResultCode Unmap(Process* target_process, VAddr address);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the shared memory block
|
||||
* @param offset Offset from the start of the shared memory block to get pointer
|
||||
* @return Pointer to the shared memory block from the specified offset
|
||||
*/
|
||||
* Gets a pointer to the shared memory block
|
||||
* @param offset Offset from the start of the shared memory block to get pointer
|
||||
* @return Pointer to the shared memory block from the specified offset
|
||||
*/
|
||||
u8* GetPointer(u32 offset = 0);
|
||||
|
||||
/// Process that created this shared memory block.
|
||||
@@ -129,4 +129,4 @@ private:
|
||||
~SharedMemory() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -57,7 +57,7 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
}
|
||||
|
||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||
static ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address) {
|
||||
static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) {
|
||||
if (!Memory::IsValidVirtualAddress(port_name_address))
|
||||
return ERR_NOT_FOUND;
|
||||
|
||||
@@ -253,8 +253,8 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
|
||||
}
|
||||
|
||||
/// Attempts to locks a mutex, creating it if it does not already exist
|
||||
static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
Handle requesting_thread_handle) {
|
||||
static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
Handle requesting_thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called holding_thread_handle=0x%08X, mutex_addr=0x%llx, "
|
||||
"requesting_current_thread_handle=0x%08X",
|
||||
@@ -278,7 +278,7 @@ static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
}
|
||||
|
||||
/// Unlock a mutex
|
||||
static ResultCode UnlockMutex(VAddr mutex_addr) {
|
||||
static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
|
||||
LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr);
|
||||
|
||||
SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
|
||||
@@ -315,7 +315,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
*result = g_current_process->allowed_thread_priority_mask;
|
||||
break;
|
||||
case GetInfoType::MapRegionBaseAddr:
|
||||
*result = vm_manager.GetAddressSpaceBaseAddr();
|
||||
*result = vm_manager.GetMapRegionBaseAddr();
|
||||
break;
|
||||
case GetInfoType::MapRegionSize:
|
||||
*result = vm_manager.GetAddressSpaceSize();
|
||||
@@ -739,6 +739,18 @@ static ResultCode SetThreadCoreMask(u64, u64, u64) {
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions,
|
||||
u32 remote_permissions) {
|
||||
LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz,
|
||||
local_permissions, remote_permissions);
|
||||
auto sharedMemHandle = SharedMemory::Create(
|
||||
g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz,
|
||||
(Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions);
|
||||
|
||||
CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FunctionDef {
|
||||
using Func = void();
|
||||
@@ -776,12 +788,12 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x17, SvcWrap<ResetSignal>, "ResetSignal"},
|
||||
{0x18, SvcWrap<WaitSynchronization>, "WaitSynchronization"},
|
||||
{0x19, SvcWrap<CancelSynchronization>, "CancelSynchronization"},
|
||||
{0x1A, SvcWrap<LockMutex>, "LockMutex"},
|
||||
{0x1B, SvcWrap<UnlockMutex>, "UnlockMutex"},
|
||||
{0x1A, SvcWrap<ArbitrateLock>, "ArbitrateLock"},
|
||||
{0x1B, SvcWrap<ArbitrateUnlock>, "ArbitrateUnlock"},
|
||||
{0x1C, SvcWrap<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"},
|
||||
{0x1D, SvcWrap<SignalProcessWideKey>, "SignalProcessWideKey"},
|
||||
{0x1E, SvcWrap<GetSystemTick>, "GetSystemTick"},
|
||||
{0x1F, SvcWrap<ConnectToPort>, "ConnectToPort"},
|
||||
{0x1F, SvcWrap<ConnectToNamedPort>, "ConnectToNamedPort"},
|
||||
{0x20, nullptr, "SendSyncRequestLight"},
|
||||
{0x21, SvcWrap<SendSyncRequest>, "SendSyncRequest"},
|
||||
{0x22, nullptr, "SendSyncRequestWithUserBuffer"},
|
||||
@@ -825,12 +837,12 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x48, nullptr, "Unknown"},
|
||||
{0x49, nullptr, "Unknown"},
|
||||
{0x4A, nullptr, "Unknown"},
|
||||
{0x4B, nullptr, "Unknown"},
|
||||
{0x4C, nullptr, "Unknown"},
|
||||
{0x4B, nullptr, "CreateJitMemory"},
|
||||
{0x4C, nullptr, "MapJitMemory"},
|
||||
{0x4D, nullptr, "SleepSystem"},
|
||||
{0x4E, nullptr, "ReadWriteRegister"},
|
||||
{0x4F, nullptr, "SetProcessActivity"},
|
||||
{0x50, nullptr, "CreateSharedMemory"},
|
||||
{0x50, SvcWrap<CreateSharedMemory>, "CreateSharedMemory"},
|
||||
{0x51, nullptr, "MapTransferMemory"},
|
||||
{0x52, nullptr, "UnmapTransferMemory"},
|
||||
{0x53, nullptr, "CreateInterruptEvent"},
|
||||
|
||||
@@ -14,7 +14,11 @@ struct MemoryInfo {
|
||||
u32 type;
|
||||
u32 attributes;
|
||||
u32 permission;
|
||||
u32 device_refcount;
|
||||
u32 ipc_refcount;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
};
|
||||
static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size.");
|
||||
|
||||
struct PageInfo {
|
||||
u64 flags;
|
||||
|
||||
@@ -145,6 +145,15 @@ void SvcWrap() {
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(Handle*, u64, u32, u32)>
|
||||
void SvcWrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval =
|
||||
func(¶m_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (u32)(PARAM(3) & 0xFFFFFFFF)).raw;
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Function wrappers that return type u32
|
||||
|
||||
|
||||
@@ -111,4 +111,4 @@ void TimersInit() {
|
||||
|
||||
void TimersShutdown() {}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -76,4 +76,4 @@ void TimersInit();
|
||||
/// Tears down the timer variables
|
||||
void TimersShutdown();
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -375,6 +375,11 @@ u64 VMManager::GetAddressSpaceSize() {
|
||||
return MAX_ADDRESS;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetMapRegionBaseAddr() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return Memory::HEAP_VADDR;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetNewMapRegionBaseAddr() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x8000000;
|
||||
|
||||
@@ -192,6 +192,9 @@ public:
|
||||
/// Gets the total address space address size, used by svcGetInfo
|
||||
u64 GetAddressSpaceSize();
|
||||
|
||||
/// Gets the map region base address, used by svcGetInfo
|
||||
VAddr GetMapRegionBaseAddr();
|
||||
|
||||
/// Gets the base address for a new memory region, used by svcGetInfo
|
||||
VAddr GetNewMapRegionBaseAddr();
|
||||
|
||||
|
||||
@@ -9,15 +9,76 @@
|
||||
namespace Service {
|
||||
namespace Account {
|
||||
|
||||
class IProfile final : public ServiceFramework<IProfile> {
|
||||
public:
|
||||
IProfile() : ServiceFramework("IProfile") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IProfile::GetBase, "GetBase"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetBase(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
ProfileBase profile_base{};
|
||||
IPC::RequestBuilder rb{ctx, 16};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(profile_base);
|
||||
}
|
||||
};
|
||||
|
||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||
public:
|
||||
IManagerForApplication() : ServiceFramework("IProfile") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void CheckAvailability(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(true); // TODO: Check when this is supposed to return true and when not
|
||||
}
|
||||
};
|
||||
|
||||
void ACC_U0::GetUserExistence(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(true); // TODO: Check when this is supposed to return true and when not
|
||||
}
|
||||
|
||||
void ACC_U0::GetProfile(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProfile>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void ACC_U0::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void ACC_U0::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IManagerForApplication>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
ACC_U0::ACC_U0() : ServiceFramework("acc:u0") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &ACC_U0::GetUserExistence, "GetUserExistence"},
|
||||
{5, &ACC_U0::GetProfile, "GetProfile"},
|
||||
{100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
|
||||
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -9,13 +9,28 @@
|
||||
namespace Service {
|
||||
namespace Account {
|
||||
|
||||
// TODO: RE this structure
|
||||
struct UserData {
|
||||
INSERT_PADDING_BYTES(0x80);
|
||||
};
|
||||
static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size");
|
||||
|
||||
// TODO: RE this structure
|
||||
struct ProfileBase {
|
||||
INSERT_PADDING_BYTES(0x38);
|
||||
};
|
||||
static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
|
||||
|
||||
class ACC_U0 final : public ServiceFramework<ACC_U0> {
|
||||
public:
|
||||
ACC_U0();
|
||||
~ACC_U0() = default;
|
||||
|
||||
private:
|
||||
void GetUserExistence(Kernel::HLERequestContext& ctx);
|
||||
void GetProfile(Kernel::HLERequestContext& ctx);
|
||||
void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
|
||||
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Account
|
||||
|
||||
@@ -55,6 +55,8 @@ class ISelfController final : public ServiceFramework<ISelfController> {
|
||||
public:
|
||||
ISelfController() : ServiceFramework("ISelfController") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &ISelfController::LockExit, "LockExit"},
|
||||
{2, &ISelfController::UnlockExit, "UnlockExit"},
|
||||
{11, &ISelfController::SetOperationModeChangedNotification,
|
||||
"SetOperationModeChangedNotification"},
|
||||
{12, &ISelfController::SetPerformanceModeChangedNotification,
|
||||
@@ -128,6 +130,20 @@ private:
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
|
||||
}
|
||||
|
||||
void LockExit(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void UnlockExit(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
};
|
||||
|
||||
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
|
||||
@@ -201,10 +217,77 @@ private:
|
||||
Kernel::SharedPtr<Kernel::Event> event;
|
||||
};
|
||||
|
||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||
public:
|
||||
explicit IStorageAccessor(std::vector<u8> buffer)
|
||||
: ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorageAccessor::GetSize, "GetSize"},
|
||||
{11, &IStorageAccessor::Read, "Read"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<u8> buffer;
|
||||
|
||||
void GetSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(buffer.size()));
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void Read(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
u64 offset = rp.Pop<u64>();
|
||||
|
||||
const auto& output_buffer = ctx.BufferDescriptorC()[0];
|
||||
|
||||
ASSERT(offset + output_buffer.Size() <= buffer.size());
|
||||
|
||||
Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
class IStorage final : public ServiceFramework<IStorage> {
|
||||
public:
|
||||
explicit IStorage(std::vector<u8> buffer)
|
||||
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorage::Open, "Open"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<u8> buffer;
|
||||
|
||||
void Open(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
|
||||
public:
|
||||
IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
|
||||
{21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
|
||||
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
|
||||
{66, &IApplicationFunctions::InitializeGamePlayRecording,
|
||||
"InitializeGamePlayRecording"},
|
||||
@@ -215,6 +298,26 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void PopLaunchParameter(Kernel::HLERequestContext& ctx) {
|
||||
constexpr u8 data[0x88] = {
|
||||
0xca, 0x97, 0x94, 0xc7, // Magic
|
||||
1, 0, 0, 0, // IsAccountSelected (bool)
|
||||
1, 0, 0, 0, // User Id (word 0)
|
||||
0, 0, 0, 0, // User Id (word 1)
|
||||
0, 0, 0, 0, // User Id (word 2)
|
||||
0, 0, 0, 0 // User Id (word 3)
|
||||
};
|
||||
|
||||
std::vector<u8> buffer(data, data + sizeof(data));
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorage>(buffer);
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void SetTerminateResult(Kernel::HLERequestContext& ctx) {
|
||||
// Takes an input u32 Result, no output.
|
||||
// For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
|
||||
@@ -228,6 +331,13 @@ private:
|
||||
LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
|
||||
}
|
||||
|
||||
void GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(SystemLanguage::English);
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
namespace Service {
|
||||
namespace AM {
|
||||
|
||||
// TODO: Add more languages
|
||||
enum SystemLanguage {
|
||||
Japanese = 0,
|
||||
English = 1,
|
||||
};
|
||||
|
||||
class AppletOE final : public ServiceFramework<AppletOE> {
|
||||
public:
|
||||
AppletOE();
|
||||
|
||||
@@ -51,7 +51,8 @@ private:
|
||||
|
||||
APM::APM() : ServiceFramework("apm") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &APM::OpenSession, "OpenSession"}, {0x00000001, nullptr, "GetPerformanceMode"},
|
||||
{0x00000000, &APM::OpenSession, "OpenSession"},
|
||||
{0x00000001, nullptr, "GetPerformanceMode"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ private:
|
||||
|
||||
/// Log field type
|
||||
enum class Field : u8 {
|
||||
Skip = 1,
|
||||
Message = 2,
|
||||
Line = 3,
|
||||
Filename = 4,
|
||||
@@ -85,6 +86,11 @@ private:
|
||||
while (addr < end_addr) {
|
||||
const Field field{static_cast<Field>(Memory::Read8(addr++))};
|
||||
size_t length{Memory::Read8(addr++)};
|
||||
|
||||
if (static_cast<Field>(Memory::Read8(addr)) == Field::Skip) {
|
||||
++addr;
|
||||
}
|
||||
|
||||
switch (field) {
|
||||
case Field::Message:
|
||||
message = Memory::ReadCString(addr, length);
|
||||
@@ -99,6 +105,7 @@ private:
|
||||
function = Memory::ReadCString(addr, length);
|
||||
break;
|
||||
}
|
||||
|
||||
addr += length;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,20 +22,21 @@ VAddr nvmap::GetObjectAddress(u32 handle) const {
|
||||
}
|
||||
|
||||
u32 nvmap::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
switch (command) {
|
||||
case IocCreateCommand:
|
||||
switch (static_cast<IoctlCommand>(command)) {
|
||||
case IoctlCommand::Create:
|
||||
return IocCreate(input, output);
|
||||
case IocAllocCommand:
|
||||
case IoctlCommand::Alloc:
|
||||
return IocAlloc(input, output);
|
||||
case IocGetIdCommand:
|
||||
case IoctlCommand::GetId:
|
||||
return IocGetId(input, output);
|
||||
case IocFromIdCommand:
|
||||
case IoctlCommand::FromId:
|
||||
return IocFromId(input, output);
|
||||
case IocParamCommand:
|
||||
case IoctlCommand::Param:
|
||||
return IocParam(input, output);
|
||||
}
|
||||
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
|
||||
@@ -48,12 +48,12 @@ private:
|
||||
/// Mapping of currently allocated handles to the objects they represent.
|
||||
std::unordered_map<u32, std::shared_ptr<Object>> handles;
|
||||
|
||||
enum IoctlCommands {
|
||||
IocCreateCommand = 0xC0080101,
|
||||
IocFromIdCommand = 0xC0080103,
|
||||
IocAllocCommand = 0xC0200104,
|
||||
IocParamCommand = 0xC00C0109,
|
||||
IocGetIdCommand = 0xC008010E
|
||||
enum class IoctlCommand : u32 {
|
||||
Create = 0xC0080101,
|
||||
FromId = 0xC0080103,
|
||||
Alloc = 0xC0200104,
|
||||
Param = 0xC00C0109,
|
||||
GetId = 0xC008010E
|
||||
};
|
||||
|
||||
struct IocCreateParams {
|
||||
|
||||
@@ -48,6 +48,18 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(nv_result);
|
||||
}
|
||||
|
||||
void NVDRV::Close(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
u32 fd = rp.Pop<u32>();
|
||||
|
||||
auto result = nvdrv->Close(fd);
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(result);
|
||||
}
|
||||
|
||||
void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
@@ -55,12 +67,25 @@ void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
u64 pid = rp.Pop<u64>();
|
||||
u64 unk = rp.Pop<u64>();
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called, pid=0x%llx, unk=0x%llx", pid, unk);
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
|
||||
: ServiceFramework(name), nvdrv(std::move(nvdrv)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &NVDRV::Open, "Open"},
|
||||
{1, &NVDRV::Ioctl, "Ioctl"},
|
||||
{2, &NVDRV::Close, "Close"},
|
||||
{3, &NVDRV::Initialize, "Initialize"},
|
||||
{8, &NVDRV::SetClientPID, "SetClientPID"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ public:
|
||||
private:
|
||||
void Open(Kernel::HLERequestContext& ctx);
|
||||
void Ioctl(Kernel::HLERequestContext& ctx);
|
||||
void Close(Kernel::HLERequestContext& ctx);
|
||||
void Initialize(Kernel::HLERequestContext& ctx);
|
||||
void SetClientPID(Kernel::HLERequestContext& ctx);
|
||||
|
||||
std::shared_ptr<Module> nvdrv;
|
||||
};
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvmap.h"
|
||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||
#include "core/hle/service/nvdrv/interface.h"
|
||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Nvidia {
|
||||
@@ -49,5 +49,15 @@ u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector
|
||||
return device->ioctl(command, input, output);
|
||||
}
|
||||
|
||||
ResultCode Module::Close(u32 fd) {
|
||||
auto itr = open_files.find(fd);
|
||||
ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
|
||||
|
||||
open_files.erase(itr);
|
||||
|
||||
// TODO(flerovium): return correct result code if operation failed.
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Nvidia
|
||||
} // namespace Service
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
u32 Open(std::string device_name);
|
||||
/// Sends an ioctl command to the specified file descriptor.
|
||||
u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output);
|
||||
/// Closes a device file descriptor and returns operation success.
|
||||
ResultCode Close(u32 fd);
|
||||
|
||||
private:
|
||||
/// Id to use for the next open file descriptor.
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#include "core/hle/service/nvdrv/nvdrv.h"
|
||||
#include "core/hle/service/pctl/pctl.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/set/set.h"
|
||||
#include "core/hle/service/sm/controller.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "core/hle/service/sockets/sockets.h"
|
||||
#include "core/hle/service/time/time.h"
|
||||
#include "core/hle/service/vi/vi.h"
|
||||
|
||||
@@ -174,8 +176,10 @@ void Init() {
|
||||
LM::InstallInterfaces(*SM::g_service_manager);
|
||||
Nvidia::InstallInterfaces(*SM::g_service_manager);
|
||||
PCTL::InstallInterfaces(*SM::g_service_manager);
|
||||
Sockets::InstallInterfaces(*SM::g_service_manager);
|
||||
Time::InstallInterfaces(*SM::g_service_manager);
|
||||
VI::InstallInterfaces(*SM::g_service_manager);
|
||||
Set::InstallInterfaces(*SM::g_service_manager);
|
||||
|
||||
LOG_DEBUG(Service, "initialized OK");
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class ClientPort;
|
||||
class ServerPort;
|
||||
class ServerSession;
|
||||
class HLERequestContext;
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Service {
|
||||
|
||||
@@ -189,4 +189,4 @@ extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_
|
||||
/// Adds a port to the named port table
|
||||
void AddNamedPort(std::string name, Kernel::SharedPtr<Kernel::ClientPort> port);
|
||||
|
||||
} // namespace
|
||||
} // namespace Service
|
||||
|
||||
42
src/core/hle/service/set/set.cpp
Normal file
42
src/core/hle/service/set/set.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/service/set/set.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Set {
|
||||
|
||||
void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
|
||||
constexpr std::array<u8, 13> lang_codes{};
|
||||
|
||||
const auto& output_buffer = ctx.BufferDescriptorC()[0];
|
||||
|
||||
Memory::WriteBlock(output_buffer.Address(), lang_codes.data(), lang_codes.size());
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(lang_codes.size()));
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
SET::SET(const char* name) : ServiceFramework(name) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<SET>("set")->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Set
|
||||
} // namespace Service
|
||||
25
src/core/hle/service/set/set.h
Normal file
25
src/core/hle/service/set/set.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Set {
|
||||
|
||||
class SET final : public ServiceFramework<SET> {
|
||||
public:
|
||||
explicit SET(const char* name);
|
||||
~SET() = default;
|
||||
|
||||
private:
|
||||
void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
/// Registers all Set services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Set
|
||||
} // namespace Service
|
||||
@@ -32,6 +32,12 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) {
|
||||
DuplicateSession(ctx);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession");
|
||||
}
|
||||
|
||||
void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -46,7 +52,7 @@ Controller::Controller() : ServiceFramework("IpcController") {
|
||||
{0x00000001, nullptr, "ConvertDomainToSession"},
|
||||
{0x00000002, &Controller::DuplicateSession, "DuplicateSession"},
|
||||
{0x00000003, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"},
|
||||
{0x00000004, nullptr, "DuplicateSessionEx"},
|
||||
{0x00000004, &Controller::DuplicateSessionEx, "DuplicateSessionEx"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
private:
|
||||
void ConvertSessionToDomain(Kernel::HLERequestContext& ctx);
|
||||
void DuplicateSession(Kernel::HLERequestContext& ctx);
|
||||
void DuplicateSessionEx(Kernel::HLERequestContext& ctx);
|
||||
void QueryPointerBufferSize(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(client_port.Code());
|
||||
LOG_ERROR(Service_SM, "called service=%s -> error 0x%08X", name.c_str(),
|
||||
client_port.Code().raw);
|
||||
UNIMPLEMENTED();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
67
src/core/hle/service/sockets/bsd_u.cpp
Normal file
67
src/core/hle/service/sockets/bsd_u.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/sockets/bsd_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Sockets {
|
||||
|
||||
void BSD_U::RegisterClient(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0); // bsd errno
|
||||
}
|
||||
|
||||
void BSD_U::Socket(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
u32 domain = rp.Pop<u32>();
|
||||
u32 type = rp.Pop<u32>();
|
||||
u32 protocol = rp.Pop<u32>();
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called domain=%u type=%u protocol=%u", domain, type, protocol);
|
||||
|
||||
u32 fd = next_fd++;
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(fd);
|
||||
rb.Push<u32>(0); // bsd errno
|
||||
}
|
||||
|
||||
void BSD_U::Connect(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0); // ret
|
||||
rb.Push<u32>(0); // bsd errno
|
||||
}
|
||||
|
||||
void BSD_U::SendTo(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0); // ret
|
||||
rb.Push<u32>(0); // bsd errno
|
||||
}
|
||||
|
||||
BSD_U::BSD_U() : ServiceFramework("bsd:u") {
|
||||
static const FunctionInfo functions[] = {{0, &BSD_U::RegisterClient, "RegisterClient"},
|
||||
{2, &BSD_U::Socket, "Socket"},
|
||||
{11, &BSD_U::SendTo, "SendTo"},
|
||||
{14, &BSD_U::Connect, "Connect"}};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Sockets
|
||||
} // namespace Service
|
||||
29
src/core/hle/service/sockets/bsd_u.h
Normal file
29
src/core/hle/service/sockets/bsd_u.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Sockets {
|
||||
|
||||
class BSD_U final : public ServiceFramework<BSD_U> {
|
||||
public:
|
||||
BSD_U();
|
||||
~BSD_U() = default;
|
||||
|
||||
private:
|
||||
void RegisterClient(Kernel::HLERequestContext& ctx);
|
||||
void Socket(Kernel::HLERequestContext& ctx);
|
||||
void Connect(Kernel::HLERequestContext& ctx);
|
||||
void SendTo(Kernel::HLERequestContext& ctx);
|
||||
|
||||
/// Id to use for the next open file descriptor.
|
||||
u32 next_fd = 1;
|
||||
};
|
||||
|
||||
} // namespace Sockets
|
||||
} // namespace Service
|
||||
22
src/core/hle/service/sockets/sfdnsres.h
Normal file
22
src/core/hle/service/sockets/sfdnsres.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Sockets {
|
||||
|
||||
class SFDNSRES final : public ServiceFramework<SFDNSRES> {
|
||||
public:
|
||||
SFDNSRES() : ServiceFramework("sfdnsres") {}
|
||||
~SFDNSRES() = default;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace Sockets
|
||||
} // namespace Service
|
||||
18
src/core/hle/service/sockets/sockets.cpp
Normal file
18
src/core/hle/service/sockets/sockets.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/sockets/bsd_u.h"
|
||||
#include "core/hle/service/sockets/sfdnsres.h"
|
||||
#include "core/hle/service/sockets/sockets.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Sockets {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<BSD_U>()->InstallAsService(service_manager);
|
||||
std::make_shared<SFDNSRES>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Sockets
|
||||
} // namespace Service
|
||||
16
src/core/hle/service/sockets/sockets.h
Normal file
16
src/core/hle/service/sockets/sockets.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Sockets {
|
||||
|
||||
/// Registers all Sockets services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Sockets
|
||||
} // namespace Service
|
||||
@@ -2,14 +2,142 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/service/time/time.h"
|
||||
#include "core/hle/service/time/time_s.h"
|
||||
#include "core/hle/service/time/time_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
class ISystemClock final : public ServiceFramework<ISystemClock> {
|
||||
public:
|
||||
ISystemClock() : ServiceFramework("ISystemClock") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetCurrentTime(Kernel::HLERequestContext& ctx) {
|
||||
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count()};
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(time_since_epoch);
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
class ISteadyClock final : public ServiceFramework<ISteadyClock> {
|
||||
public:
|
||||
ISteadyClock() : ServiceFramework("ISteadyClock") {}
|
||||
};
|
||||
|
||||
class ITimeZoneService final : public ServiceFramework<ITimeZoneService> {
|
||||
public:
|
||||
ITimeZoneService() : ServiceFramework("ITimeZoneService") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
|
||||
{2, &ITimeZoneService::GetTotalLocationNameCount, "GetTotalLocationNameCount"},
|
||||
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetDeviceLocationName(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
LocationName location_name{};
|
||||
IPC::RequestBuilder rb{ctx, (sizeof(LocationName) / 4) + 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(location_name);
|
||||
}
|
||||
|
||||
void GetTotalLocationNameCount(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void ToCalendarTimeWithMyRule(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
u64 posix_time = rp.Pop<u64>();
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called, posix_time=0x%016llX", posix_time);
|
||||
|
||||
CalendarTime calendar_time{2018, 1, 1, 0, 0, 0};
|
||||
CalendarAdditionalInfo additional_info{};
|
||||
IPC::RequestBuilder rb{ctx, 10};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(calendar_time);
|
||||
rb.PushRaw(additional_info);
|
||||
}
|
||||
};
|
||||
|
||||
void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<ISystemClock>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<ISystemClock>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<ISteadyClock>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized ISteadyClock -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ITimeZoneService>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> time, const char* name)
|
||||
: ServiceFramework(name), time(std::move(time)) {}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<TimeS>()->InstallAsService(service_manager);
|
||||
auto time = std::make_shared<Module>();
|
||||
std::make_shared<TIME_S>(time)->InstallAsService(service_manager);
|
||||
std::make_shared<TIME_U>(time)->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Time
|
||||
|
||||
@@ -9,6 +9,46 @@
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
// TODO(Rozelette) RE this structure
|
||||
struct LocationName {
|
||||
INSERT_PADDING_BYTES(0x24);
|
||||
};
|
||||
static_assert(sizeof(LocationName) == 0x24, "LocationName is incorrect size");
|
||||
|
||||
struct CalendarTime {
|
||||
u16_le year;
|
||||
u8 month; // Starts at 1
|
||||
u8 day; // Starts at 1
|
||||
u8 hour;
|
||||
u8 minute;
|
||||
u8 second;
|
||||
INSERT_PADDING_BYTES(1);
|
||||
};
|
||||
static_assert(sizeof(CalendarTime) == 0x8, "CalendarTime structure has incorrect size");
|
||||
|
||||
// TODO(Rozelette) RE this structure
|
||||
struct CalendarAdditionalInfo {
|
||||
INSERT_PADDING_BYTES(0x18);
|
||||
};
|
||||
static_assert(sizeof(CalendarAdditionalInfo) == 0x18,
|
||||
"CalendarAdditionalInfo structure has incorrect size");
|
||||
|
||||
class Module final {
|
||||
public:
|
||||
class Interface : public ServiceFramework<Interface> {
|
||||
public:
|
||||
Interface(std::shared_ptr<Module> time, const char* name);
|
||||
|
||||
void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
|
||||
void GetStandardNetworkSystemClock(Kernel::HLERequestContext& ctx);
|
||||
void GetStandardSteadyClock(Kernel::HLERequestContext& ctx);
|
||||
void GetTimeZoneService(Kernel::HLERequestContext& ctx);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Module> time;
|
||||
};
|
||||
};
|
||||
|
||||
/// Registers all Time services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
|
||||
@@ -2,54 +2,14 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/service/time/time_s.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
class ISystemClock final : public ServiceFramework<ISystemClock> {
|
||||
public:
|
||||
ISystemClock() : ServiceFramework("ISystemClock") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISystemClock::GetCurrentTime, "GetCurrentTime"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetCurrentTime(Kernel::HLERequestContext& ctx) {
|
||||
const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count()};
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(time_since_epoch);
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
void TimeS::GetStandardUserSystemClock(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<ISystemClock>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized ISystemClock -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
TimeS::TimeS() : ServiceFramework("time:s") {
|
||||
TIME_S::TIME_S(std::shared_ptr<Module> time) : Module::Interface(std::move(time), "time:s") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &TimeS::GetStandardUserSystemClock, "GetStandardUserSystemClock"},
|
||||
{0, &TIME_S::GetStandardUserSystemClock, "GetStandardUserSystemClock"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -4,19 +4,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/time/time.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Time {
|
||||
|
||||
class TimeS final : public ServiceFramework<TimeS> {
|
||||
class TIME_S final : public Module::Interface {
|
||||
public:
|
||||
TimeS();
|
||||
~TimeS() = default;
|
||||
|
||||
private:
|
||||
void GetStandardUserSystemClock(Kernel::HLERequestContext& ctx);
|
||||
explicit TIME_S(std::shared_ptr<Module> time);
|
||||
};
|
||||
|
||||
} // namespace Time
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user