Compare commits
222 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ff20dc6a7 | ||
|
|
3dab0e284b | ||
|
|
15e68cdbaa | ||
|
|
e3ca561ea0 | ||
|
|
ddb767f1b6 | ||
|
|
5410b4659d | ||
|
|
a9cacd03f6 | ||
|
|
6e0eba9917 | ||
|
|
65c664560c | ||
|
|
76b475faf7 | ||
|
|
6269a01b4e | ||
|
|
0d46f0df12 | ||
|
|
638956aa81 | ||
|
|
92c7135065 | ||
|
|
a6d4903aaf | ||
|
|
6e4e0b2b41 | ||
|
|
055f1546d7 | ||
|
|
79167fc989 | ||
|
|
9685dd5840 | ||
|
|
18c8ae7750 | ||
|
|
d480b63e0d | ||
|
|
c1f55c32c8 | ||
|
|
0f929762b3 | ||
|
|
4c59105adf | ||
|
|
fca3d1cc65 | ||
|
|
cc73bad293 | ||
|
|
3d41fdfbba | ||
|
|
ca633a5a3c | ||
|
|
80c5e8ae99 | ||
|
|
e9d147349b | ||
|
|
6c0c81dfdc | ||
|
|
a093feca62 | ||
|
|
066d6184d4 | ||
|
|
b611d852db | ||
|
|
85a60e2044 | ||
|
|
f33e406ff2 | ||
|
|
c0e2d52758 | ||
|
|
b11072d54a | ||
|
|
c96da97630 | ||
|
|
50ef2beb58 | ||
|
|
c18425ef98 | ||
|
|
da2bdbc0d7 | ||
|
|
7fa9177830 | ||
|
|
1dd754590f | ||
|
|
8af1ae46aa | ||
|
|
c7c379bd19 | ||
|
|
6a28a66832 | ||
|
|
1bbbd26563 | ||
|
|
3f9f047375 | ||
|
|
ff6785f3e8 | ||
|
|
9f2f819bb6 | ||
|
|
5f57ab1b2a | ||
|
|
84cadf9918 | ||
|
|
10422f3c18 | ||
|
|
dfac394e60 | ||
|
|
73de9bab1a | ||
|
|
0399d98cd9 | ||
|
|
8447d20a11 | ||
|
|
20b58bab9c | ||
|
|
41b3725d28 | ||
|
|
2981408722 | ||
|
|
1669911b1d | ||
|
|
36dedae842 | ||
|
|
1da0ee57fd | ||
|
|
ad39bab271 | ||
|
|
c9e821e93e | ||
|
|
11fb17054e | ||
|
|
838724c588 | ||
|
|
0b831dd2ba | ||
|
|
81f24f5685 | ||
|
|
ea1880f47c | ||
|
|
6d7941042b | ||
|
|
52a78228dd | ||
|
|
a27befe456 | ||
|
|
067ac434ba | ||
|
|
5f8aa02584 | ||
|
|
08d454e30d | ||
|
|
b7162c32a4 | ||
|
|
dc70a87af1 | ||
|
|
63f26d5c40 | ||
|
|
8f8fe62a19 | ||
|
|
62bd1299ea | ||
|
|
4f81bc4e1b | ||
|
|
9d71ce88ce | ||
|
|
c06d6b27f3 | ||
|
|
7e191dccc1 | ||
|
|
c3e95086b6 | ||
|
|
a3d82ef5d9 | ||
|
|
be1f5dedfb | ||
|
|
7a0bb406d5 | ||
|
|
0d8ae773f1 | ||
|
|
1ab133d7fa | ||
|
|
38989bef43 | ||
|
|
eab7457c00 | ||
|
|
0e13d9cb7b | ||
|
|
c11cfaa705 | ||
|
|
4ac4b308e4 | ||
|
|
ea080501fb | ||
|
|
bf4e2b2f0b | ||
|
|
7c7f4a9be2 | ||
|
|
61779fa072 | ||
|
|
d2277b825e | ||
|
|
fe906fff36 | ||
|
|
f9af74201c | ||
|
|
afdd657d30 | ||
|
|
5673ce39c7 | ||
|
|
3c43ea5c68 | ||
|
|
d383043e07 | ||
|
|
fb5bd0920d | ||
|
|
46cbb6b090 | ||
|
|
55c49d5bf4 | ||
|
|
61f9d9c4ab | ||
|
|
acc8fe5a2a | ||
|
|
f969ddb54e | ||
|
|
9f8fbce35b | ||
|
|
94d27b1717 | ||
|
|
ac88d3e89f | ||
|
|
a353322b58 | ||
|
|
50153a1cb2 | ||
|
|
17f3590d59 | ||
|
|
7786f41cc0 | ||
|
|
019d7208c8 | ||
|
|
2015a1b180 | ||
|
|
db0497b808 | ||
|
|
987a170665 | ||
|
|
33dbf24b56 | ||
|
|
2dc8b5c224 | ||
|
|
5f3d6c85db | ||
|
|
2f9c0e7c7e | ||
|
|
09b8a16414 | ||
|
|
004b1b3830 | ||
|
|
281fd881a0 | ||
|
|
2a7653142d | ||
|
|
b366b885a1 | ||
|
|
3cb753eeb1 | ||
|
|
d81aaa3ed3 | ||
|
|
e2176dc7ce | ||
|
|
174c22e5f6 | ||
|
|
5440b9c634 | ||
|
|
abec5f82e2 | ||
|
|
bbc4f369ed | ||
|
|
79e9c2e237 | ||
|
|
83517cb53a | ||
|
|
9949e4d508 | ||
|
|
c116b220e9 | ||
|
|
c011b6f67e | ||
|
|
c712dafaee | ||
|
|
a931cf9e8b | ||
|
|
a941a94148 | ||
|
|
8d9534d830 | ||
|
|
47dc5e0dab | ||
|
|
f3885845fc | ||
|
|
c0d3e2da4e | ||
|
|
517112f549 | ||
|
|
6324d86c71 | ||
|
|
5aff2d38a9 | ||
|
|
ee318d4015 | ||
|
|
86146ef819 | ||
|
|
a2efb1dd48 | ||
|
|
ee1eb8cfdf | ||
|
|
0639e03055 | ||
|
|
930487c7fb | ||
|
|
92209f905f | ||
|
|
f22e090b86 | ||
|
|
218a08df93 | ||
|
|
0cb7ce71e0 | ||
|
|
9f21f20d7c | ||
|
|
128aeba0f3 | ||
|
|
03f877919d | ||
|
|
37f50c8773 | ||
|
|
4732e1f064 | ||
|
|
00c830405b | ||
|
|
4b114e1b8a | ||
|
|
0a49c46353 | ||
|
|
47629c89a8 | ||
|
|
89e81a9be2 | ||
|
|
0ff2929644 | ||
|
|
cfc9effa6c | ||
|
|
4669f15f8b | ||
|
|
4112aa68a6 | ||
|
|
6e386a334b | ||
|
|
dbfc39d214 | ||
|
|
61fbf5c8e6 | ||
|
|
be09dfeed9 | ||
|
|
2f842a86fe | ||
|
|
ce026332a5 | ||
|
|
fa220dd709 | ||
|
|
a776464a55 | ||
|
|
9a85277d83 | ||
|
|
05dc93399b | ||
|
|
39fb3e362c | ||
|
|
566f97b580 | ||
|
|
bf0543af23 | ||
|
|
c5684411a0 | ||
|
|
2abe5e39fc | ||
|
|
adf47cd59a | ||
|
|
c531a92eda | ||
|
|
14afc704d4 | ||
|
|
8d70d1ea45 | ||
|
|
5fb99e6a16 | ||
|
|
5c3d5d0849 | ||
|
|
79de0f8fe8 | ||
|
|
6e8e1a4110 | ||
|
|
9232fbdf34 | ||
|
|
38eb33f150 | ||
|
|
b54a72afc0 | ||
|
|
62cd19e4ae | ||
|
|
7e3d746b06 | ||
|
|
e7dfcdde74 | ||
|
|
8c99dd055c | ||
|
|
799e632ccb | ||
|
|
c23c30c76f | ||
|
|
00749f5ab3 | ||
|
|
6ea1576513 | ||
|
|
81a16c073a | ||
|
|
23b1e6eded | ||
|
|
438a9b70cc | ||
|
|
6cf6fa2842 | ||
|
|
d27279092f | ||
|
|
bb081dd1d2 | ||
|
|
019778707d | ||
|
|
2abf39ea4a |
@@ -42,3 +42,7 @@ notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://api.yuzu-emu.org/code/travis/notify
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.ccache
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
docker run -v $(pwd):/yuzu ubuntu:18.04 /bin/bash /yuzu/.travis/linux/docker.sh
|
||||
docker run -e CCACHE_DIR=/ccache -v $HOME/.ccache:/ccache -v $(pwd):/yuzu ubuntu:18.04 /bin/bash /yuzu/.travis/linux/docker.sh
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
apt-get update
|
||||
apt-get install -y build-essential git libqt5opengl5-dev libsdl2-dev libssl-dev python qtbase5-dev wget
|
||||
|
||||
# Get a recent version of CMake
|
||||
wget https://cmake.org/files/v3.10/cmake-3.10.1-Linux-x86_64.sh
|
||||
sh cmake-3.10.1-Linux-x86_64.sh --exclude-subdir --prefix=/ --skip-license
|
||||
apt-get install --no-install-recommends -y build-essential git libqt5opengl5-dev libsdl2-dev libssl-dev python qtbase5-dev wget cmake ninja-build ccache
|
||||
|
||||
cd /yuzu
|
||||
|
||||
export PATH=/usr/lib/ccache:$PATH
|
||||
ln -sf /usr/bin/ccache /usr/lib/ccache/cc
|
||||
ln -sf /usr/bin/ccache /usr/lib/ccache/c++
|
||||
mkdir build && cd build
|
||||
cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_BUILD_TYPE=Release
|
||||
make -j4
|
||||
ccache --show-stats > ccache_before
|
||||
cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_BUILD_TYPE=Release -G Ninja
|
||||
ninja
|
||||
ccache --show-stats > ccache_after
|
||||
diff -U100 ccache_before ccache_after || true
|
||||
|
||||
ctest -VV -C Release
|
||||
|
||||
@@ -7,8 +7,12 @@ export Qt5_DIR=$(brew --prefix)/opt/qt5
|
||||
export UNICORNDIR=$(pwd)/externals/unicorn
|
||||
|
||||
mkdir build && cd build
|
||||
export PATH=/usr/local/opt/ccache/libexec:$PATH
|
||||
ccache --show-stats > ccache_before
|
||||
cmake --version
|
||||
cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_BUILD_TYPE=Release
|
||||
make -j4
|
||||
ccache --show-stats > ccache_after
|
||||
diff -U100 ccache_before ccache_after || true
|
||||
|
||||
ctest -VV -C Release
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
brew update
|
||||
brew install dylibbundler p7zip qt5 sdl2
|
||||
brew install dylibbundler p7zip qt5 sdl2 ccache
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
|
||||
@@ -3,7 +3,9 @@ function(copy_yuzu_Qt5_deps target_dir)
|
||||
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
||||
set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
|
||||
set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
|
||||
set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/")
|
||||
set(PLATFORMS ${DLL_DEST}platforms/)
|
||||
set(STYLES ${DLL_DEST}styles/)
|
||||
windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
|
||||
icudt*.dll
|
||||
icuin*.dll
|
||||
@@ -14,4 +16,5 @@ function(copy_yuzu_Qt5_deps target_dir)
|
||||
Qt5Widgets$<$<CONFIG:Debug>:d>.*
|
||||
)
|
||||
windows_copy_files(yuzu ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
|
||||
windows_copy_files(yuzu ${Qt5_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*)
|
||||
endfunction(copy_yuzu_Qt5_deps)
|
||||
|
||||
@@ -53,7 +53,7 @@ build_script:
|
||||
# https://www.appveyor.com/docs/build-phase
|
||||
msbuild msvc_build/yuzu.sln /maxcpucount /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
} else {
|
||||
C:\msys64\usr\bin\bash.exe -lc 'mingw32-make -j4 -C mingw_build/ 2>&1'
|
||||
C:\msys64\usr\bin\bash.exe -lc 'mingw32-make -C mingw_build/ 2>&1'
|
||||
}
|
||||
|
||||
after_build:
|
||||
@@ -116,6 +116,7 @@ after_build:
|
||||
|
||||
mkdir $RELEASE_DIST
|
||||
mkdir $RELEASE_DIST/platforms
|
||||
mkdir $RELEASE_DIST/styles
|
||||
|
||||
# copy the compiled binaries and other release files to the release folder
|
||||
Get-ChildItem "$CMAKE_BINARY_DIR" -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
@@ -136,6 +137,9 @@ after_build:
|
||||
# copy the qt windows plugin dll to platforms
|
||||
Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/platforms/qwindows.dll" -force -destination "$RELEASE_DIST/platforms"
|
||||
|
||||
# copy the qt windows vista style dll to platforms
|
||||
Copy-Item -path "C:/msys64/mingw64/share/qt5/plugins/styles/qwindowsvistastyle.dll" -force -destination "$RELEASE_DIST/styles"
|
||||
|
||||
7z a -tzip $MINGW_BUILD_ZIP $RELEASE_DIST\*
|
||||
7z a $MINGW_SEVENZIP $RELEASE_DIST
|
||||
}
|
||||
|
||||
@@ -30,15 +30,14 @@ __declspec(noinline, noreturn)
|
||||
#define ASSERT(_a_) \
|
||||
do \
|
||||
if (!(_a_)) { \
|
||||
assert_noinline_call([] { NGLOG_CRITICAL(Debug, "Assertion Failed!"); }); \
|
||||
assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASSERT_MSG(_a_, ...) \
|
||||
do \
|
||||
if (!(_a_)) { \
|
||||
assert_noinline_call( \
|
||||
[&] { NGLOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
|
||||
assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
@@ -32,12 +32,15 @@
|
||||
#define SDMC_DIR "sdmc"
|
||||
#define NAND_DIR "nand"
|
||||
#define SYSDATA_DIR "sysdata"
|
||||
#define LOG_DIR "log"
|
||||
|
||||
// Filenames
|
||||
// Files in the directory returned by GetUserPath(D_CONFIG_IDX)
|
||||
#define EMU_CONFIG "emu.ini"
|
||||
#define DEBUGGER_CONFIG "debugger.ini"
|
||||
#define LOGGER_CONFIG "logger.ini"
|
||||
// Files in the directory returned by GetUserPath(D_LOGS_IDX)
|
||||
#define LOG_FILE "citra_log.txt"
|
||||
|
||||
// Sys files
|
||||
#define SHARED_FONT "shared_font.bin"
|
||||
|
||||
@@ -118,7 +118,7 @@ bool IsDirectory(const std::string& filename) {
|
||||
#endif
|
||||
|
||||
if (result < 0) {
|
||||
NGLOG_DEBUG(Common_Filesystem, "stat failed on {}: {}", filename, GetLastErrorMsg());
|
||||
LOG_DEBUG(Common_Filesystem, "stat failed on {}: {}", filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -128,29 +128,29 @@ bool IsDirectory(const std::string& filename) {
|
||||
// Deletes a given filename, return true on success
|
||||
// Doesn't supports deleting a directory
|
||||
bool Delete(const std::string& filename) {
|
||||
NGLOG_TRACE(Common_Filesystem, "file {}", filename);
|
||||
LOG_TRACE(Common_Filesystem, "file {}", filename);
|
||||
|
||||
// Return true because we care about the file no
|
||||
// being there, not the actual delete.
|
||||
if (!Exists(filename)) {
|
||||
NGLOG_DEBUG(Common_Filesystem, "{} does not exist", filename);
|
||||
LOG_DEBUG(Common_Filesystem, "{} does not exist", filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We can't delete a directory
|
||||
if (IsDirectory(filename)) {
|
||||
NGLOG_ERROR(Common_Filesystem, "Failed: {} is a directory", filename);
|
||||
LOG_ERROR(Common_Filesystem, "Failed: {} is a directory", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) {
|
||||
NGLOG_ERROR(Common_Filesystem, "DeleteFile failed on {}: {}", filename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "DeleteFile failed on {}: {}", filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (unlink(filename.c_str()) == -1) {
|
||||
NGLOG_ERROR(Common_Filesystem, "unlink failed on {}: {}", filename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "unlink failed on {}: {}", filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@@ -160,16 +160,16 @@ bool Delete(const std::string& filename) {
|
||||
|
||||
// Returns true if successful, or path already exists.
|
||||
bool CreateDir(const std::string& path) {
|
||||
NGLOG_TRACE(Common_Filesystem, "directory {}", path);
|
||||
LOG_TRACE(Common_Filesystem, "directory {}", path);
|
||||
#ifdef _WIN32
|
||||
if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr))
|
||||
return true;
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_ALREADY_EXISTS) {
|
||||
NGLOG_DEBUG(Common_Filesystem, "CreateDirectory failed on {}: already exists", path);
|
||||
LOG_DEBUG(Common_Filesystem, "CreateDirectory failed on {}: already exists", path);
|
||||
return true;
|
||||
}
|
||||
NGLOG_ERROR(Common_Filesystem, "CreateDirectory failed on {}: {}", path, error);
|
||||
LOG_ERROR(Common_Filesystem, "CreateDirectory failed on {}: {}", path, error);
|
||||
return false;
|
||||
#else
|
||||
if (mkdir(path.c_str(), 0755) == 0)
|
||||
@@ -178,11 +178,11 @@ bool CreateDir(const std::string& path) {
|
||||
int err = errno;
|
||||
|
||||
if (err == EEXIST) {
|
||||
NGLOG_DEBUG(Common_Filesystem, "mkdir failed on {}: already exists", path);
|
||||
LOG_DEBUG(Common_Filesystem, "mkdir failed on {}: already exists", path);
|
||||
return true;
|
||||
}
|
||||
|
||||
NGLOG_ERROR(Common_Filesystem, "mkdir failed on {}: {}", path, strerror(err));
|
||||
LOG_ERROR(Common_Filesystem, "mkdir failed on {}: {}", path, strerror(err));
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -190,10 +190,10 @@ bool CreateDir(const std::string& path) {
|
||||
// Creates the full path of fullPath returns true on success
|
||||
bool CreateFullPath(const std::string& fullPath) {
|
||||
int panicCounter = 100;
|
||||
NGLOG_TRACE(Common_Filesystem, "path {}", fullPath);
|
||||
LOG_TRACE(Common_Filesystem, "path {}", fullPath);
|
||||
|
||||
if (FileUtil::Exists(fullPath)) {
|
||||
NGLOG_DEBUG(Common_Filesystem, "path exists {}", fullPath);
|
||||
LOG_DEBUG(Common_Filesystem, "path exists {}", fullPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -209,14 +209,14 @@ bool CreateFullPath(const std::string& fullPath) {
|
||||
// Include the '/' so the first call is CreateDir("/") rather than CreateDir("")
|
||||
std::string const subPath(fullPath.substr(0, position + 1));
|
||||
if (!FileUtil::IsDirectory(subPath) && !FileUtil::CreateDir(subPath)) {
|
||||
NGLOG_ERROR(Common, "CreateFullPath: directory creation failed");
|
||||
LOG_ERROR(Common, "CreateFullPath: directory creation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// A safety check
|
||||
panicCounter--;
|
||||
if (panicCounter <= 0) {
|
||||
NGLOG_ERROR(Common, "CreateFullPath: directory structure is too deep");
|
||||
LOG_ERROR(Common, "CreateFullPath: directory structure is too deep");
|
||||
return false;
|
||||
}
|
||||
position++;
|
||||
@@ -225,11 +225,11 @@ bool CreateFullPath(const std::string& fullPath) {
|
||||
|
||||
// Deletes a directory filename, returns true on success
|
||||
bool DeleteDir(const std::string& filename) {
|
||||
NGLOG_TRACE(Common_Filesystem, "directory {}", filename);
|
||||
LOG_TRACE(Common_Filesystem, "directory {}", filename);
|
||||
|
||||
// check if a directory
|
||||
if (!FileUtil::IsDirectory(filename)) {
|
||||
NGLOG_ERROR(Common_Filesystem, "Not a directory {}", filename);
|
||||
LOG_ERROR(Common_Filesystem, "Not a directory {}", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -240,14 +240,14 @@ bool DeleteDir(const std::string& filename) {
|
||||
if (rmdir(filename.c_str()) == 0)
|
||||
return true;
|
||||
#endif
|
||||
NGLOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// renames file srcFilename to destFilename, returns true on success
|
||||
bool Rename(const std::string& srcFilename, const std::string& destFilename) {
|
||||
NGLOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
|
||||
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
|
||||
#ifdef _WIN32
|
||||
if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(),
|
||||
Common::UTF8ToUTF16W(destFilename).c_str()) == 0)
|
||||
@@ -256,21 +256,21 @@ bool Rename(const std::string& srcFilename, const std::string& destFilename) {
|
||||
if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
|
||||
return true;
|
||||
#endif
|
||||
NGLOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
|
||||
GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
|
||||
GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
// copies file srcFilename to destFilename, returns true on success
|
||||
bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||
NGLOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
|
||||
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
|
||||
#ifdef _WIN32
|
||||
if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(),
|
||||
Common::UTF8ToUTF16W(destFilename).c_str(), FALSE))
|
||||
return true;
|
||||
|
||||
NGLOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
|
||||
GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
|
||||
GetLastErrorMsg());
|
||||
return false;
|
||||
#else
|
||||
|
||||
@@ -282,8 +282,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||
// Open input file
|
||||
FILE* input = fopen(srcFilename.c_str(), "rb");
|
||||
if (!input) {
|
||||
NGLOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
|
||||
destFilename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
|
||||
destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -291,8 +291,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||
FILE* output = fopen(destFilename.c_str(), "wb");
|
||||
if (!output) {
|
||||
fclose(input);
|
||||
NGLOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
|
||||
destFilename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
|
||||
destFilename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -302,8 +302,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||
size_t rnum = fread(buffer, sizeof(char), BSIZE, input);
|
||||
if (rnum != BSIZE) {
|
||||
if (ferror(input) != 0) {
|
||||
NGLOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
|
||||
srcFilename, destFilename, GetLastErrorMsg());
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@@ -311,8 +311,8 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||
// write output
|
||||
size_t wnum = fwrite(buffer, sizeof(char), rnum, output);
|
||||
if (wnum != rnum) {
|
||||
NGLOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
|
||||
destFilename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
|
||||
destFilename, GetLastErrorMsg());
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
@@ -332,12 +332,12 @@ bail:
|
||||
// Returns the size of filename (64bit)
|
||||
u64 GetSize(const std::string& filename) {
|
||||
if (!Exists(filename)) {
|
||||
NGLOG_ERROR(Common_Filesystem, "failed {}: No such file", filename);
|
||||
LOG_ERROR(Common_Filesystem, "failed {}: No such file", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IsDirectory(filename)) {
|
||||
NGLOG_ERROR(Common_Filesystem, "failed {}: is a directory", filename);
|
||||
LOG_ERROR(Common_Filesystem, "failed {}: is a directory", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -348,11 +348,11 @@ u64 GetSize(const std::string& filename) {
|
||||
if (stat(filename.c_str(), &buf) == 0)
|
||||
#endif
|
||||
{
|
||||
NGLOG_TRACE(Common_Filesystem, "{}: {}", filename, buf.st_size);
|
||||
LOG_TRACE(Common_Filesystem, "{}: {}", filename, buf.st_size);
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
NGLOG_ERROR(Common_Filesystem, "Stat failed {}: {}", filename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "Stat failed {}: {}", filename, GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ u64 GetSize(const std::string& filename) {
|
||||
u64 GetSize(const int fd) {
|
||||
struct stat buf;
|
||||
if (fstat(fd, &buf) != 0) {
|
||||
NGLOG_ERROR(Common_Filesystem, "GetSize: stat failed {}: {}", fd, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "GetSize: stat failed {}: {}", fd, GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
return buf.st_size;
|
||||
@@ -371,14 +371,12 @@ u64 GetSize(FILE* f) {
|
||||
// can't use off_t here because it can be 32-bit
|
||||
u64 pos = ftello(f);
|
||||
if (fseeko(f, 0, SEEK_END) != 0) {
|
||||
NGLOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f),
|
||||
GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
u64 size = ftello(f);
|
||||
if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) {
|
||||
NGLOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f),
|
||||
GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "GetSize: seek failed {}: {}", fmt::ptr(f), GetLastErrorMsg());
|
||||
return 0;
|
||||
}
|
||||
return size;
|
||||
@@ -386,10 +384,10 @@ u64 GetSize(FILE* f) {
|
||||
|
||||
// creates an empty file filename, returns true on success
|
||||
bool CreateEmptyFile(const std::string& filename) {
|
||||
NGLOG_TRACE(Common_Filesystem, "{}", filename);
|
||||
LOG_TRACE(Common_Filesystem, "{}", filename);
|
||||
|
||||
if (!FileUtil::IOFile(filename, "wb")) {
|
||||
NGLOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "failed {}: {}", filename, GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -398,7 +396,7 @@ bool CreateEmptyFile(const std::string& filename) {
|
||||
|
||||
bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string& directory,
|
||||
DirectoryEntryCallable callback) {
|
||||
NGLOG_TRACE(Common_Filesystem, "directory {}", directory);
|
||||
LOG_TRACE(Common_Filesystem, "directory {}", directory);
|
||||
|
||||
// How many files + directories we found
|
||||
unsigned found_entries = 0;
|
||||
@@ -556,7 +554,7 @@ std::string GetCurrentDir() {
|
||||
char* dir;
|
||||
if (!(dir = getcwd(nullptr, 0))) {
|
||||
#endif
|
||||
NGLOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: {}", GetLastErrorMsg());
|
||||
return nullptr;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
@@ -676,7 +674,7 @@ std::string GetSysDirectory() {
|
||||
#endif
|
||||
sysDir += DIR_SEP;
|
||||
|
||||
NGLOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir);
|
||||
LOG_DEBUG(Common_Filesystem, "Setting to {}:", sysDir);
|
||||
return sysDir;
|
||||
}
|
||||
|
||||
@@ -692,7 +690,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string& new
|
||||
if (!FileUtil::IsDirectory(paths[D_USER_IDX])) {
|
||||
paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP;
|
||||
} else {
|
||||
NGLOG_INFO(Common_Filesystem, "Using the local user directory");
|
||||
LOG_INFO(Common_Filesystem, "Using the local user directory");
|
||||
}
|
||||
|
||||
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
|
||||
@@ -715,11 +713,13 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string& new
|
||||
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP;
|
||||
paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP;
|
||||
paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP;
|
||||
// TODO: Put the logs in a better location for each OS
|
||||
paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOG_DIR DIR_SEP;
|
||||
}
|
||||
|
||||
if (!newPath.empty()) {
|
||||
if (!FileUtil::IsDirectory(newPath)) {
|
||||
NGLOG_ERROR(Common_Filesystem, "Invalid path specified {}", newPath);
|
||||
LOG_ERROR(Common_Filesystem, "Invalid path specified {}", newPath);
|
||||
return paths[DirIDX];
|
||||
} else {
|
||||
paths[DirIDX] = newPath;
|
||||
@@ -801,8 +801,8 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
|
||||
|
||||
IOFile::IOFile() {}
|
||||
|
||||
IOFile::IOFile(const std::string& filename, const char openmode[]) {
|
||||
Open(filename, openmode);
|
||||
IOFile::IOFile(const std::string& filename, const char openmode[], int flags) {
|
||||
Open(filename, openmode, flags);
|
||||
}
|
||||
|
||||
IOFile::~IOFile() {
|
||||
@@ -823,11 +823,16 @@ void IOFile::Swap(IOFile& other) noexcept {
|
||||
std::swap(m_good, other.m_good);
|
||||
}
|
||||
|
||||
bool IOFile::Open(const std::string& filename, const char openmode[]) {
|
||||
bool IOFile::Open(const std::string& filename, const char openmode[], int flags) {
|
||||
Close();
|
||||
#ifdef _WIN32
|
||||
_wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(),
|
||||
Common::UTF8ToUTF16W(openmode).c_str());
|
||||
if (flags != 0) {
|
||||
m_file = _wfsopen(Common::UTF8ToUTF16W(filename).c_str(),
|
||||
Common::UTF8ToUTF16W(openmode).c_str(), flags);
|
||||
} else {
|
||||
_wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(),
|
||||
Common::UTF8ToUTF16W(openmode).c_str());
|
||||
}
|
||||
#else
|
||||
m_file = fopen(filename.c_str(), openmode);
|
||||
#endif
|
||||
|
||||
@@ -156,7 +156,10 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
|
||||
class IOFile : public NonCopyable {
|
||||
public:
|
||||
IOFile();
|
||||
IOFile(const std::string& filename, const char openmode[]);
|
||||
// flags is used for windows specific file open mode flags, which
|
||||
// allows yuzu to open the logs in shared write mode, so that the file
|
||||
// isn't considered "locked" while yuzu is open and people can open the log file and view it
|
||||
IOFile(const std::string& filename, const char openmode[], int flags = 0);
|
||||
|
||||
~IOFile();
|
||||
|
||||
@@ -165,7 +168,7 @@ public:
|
||||
|
||||
void Swap(IOFile& other) noexcept;
|
||||
|
||||
bool Open(const std::string& filename, const char openmode[]);
|
||||
bool Open(const std::string& filename, const char openmode[], int flags = 0);
|
||||
bool Close();
|
||||
|
||||
template <typename T>
|
||||
@@ -220,6 +223,10 @@ public:
|
||||
return WriteArray(&object, 1);
|
||||
}
|
||||
|
||||
size_t WriteString(const std::string& str) {
|
||||
return WriteArray(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
bool IsOpen() const {
|
||||
return nullptr != m_file;
|
||||
}
|
||||
|
||||
@@ -2,16 +2,145 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#ifdef _WIN32
|
||||
#include <share.h> // For _SH_DENYWR
|
||||
#else
|
||||
#define _SH_DENYWR 0
|
||||
#endif
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h" // snprintf compatibility define
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/filter.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/logging/text_formatter.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/threadsafe_queue.h"
|
||||
|
||||
namespace Log {
|
||||
|
||||
/**
|
||||
* Static state as a singleton.
|
||||
*/
|
||||
class Impl {
|
||||
public:
|
||||
static Impl& Instance() {
|
||||
static Impl backend;
|
||||
return backend;
|
||||
}
|
||||
|
||||
Impl(Impl const&) = delete;
|
||||
const Impl& operator=(Impl const&) = delete;
|
||||
|
||||
void PushEntry(Entry e) {
|
||||
std::lock_guard<std::mutex> lock(message_mutex);
|
||||
message_queue.Push(std::move(e));
|
||||
message_cv.notify_one();
|
||||
}
|
||||
|
||||
void AddBackend(std::unique_ptr<Backend> backend) {
|
||||
std::lock_guard<std::mutex> lock(writing_mutex);
|
||||
backends.push_back(std::move(backend));
|
||||
}
|
||||
|
||||
void RemoveBackend(const std::string& backend_name) {
|
||||
std::lock_guard<std::mutex> lock(writing_mutex);
|
||||
auto it = std::remove_if(backends.begin(), backends.end(), [&backend_name](const auto& i) {
|
||||
return !strcmp(i->GetName(), backend_name.c_str());
|
||||
});
|
||||
backends.erase(it, backends.end());
|
||||
}
|
||||
|
||||
const Filter& GetGlobalFilter() const {
|
||||
return filter;
|
||||
}
|
||||
|
||||
void SetGlobalFilter(const Filter& f) {
|
||||
filter = f;
|
||||
}
|
||||
|
||||
Backend* GetBackend(const std::string& backend_name) {
|
||||
auto it = std::find_if(backends.begin(), backends.end(), [&backend_name](const auto& i) {
|
||||
return !strcmp(i->GetName(), backend_name.c_str());
|
||||
});
|
||||
if (it == backends.end())
|
||||
return nullptr;
|
||||
return it->get();
|
||||
}
|
||||
|
||||
private:
|
||||
Impl() {
|
||||
backend_thread = std::thread([&] {
|
||||
Entry entry;
|
||||
auto write_logs = [&](Entry& e) {
|
||||
std::lock_guard<std::mutex> lock(writing_mutex);
|
||||
for (const auto& backend : backends) {
|
||||
backend->Write(e);
|
||||
}
|
||||
};
|
||||
while (true) {
|
||||
std::unique_lock<std::mutex> lock(message_mutex);
|
||||
message_cv.wait(lock, [&] { return !running || message_queue.Pop(entry); });
|
||||
if (!running) {
|
||||
break;
|
||||
}
|
||||
write_logs(entry);
|
||||
}
|
||||
// Drain the logging queue. Only writes out up to MAX_LOGS_TO_WRITE to prevent a case
|
||||
// where a system is repeatedly spamming logs even on close.
|
||||
constexpr int MAX_LOGS_TO_WRITE = 100;
|
||||
int logs_written = 0;
|
||||
while (logs_written++ < MAX_LOGS_TO_WRITE && message_queue.Pop(entry)) {
|
||||
write_logs(entry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
~Impl() {
|
||||
running = false;
|
||||
message_cv.notify_one();
|
||||
backend_thread.join();
|
||||
}
|
||||
|
||||
std::atomic_bool running{true};
|
||||
std::mutex message_mutex, writing_mutex;
|
||||
std::condition_variable message_cv;
|
||||
std::thread backend_thread;
|
||||
std::vector<std::unique_ptr<Backend>> backends;
|
||||
Common::MPSCQueue<Log::Entry> message_queue;
|
||||
Filter filter;
|
||||
};
|
||||
|
||||
void ConsoleBackend::Write(const Entry& entry) {
|
||||
PrintMessage(entry);
|
||||
}
|
||||
|
||||
void ColorConsoleBackend::Write(const Entry& entry) {
|
||||
PrintColoredMessage(entry);
|
||||
}
|
||||
|
||||
// _SH_DENYWR allows read only access to the file for other programs.
|
||||
// It is #defined to 0 on other platforms
|
||||
FileBackend::FileBackend(const std::string& filename)
|
||||
: file(filename, "w", _SH_DENYWR), bytes_written(0) {}
|
||||
|
||||
void FileBackend::Write(const Entry& entry) {
|
||||
// prevent logs from going over the maximum size (in case its spamming and the user doesn't
|
||||
// know)
|
||||
constexpr size_t MAX_BYTES_WRITTEN = 50 * 1024L * 1024L;
|
||||
if (!file.IsOpen() || bytes_written > MAX_BYTES_WRITTEN) {
|
||||
return;
|
||||
}
|
||||
bytes_written += file.WriteString(FormatLogMessage(entry) + '\n');
|
||||
if (entry.log_level >= Level::Error) {
|
||||
file.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
|
||||
#define ALL_LOG_CLASSES() \
|
||||
CLS(Log) \
|
||||
@@ -41,6 +170,7 @@ namespace Log {
|
||||
SUB(Service, FS) \
|
||||
SUB(Service, HID) \
|
||||
SUB(Service, LM) \
|
||||
SUB(Service, MM) \
|
||||
SUB(Service, NFP) \
|
||||
SUB(Service, NIFM) \
|
||||
SUB(Service, NS) \
|
||||
@@ -124,20 +254,32 @@ Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsign
|
||||
return entry;
|
||||
}
|
||||
|
||||
static Filter* filter = nullptr;
|
||||
void SetGlobalFilter(const Filter& filter) {
|
||||
Impl::Instance().SetGlobalFilter(filter);
|
||||
}
|
||||
|
||||
void SetFilter(Filter* new_filter) {
|
||||
filter = new_filter;
|
||||
void AddBackend(std::unique_ptr<Backend> backend) {
|
||||
Impl::Instance().AddBackend(std::move(backend));
|
||||
}
|
||||
|
||||
void RemoveBackend(const std::string& backend_name) {
|
||||
Impl::Instance().RemoveBackend(backend_name);
|
||||
}
|
||||
|
||||
Backend* GetBackend(const std::string& backend_name) {
|
||||
return Impl::Instance().GetBackend(backend_name);
|
||||
}
|
||||
|
||||
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
|
||||
unsigned int line_num, const char* function, const char* format,
|
||||
const fmt::format_args& args) {
|
||||
if (filter && !filter->CheckMessage(log_class, log_level))
|
||||
auto filter = Impl::Instance().GetGlobalFilter();
|
||||
if (!filter.CheckMessage(log_class, log_level))
|
||||
return;
|
||||
|
||||
Entry entry =
|
||||
CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
|
||||
|
||||
PrintColoredMessage(entry);
|
||||
Impl::Instance().PushEntry(std::move(entry));
|
||||
}
|
||||
} // namespace Log
|
||||
} // namespace Log
|
||||
@@ -1,13 +1,15 @@
|
||||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdarg>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/filter.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace Log {
|
||||
@@ -34,6 +36,80 @@ struct Entry {
|
||||
Entry& operator=(const Entry& o) = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for logging backends. As loggers can be created and removed at runtime, this can be
|
||||
* used by a frontend for adding a custom logging backend as needed
|
||||
*/
|
||||
class Backend {
|
||||
public:
|
||||
virtual ~Backend() = default;
|
||||
virtual void SetFilter(const Filter& new_filter) {
|
||||
filter = new_filter;
|
||||
}
|
||||
virtual const char* GetName() const = 0;
|
||||
virtual void Write(const Entry& entry) = 0;
|
||||
|
||||
private:
|
||||
Filter filter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Backend that writes to stderr without any color commands
|
||||
*/
|
||||
class ConsoleBackend : public Backend {
|
||||
public:
|
||||
static const char* Name() {
|
||||
return "console";
|
||||
}
|
||||
const char* GetName() const override {
|
||||
return Name();
|
||||
}
|
||||
void Write(const Entry& entry) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Backend that writes to stderr and with color
|
||||
*/
|
||||
class ColorConsoleBackend : public Backend {
|
||||
public:
|
||||
static const char* Name() {
|
||||
return "color_console";
|
||||
}
|
||||
|
||||
const char* GetName() const override {
|
||||
return Name();
|
||||
}
|
||||
void Write(const Entry& entry) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Backend that writes to a file passed into the constructor
|
||||
*/
|
||||
class FileBackend : public Backend {
|
||||
public:
|
||||
explicit FileBackend(const std::string& filename);
|
||||
|
||||
static const char* Name() {
|
||||
return "file";
|
||||
}
|
||||
|
||||
const char* GetName() const override {
|
||||
return Name();
|
||||
}
|
||||
|
||||
void Write(const Entry& entry) override;
|
||||
|
||||
private:
|
||||
FileUtil::IOFile file;
|
||||
size_t bytes_written;
|
||||
};
|
||||
|
||||
void AddBackend(std::unique_ptr<Backend> backend);
|
||||
|
||||
void RemoveBackend(const std::string& backend_name);
|
||||
|
||||
Backend* GetBackend(const std::string& backend_name);
|
||||
|
||||
/**
|
||||
* Returns the name of the passed log class as a C-string. Subclasses are separated by periods
|
||||
* instead of underscores as in the enumeration.
|
||||
@@ -49,5 +125,10 @@ const char* GetLevelName(Level log_level);
|
||||
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
|
||||
const char* function, std::string message);
|
||||
|
||||
void SetFilter(Filter* filter);
|
||||
} // namespace Log
|
||||
/**
|
||||
* The global filter will prevent any messages from even being processed if they are filtered. Each
|
||||
* backend can have a filter, but if the level is lower than the global filter, the backend will
|
||||
* never get the message
|
||||
*/
|
||||
void SetGlobalFilter(const Filter& filter);
|
||||
} // namespace Log
|
||||
@@ -65,14 +65,14 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
|
||||
const std::string::const_iterator end) {
|
||||
auto level_separator = std::find(begin, end, ':');
|
||||
if (level_separator == end) {
|
||||
NGLOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: %s",
|
||||
std::string(begin, end).c_str());
|
||||
LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}",
|
||||
std::string(begin, end));
|
||||
return false;
|
||||
}
|
||||
|
||||
const Level level = GetLevelByName(level_separator + 1, end);
|
||||
if (level == Level::Count) {
|
||||
NGLOG_ERROR(Log, "Unknown log level in filter: %s", std::string(begin, end).c_str());
|
||||
LOG_ERROR(Log, "Unknown log level in filter: {}", std::string(begin, end));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
|
||||
|
||||
const Class log_class = GetClassByName(begin, level_separator);
|
||||
if (log_class == Class::Count) {
|
||||
NGLOG_ERROR(Log, "Unknown log class in filter: %s", std::string(begin, end).c_str());
|
||||
LOG_ERROR(Log, "Unknown log class in filter: {}", std::string(begin, end));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ enum class Class : ClassType {
|
||||
Service_FS, ///< The FS (Filesystem) service
|
||||
Service_HID, ///< The HID (Human interface device) service
|
||||
Service_LM, ///< The LM (Logger) service
|
||||
Service_MM, ///< The MM (Multimedia) service
|
||||
Service_NFP, ///< The NFP service
|
||||
Service_NIFM, ///< The NIFM (Network interface) service
|
||||
Service_NS, ///< The NS services
|
||||
@@ -108,25 +109,25 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
|
||||
} // namespace Log
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define NGLOG_TRACE(log_class, ...) \
|
||||
#define LOG_TRACE(log_class, ...) \
|
||||
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
#else
|
||||
#define NGLOG_TRACE(log_class, fmt, ...) (void(0))
|
||||
#define LOG_TRACE(log_class, fmt, ...) (void(0))
|
||||
#endif
|
||||
|
||||
#define NGLOG_DEBUG(log_class, ...) \
|
||||
#define LOG_DEBUG(log_class, ...) \
|
||||
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
#define NGLOG_INFO(log_class, ...) \
|
||||
#define LOG_INFO(log_class, ...) \
|
||||
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
#define NGLOG_WARNING(log_class, ...) \
|
||||
#define LOG_WARNING(log_class, ...) \
|
||||
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
#define NGLOG_ERROR(log_class, ...) \
|
||||
#define LOG_ERROR(log_class, ...) \
|
||||
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
#define NGLOG_CRITICAL(log_class, ...) \
|
||||
#define LOG_CRITICAL(log_class, ...) \
|
||||
::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
|
||||
@@ -55,7 +55,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
|
||||
if (ptr == MAP_FAILED) {
|
||||
ptr = nullptr;
|
||||
#endif
|
||||
NGLOG_ERROR(Common_Memory, "Failed to allocate executable memory");
|
||||
LOG_ERROR(Common_Memory, "Failed to allocate executable memory");
|
||||
}
|
||||
#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT)
|
||||
else {
|
||||
@@ -68,7 +68,7 @@ void* AllocateExecutableMemory(size_t size, bool low) {
|
||||
|
||||
#if EMU_ARCH_BITS == 64
|
||||
if ((u64)ptr >= 0x80000000 && low == true)
|
||||
NGLOG_ERROR(Common_Memory, "Executable memory ended up above 2GB!");
|
||||
LOG_ERROR(Common_Memory, "Executable memory ended up above 2GB!");
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
@@ -85,7 +85,7 @@ void* AllocateMemoryPages(size_t size) {
|
||||
#endif
|
||||
|
||||
if (ptr == nullptr)
|
||||
NGLOG_ERROR(Common_Memory, "Failed to allocate raw memory");
|
||||
LOG_ERROR(Common_Memory, "Failed to allocate raw memory");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -99,12 +99,12 @@ void* AllocateAlignedMemory(size_t size, size_t alignment) {
|
||||
ptr = memalign(alignment, size);
|
||||
#else
|
||||
if (posix_memalign(&ptr, alignment, size) != 0)
|
||||
NGLOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
|
||||
LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (ptr == nullptr)
|
||||
NGLOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
|
||||
LOG_ERROR(Common_Memory, "Failed to allocate aligned memory");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ void FreeMemoryPages(void* ptr, size_t size) {
|
||||
if (ptr) {
|
||||
#ifdef _WIN32
|
||||
if (!VirtualFree(ptr, 0, MEM_RELEASE))
|
||||
NGLOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n{}", GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n{}", GetLastErrorMsg());
|
||||
#else
|
||||
munmap(ptr, size);
|
||||
#endif
|
||||
@@ -134,7 +134,7 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
|
||||
#ifdef _WIN32
|
||||
DWORD oldValue;
|
||||
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
|
||||
NGLOG_ERROR(Common_Memory, "WriteProtectMemory failed!\n{}", GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Memory, "WriteProtectMemory failed!\n{}", GetLastErrorMsg());
|
||||
#else
|
||||
mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
|
||||
#endif
|
||||
@@ -145,7 +145,7 @@ void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
|
||||
DWORD oldValue;
|
||||
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
|
||||
&oldValue))
|
||||
NGLOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n{}", GetLastErrorMsg());
|
||||
LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n{}", GetLastErrorMsg());
|
||||
#else
|
||||
mprotect(ptr, size,
|
||||
allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
|
||||
|
||||
@@ -25,7 +25,7 @@ ParamPackage::ParamPackage(const std::string& serialized) {
|
||||
std::vector<std::string> key_value;
|
||||
Common::SplitString(pair, KEY_VALUE_SEPARATOR, key_value);
|
||||
if (key_value.size() != 2) {
|
||||
NGLOG_ERROR(Common, "invalid key pair {}", pair);
|
||||
LOG_ERROR(Common, "invalid key pair {}", pair);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ std::string ParamPackage::Serialize() const {
|
||||
std::string ParamPackage::Get(const std::string& key, const std::string& default_value) const {
|
||||
auto pair = data.find(key);
|
||||
if (pair == data.end()) {
|
||||
NGLOG_DEBUG(Common, "key '{}' not found", key);
|
||||
LOG_DEBUG(Common, "key '{}' not found", key);
|
||||
return default_value;
|
||||
}
|
||||
|
||||
@@ -74,14 +74,14 @@ std::string ParamPackage::Get(const std::string& key, const std::string& default
|
||||
int ParamPackage::Get(const std::string& key, int default_value) const {
|
||||
auto pair = data.find(key);
|
||||
if (pair == data.end()) {
|
||||
NGLOG_DEBUG(Common, "key '{}' not found", key);
|
||||
LOG_DEBUG(Common, "key '{}' not found", key);
|
||||
return default_value;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stoi(pair->second);
|
||||
} catch (const std::logic_error&) {
|
||||
NGLOG_ERROR(Common, "failed to convert {} to int", pair->second);
|
||||
LOG_ERROR(Common, "failed to convert {} to int", pair->second);
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
@@ -89,14 +89,14 @@ int ParamPackage::Get(const std::string& key, int default_value) const {
|
||||
float ParamPackage::Get(const std::string& key, float default_value) const {
|
||||
auto pair = data.find(key);
|
||||
if (pair == data.end()) {
|
||||
NGLOG_DEBUG(Common, "key {} not found", key);
|
||||
LOG_DEBUG(Common, "key {} not found", key);
|
||||
return default_value;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stof(pair->second);
|
||||
} catch (const std::logic_error&) {
|
||||
NGLOG_ERROR(Common, "failed to convert {} to float", pair->second);
|
||||
LOG_ERROR(Common, "failed to convert {} to float", pair->second);
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,10 @@ std::string ArrayToString(const u8* data, size_t size, int line_len, bool spaces
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string StringFromBuffer(const std::vector<u8>& data) {
|
||||
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
|
||||
}
|
||||
|
||||
// Turns " hej " into "hej". Also handles tabs.
|
||||
std::string StripSpaces(const std::string& str) {
|
||||
const size_t s = str.find_first_not_of(" \t\r\n");
|
||||
@@ -277,7 +281,7 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>&
|
||||
|
||||
iconv_t const conv_desc = iconv_open("UTF-8", fromcode);
|
||||
if ((iconv_t)(-1) == conv_desc) {
|
||||
NGLOG_ERROR(Common, "Iconv initialization failure [{}]: {}", fromcode, strerror(errno));
|
||||
LOG_ERROR(Common, "Iconv initialization failure [{}]: {}", fromcode, strerror(errno));
|
||||
iconv_close(conv_desc);
|
||||
return {};
|
||||
}
|
||||
@@ -306,7 +310,7 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>&
|
||||
++src_buffer;
|
||||
}
|
||||
} else {
|
||||
NGLOG_ERROR(Common, "iconv failure [{}]: {}", fromcode, strerror(errno));
|
||||
LOG_ERROR(Common, "iconv failure [{}]: {}", fromcode, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -325,7 +329,7 @@ std::u16string UTF8ToUTF16(const std::string& input) {
|
||||
|
||||
iconv_t const conv_desc = iconv_open("UTF-16LE", "UTF-8");
|
||||
if ((iconv_t)(-1) == conv_desc) {
|
||||
NGLOG_ERROR(Common, "Iconv initialization failure [UTF-8]: {}", strerror(errno));
|
||||
LOG_ERROR(Common, "Iconv initialization failure [UTF-8]: {}", strerror(errno));
|
||||
iconv_close(conv_desc);
|
||||
return {};
|
||||
}
|
||||
@@ -354,7 +358,7 @@ std::u16string UTF8ToUTF16(const std::string& input) {
|
||||
++src_buffer;
|
||||
}
|
||||
} else {
|
||||
NGLOG_ERROR(Common, "iconv failure [UTF-8]: {}", strerror(errno));
|
||||
LOG_ERROR(Common, "iconv failure [UTF-8]: {}", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ std::string ToUpper(std::string str);
|
||||
|
||||
std::string ArrayToString(const u8* data, size_t size, int line_len = 20, bool spaces = true);
|
||||
|
||||
std::string StringFromBuffer(const std::vector<u8>& data);
|
||||
|
||||
std::string StripSpaces(const std::string& s);
|
||||
std::string StripQuotes(const std::string& s);
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ add_library(core STATIC
|
||||
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
|
||||
@@ -124,6 +126,8 @@ add_library(core STATIC
|
||||
hle/service/audio/audren_u.h
|
||||
hle/service/audio/codecctl.cpp
|
||||
hle/service/audio/codecctl.h
|
||||
hle/service/audio/hwopus.cpp
|
||||
hle/service/audio/hwopus.h
|
||||
hle/service/bcat/module.cpp
|
||||
hle/service/bcat/module.h
|
||||
hle/service/bcat/bcat.cpp
|
||||
@@ -148,6 +152,8 @@ add_library(core STATIC
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.cpp
|
||||
hle/service/lm/lm.h
|
||||
hle/service/mm/mm_u.cpp
|
||||
hle/service/mm/mm_u.h
|
||||
hle/service/nifm/nifm.cpp
|
||||
hle/service/nifm/nifm.h
|
||||
hle/service/nifm/nifm_a.cpp
|
||||
@@ -255,6 +261,8 @@ add_library(core STATIC
|
||||
loader/linker.h
|
||||
loader/loader.cpp
|
||||
loader/loader.h
|
||||
loader/nca.cpp
|
||||
loader/nca.h
|
||||
loader/nro.cpp
|
||||
loader/nro.h
|
||||
loader/nso.cpp
|
||||
|
||||
@@ -55,8 +55,8 @@ public:
|
||||
}
|
||||
|
||||
void InterpreterFallback(u64 pc, size_t num_instructions) override {
|
||||
NGLOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc,
|
||||
num_instructions, MemoryReadCode(pc));
|
||||
LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc,
|
||||
num_instructions, MemoryReadCode(pc));
|
||||
|
||||
ARM_Interface::ThreadContext ctx;
|
||||
parent.SaveContext(ctx);
|
||||
|
||||
@@ -35,6 +35,17 @@ LoadDll LoadDll::g_load_dll;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void CodeHook(uc_engine* uc, uint64_t address, uint32_t size, void* user_data) {
|
||||
GDBStub::BreakpointAddress bkpt =
|
||||
GDBStub::GetNextBreakpointFromAddress(address, GDBStub::BreakpointType::Execute);
|
||||
if (GDBStub::IsMemoryBreak() ||
|
||||
(bkpt.type != GDBStub::BreakpointType::None && address == bkpt.address)) {
|
||||
auto core = static_cast<ARM_Unicorn*>(user_data);
|
||||
core->RecordBreak(bkpt);
|
||||
uc_emu_stop(uc);
|
||||
}
|
||||
}
|
||||
|
||||
static void InterruptHook(uc_engine* uc, u32 intNo, void* user_data) {
|
||||
u32 esr{};
|
||||
CHECKED(uc_reg_read(uc, UC_ARM64_REG_ESR, &esr));
|
||||
@@ -67,6 +78,10 @@ ARM_Unicorn::ARM_Unicorn() {
|
||||
uc_hook hook{};
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_INTR, (void*)InterruptHook, this, 0, -1));
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_MEM_INVALID, (void*)UnmappedMemoryHook, this, 0, -1));
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
CHECKED(uc_hook_add(uc, &hook, UC_HOOK_CODE, (void*)CodeHook, this, 0, -1));
|
||||
last_bkpt_hit = false;
|
||||
}
|
||||
}
|
||||
|
||||
ARM_Unicorn::~ARM_Unicorn() {
|
||||
@@ -155,7 +170,11 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) {
|
||||
}
|
||||
|
||||
void ARM_Unicorn::Run() {
|
||||
ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0));
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
ExecuteInstructions(std::max(4000000, 0));
|
||||
} else {
|
||||
ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
void ARM_Unicorn::Step() {
|
||||
@@ -168,6 +187,18 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
|
||||
MICROPROFILE_SCOPE(ARM_Jit);
|
||||
CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));
|
||||
CoreTiming::AddTicks(num_instructions);
|
||||
if (GDBStub::IsServerEnabled()) {
|
||||
if (last_bkpt_hit) {
|
||||
uc_reg_write(uc, UC_ARM64_REG_PC, &last_bkpt.address);
|
||||
}
|
||||
Kernel::Thread* thread = Kernel::GetCurrentThread();
|
||||
SaveContext(thread->context);
|
||||
if (last_bkpt_hit) {
|
||||
last_bkpt_hit = false;
|
||||
GDBStub::Break();
|
||||
}
|
||||
GDBStub::SendTrap(thread, 5);
|
||||
}
|
||||
}
|
||||
|
||||
void ARM_Unicorn::SaveContext(ARM_Interface::ThreadContext& ctx) {
|
||||
@@ -233,3 +264,8 @@ void ARM_Unicorn::PrepareReschedule() {
|
||||
}
|
||||
|
||||
void ARM_Unicorn::ClearInstructionCache() {}
|
||||
|
||||
void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) {
|
||||
last_bkpt = bkpt;
|
||||
last_bkpt_hit = true;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <unicorn/unicorn.h>
|
||||
#include "common/common_types.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
|
||||
class ARM_Unicorn final : public ARM_Interface {
|
||||
public:
|
||||
@@ -35,7 +36,10 @@ public:
|
||||
void Step() override;
|
||||
void ClearInstructionCache() override;
|
||||
void PageTableChanged() override{};
|
||||
void RecordBreak(GDBStub::BreakpointAddress bkpt);
|
||||
|
||||
private:
|
||||
uc_engine* uc{};
|
||||
GDBStub::BreakpointAddress last_bkpt{};
|
||||
bool last_bkpt_hit;
|
||||
};
|
||||
|
||||
@@ -87,15 +87,15 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
||||
app_loader = Loader::GetLoader(filepath);
|
||||
|
||||
if (!app_loader) {
|
||||
NGLOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||
return ResultStatus::ErrorGetLoader;
|
||||
}
|
||||
std::pair<boost::optional<u32>, Loader::ResultStatus> system_mode =
|
||||
app_loader->LoadKernelSystemMode();
|
||||
|
||||
if (system_mode.second != Loader::ResultStatus::Success) {
|
||||
NGLOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
|
||||
static_cast<int>(system_mode.second));
|
||||
LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!",
|
||||
static_cast<int>(system_mode.second));
|
||||
|
||||
switch (system_mode.second) {
|
||||
case Loader::ResultStatus::ErrorEncrypted:
|
||||
@@ -111,15 +111,15 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
||||
|
||||
ResultStatus init_result{Init(emu_window, system_mode.first.get())};
|
||||
if (init_result != ResultStatus::Success) {
|
||||
NGLOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
|
||||
static_cast<int>(init_result));
|
||||
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
|
||||
static_cast<int>(init_result));
|
||||
System::Shutdown();
|
||||
return init_result;
|
||||
}
|
||||
|
||||
const Loader::ResultStatus load_result{app_loader->Load(current_process)};
|
||||
if (Loader::ResultStatus::Success != load_result) {
|
||||
NGLOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result));
|
||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result));
|
||||
System::Shutdown();
|
||||
|
||||
switch (load_result) {
|
||||
@@ -161,7 +161,7 @@ Cpu& System::CpuCore(size_t core_index) {
|
||||
}
|
||||
|
||||
System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
NGLOG_DEBUG(HW_Memory, "initialized OK");
|
||||
LOG_DEBUG(HW_Memory, "initialized OK");
|
||||
|
||||
CoreTiming::Init();
|
||||
|
||||
@@ -196,7 +196,7 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
}
|
||||
}
|
||||
|
||||
NGLOG_DEBUG(Core, "Initialized OK");
|
||||
LOG_DEBUG(Core, "Initialized OK");
|
||||
|
||||
// Reset counters and set time origin to current frame
|
||||
GetAndResetPerfStats();
|
||||
@@ -245,7 +245,7 @@ void System::Shutdown() {
|
||||
// Close app loader
|
||||
app_loader.reset();
|
||||
|
||||
NGLOG_DEBUG(Core, "Shutdown OK");
|
||||
LOG_DEBUG(Core, "Shutdown OK");
|
||||
}
|
||||
|
||||
Service::SM::ServiceManager& System::ServiceManager() {
|
||||
|
||||
@@ -56,7 +56,7 @@ Cpu::Cpu(std::shared_ptr<CpuBarrier> cpu_barrier, size_t core_index)
|
||||
arm_interface = std::make_shared<ARM_Dynarmic>();
|
||||
#else
|
||||
cpu_core = std::make_shared<ARM_Unicorn>();
|
||||
NGLOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
|
||||
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
|
||||
#endif
|
||||
} else {
|
||||
arm_interface = std::make_shared<ARM_Unicorn>();
|
||||
@@ -75,7 +75,7 @@ void Cpu::RunLoop(bool tight_loop) {
|
||||
// If we don't have a currently active thread then don't execute instructions,
|
||||
// instead advance to the next event and try to yield to the next thread
|
||||
if (Kernel::GetCurrentThread() == nullptr) {
|
||||
NGLOG_TRACE(Core, "Core-{} idling", core_index);
|
||||
LOG_TRACE(Core, "Core-{} idling", core_index);
|
||||
|
||||
if (IsMainCore()) {
|
||||
CoreTiming::Idle();
|
||||
|
||||
@@ -74,11 +74,11 @@ static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) {}
|
||||
|
||||
s64 usToCycles(s64 us) {
|
||||
if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
return std::numeric_limits<s64>::max();
|
||||
}
|
||||
if (us > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
return BASE_CLOCK_RATE * (us / 1000000);
|
||||
}
|
||||
return (BASE_CLOCK_RATE * us) / 1000000;
|
||||
@@ -86,11 +86,11 @@ s64 usToCycles(s64 us) {
|
||||
|
||||
s64 usToCycles(u64 us) {
|
||||
if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
return std::numeric_limits<s64>::max();
|
||||
}
|
||||
if (us > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000);
|
||||
}
|
||||
return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000;
|
||||
@@ -98,11 +98,11 @@ s64 usToCycles(u64 us) {
|
||||
|
||||
s64 nsToCycles(s64 ns) {
|
||||
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
return std::numeric_limits<s64>::max();
|
||||
}
|
||||
if (ns > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
return BASE_CLOCK_RATE * (ns / 1000000000);
|
||||
}
|
||||
return (BASE_CLOCK_RATE * ns) / 1000000000;
|
||||
@@ -110,11 +110,11 @@ s64 nsToCycles(s64 ns) {
|
||||
|
||||
s64 nsToCycles(u64 ns) {
|
||||
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
LOG_ERROR(Core_Timing, "Integer overflow, use max value");
|
||||
return std::numeric_limits<s64>::max();
|
||||
}
|
||||
if (ns > MAX_VALUE_TO_MULTIPLY) {
|
||||
NGLOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
LOG_DEBUG(Core_Timing, "Time very big, do rounding");
|
||||
return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000);
|
||||
}
|
||||
return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000;
|
||||
|
||||
@@ -80,19 +80,19 @@ ResultCode Disk_FileSystem::RenameFile(const std::string& src_path,
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::DeleteDirectory(const Path& path) const {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
std::string full_path = base_directory + path;
|
||||
if (size == 0) {
|
||||
@@ -107,7 +107,7 @@ ResultCode Disk_FileSystem::CreateFile(const std::string& path, u64 size) const
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
NGLOG_ERROR(Service_FS, "Too large file");
|
||||
LOG_ERROR(Service_FS, "Too large file");
|
||||
// TODO(Subv): Find out the correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -120,13 +120,13 @@ ResultCode Disk_FileSystem::CreateDirectory(const std::string& path) const {
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
NGLOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path);
|
||||
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating {}", full_path);
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode Disk_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> Disk_FileSystem::OpenDirectory(
|
||||
}
|
||||
|
||||
u64 Disk_FileSystem::GetFreeSpaceSize() const {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,14 +163,14 @@ ResultVal<FileSys::EntryType> Disk_FileSystem::GetEntryType(const std::string& p
|
||||
}
|
||||
|
||||
ResultVal<size_t> Disk_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
|
||||
NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||
file->Seek(offset, SEEK_SET);
|
||||
return MakeResult<size_t>(file->ReadBytes(buffer, length));
|
||||
}
|
||||
|
||||
ResultVal<size_t> Disk_Storage::Write(const u64 offset, const size_t length, const bool flush,
|
||||
const u8* buffer) const {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
file->Seek(offset, SEEK_SET);
|
||||
size_t written = file->WriteBytes(buffer, length);
|
||||
if (flush) {
|
||||
@@ -204,7 +204,7 @@ u64 Disk_Directory::Read(const u64 count, Entry* entries) {
|
||||
const std::string& filename = file.virtualName;
|
||||
Entry& entry = entries[entries_read];
|
||||
|
||||
NGLOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory);
|
||||
LOG_TRACE(Service_FS, "File {}: size={} dir={}", filename, file.size, file.isDirectory);
|
||||
|
||||
// TODO(Link Mauve): use a proper conversion to UTF-16.
|
||||
for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
|
||||
|
||||
@@ -71,7 +71,7 @@ std::string Path::AsString() const {
|
||||
case Binary:
|
||||
default:
|
||||
// TODO(yuriks): Add assert
|
||||
NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
|
||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ std::u16string Path::AsU16Str() const {
|
||||
case Invalid:
|
||||
case Binary:
|
||||
// TODO(yuriks): Add assert
|
||||
NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
|
||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!");
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ std::vector<u8> Path::AsBinary() const {
|
||||
case Invalid:
|
||||
default:
|
||||
// TODO(yuriks): Add assert
|
||||
NGLOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
|
||||
LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,20 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::string& file_path, siz
|
||||
if (file.GetSize() < sizeof(Header))
|
||||
return Loader::ResultStatus::Error;
|
||||
|
||||
file.Seek(offset, SEEK_SET);
|
||||
// For cartridges, HFSs can get very large, so we need to calculate the size up to
|
||||
// the actual content itself instead of just blindly reading in the entire file.
|
||||
Header pfs_header;
|
||||
if (!file.ReadBytes(&pfs_header, sizeof(Header)))
|
||||
return Loader::ResultStatus::Error;
|
||||
|
||||
bool is_hfs = (memcmp(pfs_header.magic.data(), "HFS", 3) == 0);
|
||||
if (pfs_header.magic != Common::MakeMagic('H', 'F', 'S', '0') &&
|
||||
pfs_header.magic != Common::MakeMagic('P', 'F', 'S', '0')) {
|
||||
return Loader::ResultStatus::ErrorInvalidFormat;
|
||||
}
|
||||
|
||||
bool is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0');
|
||||
|
||||
size_t entry_size = is_hfs ? sizeof(HFSEntry) : sizeof(PFSEntry);
|
||||
size_t metadata_size =
|
||||
sizeof(Header) + (pfs_header.num_entries * entry_size) + pfs_header.strtab_size;
|
||||
@@ -39,7 +46,7 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::string& file_path, siz
|
||||
|
||||
Loader::ResultStatus result = Load(file_data);
|
||||
if (result != Loader::ResultStatus::Success)
|
||||
NGLOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path);
|
||||
LOG_ERROR(Service_FS, "Failed to load PFS from file {}!", file_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -50,7 +57,12 @@ Loader::ResultStatus PartitionFilesystem::Load(const std::vector<u8>& file_data,
|
||||
return Loader::ResultStatus::Error;
|
||||
|
||||
memcpy(&pfs_header, &file_data[offset], sizeof(Header));
|
||||
is_hfs = (memcmp(pfs_header.magic.data(), "HFS", 3) == 0);
|
||||
if (pfs_header.magic != Common::MakeMagic('H', 'F', 'S', '0') &&
|
||||
pfs_header.magic != Common::MakeMagic('P', 'F', 'S', '0')) {
|
||||
return Loader::ResultStatus::ErrorInvalidFormat;
|
||||
}
|
||||
|
||||
is_hfs = pfs_header.magic == Common::MakeMagic('H', 'F', 'S', '0');
|
||||
|
||||
size_t entries_offset = offset + sizeof(Header);
|
||||
size_t entry_size = is_hfs ? sizeof(HFSEntry) : sizeof(PFSEntry);
|
||||
@@ -73,21 +85,21 @@ u32 PartitionFilesystem::GetNumEntries() const {
|
||||
return pfs_header.num_entries;
|
||||
}
|
||||
|
||||
u64 PartitionFilesystem::GetEntryOffset(int index) const {
|
||||
u64 PartitionFilesystem::GetEntryOffset(u32 index) const {
|
||||
if (index > GetNumEntries())
|
||||
return 0;
|
||||
|
||||
return content_offset + pfs_entries[index].fs_entry.offset;
|
||||
}
|
||||
|
||||
u64 PartitionFilesystem::GetEntrySize(int index) const {
|
||||
u64 PartitionFilesystem::GetEntrySize(u32 index) const {
|
||||
if (index > GetNumEntries())
|
||||
return 0;
|
||||
|
||||
return pfs_entries[index].fs_entry.size;
|
||||
}
|
||||
|
||||
std::string PartitionFilesystem::GetEntryName(int index) const {
|
||||
std::string PartitionFilesystem::GetEntryName(u32 index) const {
|
||||
if (index > GetNumEntries())
|
||||
return "";
|
||||
|
||||
@@ -113,12 +125,12 @@ u64 PartitionFilesystem::GetFileSize(const std::string& name) const {
|
||||
}
|
||||
|
||||
void PartitionFilesystem::Print() const {
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
|
||||
LOG_DEBUG(Service_FS, "Magic: {}", pfs_header.magic);
|
||||
LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
|
||||
for (u32 i = 0; i < pfs_header.num_entries; i++) {
|
||||
NGLOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i,
|
||||
pfs_entries[i].name.c_str(), pfs_entries[i].fs_entry.size,
|
||||
GetFileOffset(pfs_entries[i].name));
|
||||
LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i,
|
||||
pfs_entries[i].name.c_str(), pfs_entries[i].fs_entry.size,
|
||||
GetFileOffset(pfs_entries[i].name));
|
||||
}
|
||||
}
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -27,9 +27,9 @@ public:
|
||||
Loader::ResultStatus Load(const std::vector<u8>& file_data, size_t offset = 0);
|
||||
|
||||
u32 GetNumEntries() const;
|
||||
u64 GetEntryOffset(int index) const;
|
||||
u64 GetEntrySize(int index) const;
|
||||
std::string GetEntryName(int index) const;
|
||||
u64 GetEntryOffset(u32 index) const;
|
||||
u64 GetEntrySize(u32 index) const;
|
||||
std::string GetEntryName(u32 index) const;
|
||||
u64 GetFileOffset(const std::string& name) const;
|
||||
u64 GetFileSize(const std::string& name) const;
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
private:
|
||||
struct Header {
|
||||
std::array<char, 4> magic;
|
||||
u32_le magic;
|
||||
u32_le num_entries;
|
||||
u32_le strtab_size;
|
||||
INSERT_PADDING_BYTES(0x4);
|
||||
|
||||
@@ -21,7 +21,7 @@ Loader::ResultStatus ProgramMetadata::Load(const std::string& file_path) {
|
||||
|
||||
Loader::ResultStatus result = Load(file_data);
|
||||
if (result != Loader::ResultStatus::Success)
|
||||
NGLOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path);
|
||||
LOG_ERROR(Service_FS, "Failed to load NPDM from file {}!", file_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -76,14 +76,14 @@ u64 ProgramMetadata::GetFilesystemPermissions() const {
|
||||
}
|
||||
|
||||
void ProgramMetadata::Print() const {
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority);
|
||||
NGLOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu);
|
||||
NGLOG_DEBUG(Service_FS, "Main thread stack size: 0x{:X} bytes", npdm_header.main_stack_size);
|
||||
NGLOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category);
|
||||
NGLOG_DEBUG(Service_FS, "Flags: 0x{:02X}", npdm_header.flags);
|
||||
NGLOG_DEBUG(Service_FS, " > 64-bit instructions: {}",
|
||||
npdm_header.has_64_bit_instructions ? "YES" : "NO");
|
||||
LOG_DEBUG(Service_FS, "Magic: {:.4}", npdm_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Main thread priority: 0x{:02X}", npdm_header.main_thread_priority);
|
||||
LOG_DEBUG(Service_FS, "Main thread core: {}", npdm_header.main_thread_cpu);
|
||||
LOG_DEBUG(Service_FS, "Main thread stack size: 0x{:X} bytes", npdm_header.main_stack_size);
|
||||
LOG_DEBUG(Service_FS, "Process category: {}", npdm_header.process_category);
|
||||
LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", npdm_header.flags);
|
||||
LOG_DEBUG(Service_FS, " > 64-bit instructions: {}",
|
||||
npdm_header.has_64_bit_instructions ? "YES" : "NO");
|
||||
|
||||
auto address_space = "Unknown";
|
||||
switch (npdm_header.address_space_type) {
|
||||
@@ -95,19 +95,19 @@ void ProgramMetadata::Print() const {
|
||||
break;
|
||||
}
|
||||
|
||||
NGLOG_DEBUG(Service_FS, " > Address space: {}\n", address_space);
|
||||
LOG_DEBUG(Service_FS, " > Address space: {}\n", address_space);
|
||||
|
||||
// Begin ACID printing (potential perms, signed)
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Flags: 0x{:02X}", acid_header.flags);
|
||||
NGLOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
|
||||
NGLOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
|
||||
NGLOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
|
||||
NGLOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
|
||||
LOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", acid_header.flags);
|
||||
LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
|
||||
LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
|
||||
LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
|
||||
LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
|
||||
|
||||
// Begin ACI0 printing (actual perms, unsigned)
|
||||
NGLOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
|
||||
NGLOG_DEBUG(Service_FS, "Title ID: 0x{:016X}", aci_header.title_id);
|
||||
NGLOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", aci_file_access.permissions);
|
||||
LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
|
||||
LOG_DEBUG(Service_FS, "Title ID: 0x{:016X}", aci_header.title_id);
|
||||
LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", aci_file_access.permissions);
|
||||
}
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace FileSys {
|
||||
RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) {
|
||||
// Load the RomFS from the app
|
||||
if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) {
|
||||
NGLOG_ERROR(Service_FS, "Unable to read RomFS!");
|
||||
LOG_ERROR(Service_FS, "Unable to read RomFS!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& pa
|
||||
}
|
||||
|
||||
ResultCode RomFS_Factory::Format(const Path& path) {
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
|
||||
LOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const {
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
@@ -21,72 +21,70 @@ ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const std:
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::DeleteFile(const std::string& path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive ({}).", GetName());
|
||||
// TODO(bunnei): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::RenameFile(const std::string& src_path,
|
||||
const std::string& dest_path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).",
|
||||
GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
|
||||
GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
|
||||
GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::CreateFile(const std::string& path, u64 size) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive ({}).", GetName());
|
||||
// TODO(bunnei): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::CreateDirectory(const std::string& path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).",
|
||||
GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive ({}).",
|
||||
GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).",
|
||||
GetName());
|
||||
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive ({}).", GetName());
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory(
|
||||
const std::string& path) const {
|
||||
NGLOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive");
|
||||
LOG_WARNING(Service_FS, "Opening Directory in a ROMFS archive");
|
||||
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>());
|
||||
}
|
||||
|
||||
u64 RomFS_FileSystem::GetFreeSpaceSize() const {
|
||||
NGLOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive");
|
||||
LOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ResultVal<FileSys::EntryType> RomFS_FileSystem::GetEntryType(const std::string& path) const {
|
||||
NGLOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path);
|
||||
LOG_CRITICAL(Service_FS, "Called within an ROMFS archive (path {}).", path);
|
||||
// TODO(wwylele): Use correct error code
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
|
||||
NGLOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||
LOG_TRACE(Service_FS, "called offset={}, length={}", offset, length);
|
||||
romfs_file->Seek(data_offset + offset, SEEK_SET);
|
||||
size_t read_length = (size_t)std::min((u64)length, data_size - offset);
|
||||
|
||||
@@ -95,7 +93,7 @@ ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8*
|
||||
|
||||
ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush,
|
||||
const u8* buffer) const {
|
||||
NGLOG_ERROR(Service_FS, "Attempted to write to ROMFS file");
|
||||
LOG_ERROR(Service_FS, "Attempted to write to ROMFS file");
|
||||
// TODO(Subv): Find error code
|
||||
return MakeResult<size_t>(0);
|
||||
}
|
||||
@@ -105,7 +103,7 @@ u64 RomFS_Storage::GetSize() const {
|
||||
}
|
||||
|
||||
bool RomFS_Storage::SetSize(const u64 size) const {
|
||||
NGLOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file");
|
||||
LOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SaveData_Factory::Open(const Path&
|
||||
}
|
||||
|
||||
ResultCode SaveData_Factory::Format(const Path& path) {
|
||||
NGLOG_WARNING(Service_FS, "Format archive {}", GetName());
|
||||
LOG_WARNING(Service_FS, "Format archive {}", GetName());
|
||||
// Create the save data directory.
|
||||
if (!FileUtil::CreateFullPath(GetFullPath())) {
|
||||
// TODO(Subv): Find the correct error code.
|
||||
@@ -39,7 +39,7 @@ ResultCode SaveData_Factory::Format(const Path& path) {
|
||||
}
|
||||
|
||||
ResultVal<ArchiveFormatInfo> SaveData_Factory::GetFormatInfo(const Path& path) const {
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ ResultVal<std::unique_ptr<FileSystemBackend>> SDMC_Factory::Open(const Path& pat
|
||||
}
|
||||
|
||||
ResultCode SDMC_Factory::Format(const Path& path) {
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
|
||||
LOG_ERROR(Service_FS, "Unimplemented Format archive {}", GetName());
|
||||
// TODO(Subv): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
ResultVal<ArchiveFormatInfo> SDMC_Factory::GetFormatInfo(const Path& path) const {
|
||||
NGLOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive {}", GetName());
|
||||
// TODO(bunnei): Find the right error code for this
|
||||
return ResultCode(-1);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ template <typename InputDeviceType>
|
||||
void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDeviceType>> factory) {
|
||||
auto pair = std::make_pair(name, std::move(factory));
|
||||
if (!Impl::FactoryList<InputDeviceType>::list.insert(std::move(pair)).second) {
|
||||
NGLOG_ERROR(Input, "Factory '{}' already registered", name);
|
||||
LOG_ERROR(Input, "Factory '{}' already registered", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDevic
|
||||
template <typename InputDeviceType>
|
||||
void UnregisterFactory(const std::string& name) {
|
||||
if (Impl::FactoryList<InputDeviceType>::list.erase(name) == 0) {
|
||||
NGLOG_ERROR(Input, "Factory '{}' not registered", name);
|
||||
LOG_ERROR(Input, "Factory '{}' not registered", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ std::unique_ptr<InputDeviceType> CreateDevice(const std::string& params) {
|
||||
const auto pair = factory_list.find(engine);
|
||||
if (pair == factory_list.end()) {
|
||||
if (engine != "null") {
|
||||
NGLOG_ERROR(Input, "Unknown engine name: {}", engine);
|
||||
LOG_ERROR(Input, "Unknown engine name: {}", engine);
|
||||
}
|
||||
return std::make_unique<InputDeviceType>();
|
||||
}
|
||||
|
||||
@@ -32,9 +32,13 @@
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_cpu.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/scheduler.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
@@ -137,15 +141,17 @@ static u8 command_buffer[GDB_BUFFER_SIZE];
|
||||
static u32 command_length;
|
||||
|
||||
static u32 latest_signal = 0;
|
||||
static bool step_break = false;
|
||||
static bool memory_break = false;
|
||||
|
||||
static Kernel::Thread* current_thread = nullptr;
|
||||
|
||||
// Binding to a port within the reserved ports range (0-1023) requires root permissions,
|
||||
// so default to a port outside of that range.
|
||||
static u16 gdbstub_port = 24689;
|
||||
|
||||
static bool halt_loop = true;
|
||||
static bool step_loop = false;
|
||||
static bool send_trap = false;
|
||||
|
||||
// If set to false, the server will never be started and no
|
||||
// gdbstub-related functions will be executed.
|
||||
@@ -165,6 +171,53 @@ static std::map<u64, Breakpoint> breakpoints_execute;
|
||||
static std::map<u64, Breakpoint> breakpoints_read;
|
||||
static std::map<u64, Breakpoint> breakpoints_write;
|
||||
|
||||
static Kernel::Thread* FindThreadById(int id) {
|
||||
for (int core = 0; core < Core::NUM_CPU_CORES; core++) {
|
||||
auto threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
|
||||
for (auto thread : threads) {
|
||||
if (thread->GetThreadId() == id) {
|
||||
current_thread = thread.get();
|
||||
return current_thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static u64 RegRead(int id, Kernel::Thread* thread = nullptr) {
|
||||
if (!thread) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (id < SP_REGISTER) {
|
||||
return thread->context.cpu_registers[id];
|
||||
} else if (id == SP_REGISTER) {
|
||||
return thread->context.sp;
|
||||
} else if (id == PC_REGISTER) {
|
||||
return thread->context.pc;
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
return thread->context.cpsr;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void RegWrite(int id, u64 val, Kernel::Thread* thread = nullptr) {
|
||||
if (!thread) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (id < SP_REGISTER) {
|
||||
thread->context.cpu_registers[id] = val;
|
||||
} else if (id == SP_REGISTER) {
|
||||
thread->context.sp = val;
|
||||
} else if (id == PC_REGISTER) {
|
||||
thread->context.pc = val;
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
thread->context.cpsr = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns hex string character into the equivalent byte.
|
||||
*
|
||||
@@ -179,7 +232,7 @@ static u8 HexCharToValue(u8 hex) {
|
||||
return hex - 'A' + 0xA;
|
||||
}
|
||||
|
||||
NGLOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
|
||||
LOG_ERROR(Debug_GDBStub, "Invalid nibble: {} ({:02X})", hex, hex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -193,7 +246,7 @@ static u8 NibbleToHex(u8 n) {
|
||||
if (n < 0xA) {
|
||||
return '0' + n;
|
||||
} else {
|
||||
return 'A' + n - 0xA;
|
||||
return 'a' + n - 0xA;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +372,7 @@ static u8 ReadByte() {
|
||||
u8 c;
|
||||
size_t received_size = recv(gdbserver_socket, reinterpret_cast<char*>(&c), 1, MSG_WAITALL);
|
||||
if (received_size != 1) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size);
|
||||
LOG_ERROR(Debug_GDBStub, "recv failed: {}", received_size);
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
@@ -360,8 +413,8 @@ static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
|
||||
|
||||
auto bp = p.find(static_cast<u64>(addr));
|
||||
if (bp != p.end()) {
|
||||
NGLOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
|
||||
bp->second.len, bp->second.addr, static_cast<int>(type));
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}",
|
||||
bp->second.len, bp->second.addr, static_cast<int>(type));
|
||||
p.erase(static_cast<u64>(addr));
|
||||
}
|
||||
}
|
||||
@@ -406,10 +459,10 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
|
||||
}
|
||||
|
||||
if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) {
|
||||
NGLOG_DEBUG(Debug_GDBStub,
|
||||
"Found breakpoint type {} @ {:016X}, range: {:016X}"
|
||||
" - {:016X} ({:X} bytes)",
|
||||
static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
|
||||
LOG_DEBUG(Debug_GDBStub,
|
||||
"Found breakpoint type {} @ {:016X}, range: {:016X}"
|
||||
" - {:016X} ({:X} bytes)",
|
||||
static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -425,7 +478,7 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
|
||||
static void SendPacket(const char packet) {
|
||||
size_t sent_size = send(gdbserver_socket, &packet, 1, 0);
|
||||
if (sent_size != 1) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "send failed");
|
||||
LOG_ERROR(Debug_GDBStub, "send failed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,11 +492,13 @@ static void SendReply(const char* reply) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG(Debug_GDBStub, "Reply: {}", reply);
|
||||
|
||||
memset(command_buffer, 0, sizeof(command_buffer));
|
||||
|
||||
command_length = static_cast<u32>(strlen(reply));
|
||||
if (command_length + 4 > sizeof(command_buffer)) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply");
|
||||
LOG_ERROR(Debug_GDBStub, "command_buffer overflow in SendReply");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -460,7 +515,7 @@ static void SendReply(const char* reply) {
|
||||
while (left > 0) {
|
||||
int sent_size = send(gdbserver_socket, reinterpret_cast<char*>(ptr), left, 0);
|
||||
if (sent_size < 0) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "gdb: send failed");
|
||||
LOG_ERROR(Debug_GDBStub, "gdb: send failed");
|
||||
return Shutdown();
|
||||
}
|
||||
|
||||
@@ -471,7 +526,7 @@ static void SendReply(const char* reply) {
|
||||
|
||||
/// Handle query command from gdb client.
|
||||
static void HandleQuery() {
|
||||
NGLOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1);
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: query '{}'", command_buffer + 1);
|
||||
|
||||
const char* query = reinterpret_cast<const char*>(command_buffer + 1);
|
||||
|
||||
@@ -483,6 +538,22 @@ static void HandleQuery() {
|
||||
} else if (strncmp(query, "Xfer:features:read:target.xml:",
|
||||
strlen("Xfer:features:read:target.xml:")) == 0) {
|
||||
SendReply(target_xml);
|
||||
} else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
|
||||
std::string buffer = fmt::format("TextSeg={:0x}", Memory::PROCESS_IMAGE_VADDR);
|
||||
SendReply(buffer.c_str());
|
||||
} else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
|
||||
std::string val = "m";
|
||||
for (int core = 0; core < Core::NUM_CPU_CORES; core++) {
|
||||
auto threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
|
||||
for (auto thread : threads) {
|
||||
val += fmt::format("{:x}", thread->GetThreadId());
|
||||
val += ",";
|
||||
}
|
||||
}
|
||||
val.pop_back();
|
||||
SendReply(val.c_str());
|
||||
} else if (strncmp(query, "sThreadInfo", strlen("sThreadInfo")) == 0) {
|
||||
SendReply("l");
|
||||
} else {
|
||||
SendReply("");
|
||||
}
|
||||
@@ -490,11 +561,40 @@ static void HandleQuery() {
|
||||
|
||||
/// Handle set thread command from gdb client.
|
||||
static void HandleSetThread() {
|
||||
if (memcmp(command_buffer, "Hg0", 3) == 0 || memcmp(command_buffer, "Hc-1", 4) == 0 ||
|
||||
memcmp(command_buffer, "Hc0", 4) == 0 || memcmp(command_buffer, "Hc1", 4) == 0) {
|
||||
return SendReply("OK");
|
||||
if (memcmp(command_buffer, "Hc", 2) == 0 || memcmp(command_buffer, "Hg", 2) == 0) {
|
||||
int thread_id = -1;
|
||||
if (command_buffer[2] != '-') {
|
||||
thread_id = static_cast<int>(HexToInt(
|
||||
command_buffer + 2,
|
||||
command_length - 2 /*strlen(reinterpret_cast<char*>(command_buffer) + 2)*/));
|
||||
}
|
||||
if (thread_id >= 1) {
|
||||
current_thread = FindThreadById(thread_id);
|
||||
}
|
||||
if (!current_thread) {
|
||||
thread_id = 1;
|
||||
current_thread = FindThreadById(thread_id);
|
||||
}
|
||||
if (current_thread) {
|
||||
SendReply("OK");
|
||||
return;
|
||||
}
|
||||
}
|
||||
SendReply("E01");
|
||||
}
|
||||
|
||||
/// Handle thread alive command from gdb client.
|
||||
static void HandleThreadAlive() {
|
||||
int thread_id = static_cast<int>(
|
||||
HexToInt(command_buffer + 1,
|
||||
command_length - 1 /*strlen(reinterpret_cast<char*>(command_buffer) + 1)*/));
|
||||
if (thread_id == 0) {
|
||||
thread_id = 1;
|
||||
}
|
||||
if (FindThreadById(thread_id)) {
|
||||
SendReply("OK");
|
||||
return;
|
||||
}
|
||||
SendReply("E01");
|
||||
}
|
||||
|
||||
@@ -503,15 +603,24 @@ static void HandleSetThread() {
|
||||
*
|
||||
* @param signal Signal to be sent to client.
|
||||
*/
|
||||
static void SendSignal(u32 signal) {
|
||||
static void SendSignal(Kernel::Thread* thread, u32 signal, bool full = true) {
|
||||
if (gdbserver_socket == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
latest_signal = signal;
|
||||
|
||||
std::string buffer = fmt::format("T{:02x}", latest_signal);
|
||||
NGLOG_DEBUG(Debug_GDBStub, "Response: {}", buffer);
|
||||
std::string buffer;
|
||||
if (full) {
|
||||
buffer = fmt::format("T{:02x}{:02x}:{:016x};{:02x}:{:016x};", latest_signal, PC_REGISTER,
|
||||
Common::swap64(RegRead(PC_REGISTER, thread)), SP_REGISTER,
|
||||
Common::swap64(RegRead(SP_REGISTER, thread)));
|
||||
} else {
|
||||
buffer = fmt::format("T{:02x};", latest_signal);
|
||||
}
|
||||
|
||||
buffer += fmt::format("thread:{:x};", thread->GetThreadId());
|
||||
|
||||
SendReply(buffer.c_str());
|
||||
}
|
||||
|
||||
@@ -525,18 +634,18 @@ static void ReadCommand() {
|
||||
// ignore ack
|
||||
return;
|
||||
} else if (c == 0x03) {
|
||||
NGLOG_INFO(Debug_GDBStub, "gdb: found break command");
|
||||
LOG_INFO(Debug_GDBStub, "gdb: found break command");
|
||||
halt_loop = true;
|
||||
SendSignal(SIGTRAP);
|
||||
SendSignal(current_thread, SIGTRAP);
|
||||
return;
|
||||
} else if (c != GDB_STUB_START) {
|
||||
NGLOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c);
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: read invalid byte {:02X}", c);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((c = ReadByte()) != GDB_STUB_END) {
|
||||
if (command_length >= sizeof(command_buffer)) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow");
|
||||
LOG_ERROR(Debug_GDBStub, "gdb: command_buffer overflow");
|
||||
SendPacket(GDB_STUB_NACK);
|
||||
return;
|
||||
}
|
||||
@@ -549,10 +658,9 @@ static void ReadCommand() {
|
||||
u8 checksum_calculated = CalculateChecksum(command_buffer, command_length);
|
||||
|
||||
if (checksum_received != checksum_calculated) {
|
||||
NGLOG_ERROR(
|
||||
Debug_GDBStub,
|
||||
"gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})",
|
||||
checksum_calculated, checksum_received, command_buffer, command_length);
|
||||
LOG_ERROR(Debug_GDBStub,
|
||||
"gdb: invalid checksum: calculated {:02X} and read {:02X} for ${}# (length: {})",
|
||||
checksum_calculated, checksum_received, command_buffer, command_length);
|
||||
|
||||
command_length = 0;
|
||||
|
||||
@@ -579,7 +687,7 @@ static bool IsDataAvailable() {
|
||||
t.tv_usec = 0;
|
||||
|
||||
if (select(gdbserver_socket + 1, &fd_socket, nullptr, nullptr, &t) < 0) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "select failed");
|
||||
LOG_ERROR(Debug_GDBStub, "select failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -598,11 +706,11 @@ static void ReadRegister() {
|
||||
}
|
||||
|
||||
if (id <= SP_REGISTER) {
|
||||
LongToGdbHex(reply, Core::CurrentArmInterface().GetReg(static_cast<int>(id)));
|
||||
LongToGdbHex(reply, RegRead(id, current_thread));
|
||||
} else if (id == PC_REGISTER) {
|
||||
LongToGdbHex(reply, Core::CurrentArmInterface().GetPC());
|
||||
LongToGdbHex(reply, RegRead(id, current_thread));
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::CurrentArmInterface().GetCPSR());
|
||||
IntToGdbHex(reply, (u32)RegRead(id, current_thread));
|
||||
} else {
|
||||
return SendReply("E01");
|
||||
}
|
||||
@@ -618,16 +726,16 @@ static void ReadRegisters() {
|
||||
u8* bufptr = buffer;
|
||||
|
||||
for (int reg = 0; reg <= SP_REGISTER; reg++) {
|
||||
LongToGdbHex(bufptr + reg * 16, Core::CurrentArmInterface().GetReg(reg));
|
||||
LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
|
||||
}
|
||||
|
||||
bufptr += (32 * 16);
|
||||
|
||||
LongToGdbHex(bufptr, Core::CurrentArmInterface().GetPC());
|
||||
LongToGdbHex(bufptr, RegRead(PC_REGISTER, current_thread));
|
||||
|
||||
bufptr += 16;
|
||||
|
||||
IntToGdbHex(bufptr, Core::CurrentArmInterface().GetCPSR());
|
||||
IntToGdbHex(bufptr, (u32)RegRead(CPSR_REGISTER, current_thread));
|
||||
|
||||
bufptr += 8;
|
||||
|
||||
@@ -646,11 +754,11 @@ static void WriteRegister() {
|
||||
}
|
||||
|
||||
if (id <= SP_REGISTER) {
|
||||
Core::CurrentArmInterface().SetReg(id, GdbHexToLong(buffer_ptr));
|
||||
RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
|
||||
} else if (id == PC_REGISTER) {
|
||||
Core::CurrentArmInterface().SetPC(GdbHexToLong(buffer_ptr));
|
||||
RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
Core::CurrentArmInterface().SetCPSR(GdbHexToInt(buffer_ptr));
|
||||
RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
|
||||
} else {
|
||||
return SendReply("E01");
|
||||
}
|
||||
@@ -667,11 +775,11 @@ static void WriteRegisters() {
|
||||
|
||||
for (int i = 0, reg = 0; reg <= CPSR_REGISTER; i++, reg++) {
|
||||
if (reg <= SP_REGISTER) {
|
||||
Core::CurrentArmInterface().SetReg(reg, GdbHexToLong(buffer_ptr + i * 16));
|
||||
RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
|
||||
} else if (reg == PC_REGISTER) {
|
||||
Core::CurrentArmInterface().SetPC(GdbHexToLong(buffer_ptr + i * 16));
|
||||
RegWrite(PC_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
|
||||
} else if (reg == CPSR_REGISTER) {
|
||||
Core::CurrentArmInterface().SetCPSR(GdbHexToInt(buffer_ptr + i * 16));
|
||||
RegWrite(CPSR_REGISTER, GdbHexToInt(buffer_ptr + i * 16), current_thread);
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
@@ -692,7 +800,7 @@ static void ReadMemory() {
|
||||
u64 len =
|
||||
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
|
||||
|
||||
NGLOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: addr: {:016X} len: {:016X}", addr, len);
|
||||
|
||||
if (len * 2 > sizeof(reply)) {
|
||||
SendReply("E01");
|
||||
@@ -734,7 +842,7 @@ static void WriteMemory() {
|
||||
void Break(bool is_memory_break) {
|
||||
if (!halt_loop) {
|
||||
halt_loop = true;
|
||||
SendSignal(SIGTRAP);
|
||||
send_trap = true;
|
||||
}
|
||||
|
||||
memory_break = is_memory_break;
|
||||
@@ -744,10 +852,10 @@ void Break(bool is_memory_break) {
|
||||
static void Step() {
|
||||
step_loop = true;
|
||||
halt_loop = true;
|
||||
step_break = true;
|
||||
SendSignal(SIGTRAP);
|
||||
send_trap = true;
|
||||
}
|
||||
|
||||
/// Tell the CPU if we hit a memory breakpoint.
|
||||
bool IsMemoryBreak() {
|
||||
if (IsConnected()) {
|
||||
return false;
|
||||
@@ -759,7 +867,6 @@ bool IsMemoryBreak() {
|
||||
/// Tell the CPU to continue executing.
|
||||
static void Continue() {
|
||||
memory_break = false;
|
||||
step_break = false;
|
||||
step_loop = false;
|
||||
halt_loop = false;
|
||||
}
|
||||
@@ -780,8 +887,8 @@ static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) {
|
||||
breakpoint.len = len;
|
||||
p.insert({addr, breakpoint});
|
||||
|
||||
NGLOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
|
||||
static_cast<int>(type), breakpoint.len, breakpoint.addr);
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}",
|
||||
static_cast<int>(type), breakpoint.len, breakpoint.addr);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -888,7 +995,7 @@ void HandlePacket() {
|
||||
return;
|
||||
}
|
||||
|
||||
NGLOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer);
|
||||
LOG_DEBUG(Debug_GDBStub, "Packet: {}", command_buffer);
|
||||
|
||||
switch (command_buffer[0]) {
|
||||
case 'q':
|
||||
@@ -898,11 +1005,11 @@ void HandlePacket() {
|
||||
HandleSetThread();
|
||||
break;
|
||||
case '?':
|
||||
SendSignal(latest_signal);
|
||||
SendSignal(current_thread, latest_signal);
|
||||
break;
|
||||
case 'k':
|
||||
Shutdown();
|
||||
NGLOG_INFO(Debug_GDBStub, "killed by gdb");
|
||||
LOG_INFO(Debug_GDBStub, "killed by gdb");
|
||||
return;
|
||||
case 'g':
|
||||
ReadRegisters();
|
||||
@@ -935,6 +1042,9 @@ void HandlePacket() {
|
||||
case 'Z':
|
||||
AddBreakpoint();
|
||||
break;
|
||||
case 'T':
|
||||
HandleThreadAlive();
|
||||
break;
|
||||
default:
|
||||
SendReply("");
|
||||
break;
|
||||
@@ -981,7 +1091,7 @@ static void Init(u16 port) {
|
||||
breakpoints_write.clear();
|
||||
|
||||
// Start gdb server
|
||||
NGLOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port);
|
||||
LOG_INFO(Debug_GDBStub, "Starting GDB server on port {}...", port);
|
||||
|
||||
sockaddr_in saddr_server = {};
|
||||
saddr_server.sin_family = AF_INET;
|
||||
@@ -994,28 +1104,28 @@ static void Init(u16 port) {
|
||||
|
||||
int tmpsock = static_cast<int>(socket(PF_INET, SOCK_STREAM, 0));
|
||||
if (tmpsock == -1) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
|
||||
LOG_ERROR(Debug_GDBStub, "Failed to create gdb socket");
|
||||
}
|
||||
|
||||
// Set socket to SO_REUSEADDR so it can always bind on the same port
|
||||
int reuse_enabled = 1;
|
||||
if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled,
|
||||
sizeof(reuse_enabled)) < 0) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
|
||||
LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option");
|
||||
}
|
||||
|
||||
const sockaddr* server_addr = reinterpret_cast<const sockaddr*>(&saddr_server);
|
||||
socklen_t server_addrlen = sizeof(saddr_server);
|
||||
if (bind(tmpsock, server_addr, server_addrlen) < 0) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket");
|
||||
LOG_ERROR(Debug_GDBStub, "Failed to bind gdb socket");
|
||||
}
|
||||
|
||||
if (listen(tmpsock, 1) < 0) {
|
||||
NGLOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket");
|
||||
LOG_ERROR(Debug_GDBStub, "Failed to listen to gdb socket");
|
||||
}
|
||||
|
||||
// Wait for gdb to connect
|
||||
NGLOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...");
|
||||
LOG_INFO(Debug_GDBStub, "Waiting for gdb to connect...");
|
||||
sockaddr_in saddr_client;
|
||||
sockaddr* client_addr = reinterpret_cast<sockaddr*>(&saddr_client);
|
||||
socklen_t client_addrlen = sizeof(saddr_client);
|
||||
@@ -1026,9 +1136,9 @@ static void Init(u16 port) {
|
||||
halt_loop = false;
|
||||
step_loop = false;
|
||||
|
||||
NGLOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
|
||||
LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client");
|
||||
} else {
|
||||
NGLOG_INFO(Debug_GDBStub, "Client connected.");
|
||||
LOG_INFO(Debug_GDBStub, "Client connected.");
|
||||
saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
@@ -1047,7 +1157,7 @@ void Shutdown() {
|
||||
return;
|
||||
}
|
||||
|
||||
NGLOG_INFO(Debug_GDBStub, "Stopping GDB ...");
|
||||
LOG_INFO(Debug_GDBStub, "Stopping GDB ...");
|
||||
if (gdbserver_socket != -1) {
|
||||
shutdown(gdbserver_socket, SHUT_RDWR);
|
||||
gdbserver_socket = -1;
|
||||
@@ -1057,7 +1167,7 @@ void Shutdown() {
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
NGLOG_INFO(Debug_GDBStub, "GDB stopped.");
|
||||
LOG_INFO(Debug_GDBStub, "GDB stopped.");
|
||||
}
|
||||
|
||||
bool IsServerEnabled() {
|
||||
@@ -1079,4 +1189,11 @@ bool GetCpuStepFlag() {
|
||||
void SetCpuStepFlag(bool is_step) {
|
||||
step_loop = is_step;
|
||||
}
|
||||
|
||||
void SendTrap(Kernel::Thread* thread, int trap) {
|
||||
if (send_trap) {
|
||||
send_trap = false;
|
||||
SendSignal(thread, trap);
|
||||
}
|
||||
}
|
||||
}; // namespace GDBStub
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
||||
namespace GDBStub {
|
||||
|
||||
@@ -91,4 +92,12 @@ bool GetCpuStepFlag();
|
||||
* @param is_step
|
||||
*/
|
||||
void SetCpuStepFlag(bool is_step);
|
||||
|
||||
/**
|
||||
* Send trap signal from thread back to the gdbstub server.
|
||||
*
|
||||
* @param thread Sending thread.
|
||||
* @param trap Trap no.
|
||||
*/
|
||||
void SendTrap(Kernel::Thread* thread, int trap);
|
||||
} // namespace GDBStub
|
||||
|
||||
173
src/core/hle/kernel/address_arbiter.cpp
Normal file
173
src/core/hle/kernel/address_arbiter.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
#include "core/hle/lock.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Kernel {
|
||||
namespace AddressArbiter {
|
||||
|
||||
// Performs actual address waiting logic.
|
||||
static ResultCode WaitForAddress(VAddr address, s64 timeout) {
|
||||
SharedPtr<Thread> current_thread = GetCurrentThread();
|
||||
current_thread->arb_wait_address = address;
|
||||
current_thread->status = THREADSTATUS_WAIT_ARB;
|
||||
current_thread->wakeup_callback = nullptr;
|
||||
|
||||
current_thread->WakeAfterDelay(timeout);
|
||||
|
||||
Core::System::GetInstance().CpuCore(current_thread->processor_id).PrepareReschedule();
|
||||
return RESULT_TIMEOUT;
|
||||
}
|
||||
|
||||
// Gets the threads waiting on an address.
|
||||
static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads,
|
||||
VAddr address) {
|
||||
auto RetrieveWaitingThreads =
|
||||
[](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) {
|
||||
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
|
||||
auto& thread_list = scheduler->GetThreadList();
|
||||
|
||||
for (auto& thread : thread_list) {
|
||||
if (thread->arb_wait_address == arb_addr)
|
||||
waiting_threads.push_back(thread);
|
||||
}
|
||||
};
|
||||
|
||||
// Retrieve a list of all threads that are waiting for this address.
|
||||
RetrieveWaitingThreads(0, waiting_threads, address);
|
||||
RetrieveWaitingThreads(1, waiting_threads, address);
|
||||
RetrieveWaitingThreads(2, waiting_threads, address);
|
||||
RetrieveWaitingThreads(3, waiting_threads, address);
|
||||
// Sort them by priority, such that the highest priority ones come first.
|
||||
std::sort(waiting_threads.begin(), waiting_threads.end(),
|
||||
[](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
|
||||
return lhs->current_priority < rhs->current_priority;
|
||||
});
|
||||
}
|
||||
|
||||
// Wake up num_to_wake (or all) threads in a vector.
|
||||
static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) {
|
||||
// Only process up to 'target' threads, unless 'target' is <= 0, in which case process
|
||||
// them all.
|
||||
size_t last = waiting_threads.size();
|
||||
if (num_to_wake > 0)
|
||||
last = num_to_wake;
|
||||
|
||||
// Signal the waiting threads.
|
||||
for (size_t i = 0; i < last; i++) {
|
||||
ASSERT(waiting_threads[i]->status = THREADSTATUS_WAIT_ARB);
|
||||
waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
waiting_threads[i]->arb_wait_address = 0;
|
||||
waiting_threads[i]->ResumeFromWait();
|
||||
}
|
||||
}
|
||||
|
||||
// Signals an address being waited on.
|
||||
ResultCode SignalToAddress(VAddr address, s32 num_to_wake) {
|
||||
// Get threads waiting on the address.
|
||||
std::vector<SharedPtr<Thread>> waiting_threads;
|
||||
GetThreadsWaitingOnAddress(waiting_threads, address);
|
||||
|
||||
WakeThreads(waiting_threads, num_to_wake);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
// Signals an address being waited on and increments its value if equal to the value argument.
|
||||
ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) {
|
||||
// Ensure that we can write to the address.
|
||||
if (!Memory::IsValidVirtualAddress(address)) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
|
||||
if (static_cast<s32>(Memory::Read32(address)) == value) {
|
||||
Memory::Write32(address, static_cast<u32>(value + 1));
|
||||
} else {
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return SignalToAddress(address, num_to_wake);
|
||||
}
|
||||
|
||||
// Signals an address being waited on and modifies its value based on waiting thread count if equal
|
||||
// to the value argument.
|
||||
ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
|
||||
s32 num_to_wake) {
|
||||
// Ensure that we can write to the address.
|
||||
if (!Memory::IsValidVirtualAddress(address)) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
|
||||
// Get threads waiting on the address.
|
||||
std::vector<SharedPtr<Thread>> waiting_threads;
|
||||
GetThreadsWaitingOnAddress(waiting_threads, address);
|
||||
|
||||
// Determine the modified value depending on the waiting count.
|
||||
s32 updated_value;
|
||||
if (waiting_threads.size() == 0) {
|
||||
updated_value = value - 1;
|
||||
} else if (num_to_wake <= 0 || waiting_threads.size() <= num_to_wake) {
|
||||
updated_value = value + 1;
|
||||
} else {
|
||||
updated_value = value;
|
||||
}
|
||||
|
||||
if (static_cast<s32>(Memory::Read32(address)) == value) {
|
||||
Memory::Write32(address, static_cast<u32>(updated_value));
|
||||
} else {
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
WakeThreads(waiting_threads, num_to_wake);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
// Waits on an address if the value passed is less than the argument value, optionally decrementing.
|
||||
ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement) {
|
||||
// Ensure that we can read the address.
|
||||
if (!Memory::IsValidVirtualAddress(address)) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
|
||||
s32 cur_value = static_cast<s32>(Memory::Read32(address));
|
||||
if (cur_value < value) {
|
||||
Memory::Write32(address, static_cast<u32>(cur_value - 1));
|
||||
} else {
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
// Short-circuit without rescheduling, if timeout is zero.
|
||||
if (timeout == 0) {
|
||||
return RESULT_TIMEOUT;
|
||||
}
|
||||
|
||||
return WaitForAddress(address, timeout);
|
||||
}
|
||||
|
||||
// Waits on an address if the value passed is equal to the argument value.
|
||||
ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) {
|
||||
// Ensure that we can read the address.
|
||||
if (!Memory::IsValidVirtualAddress(address)) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
// Only wait for the address if equal.
|
||||
if (static_cast<s32>(Memory::Read32(address)) != value) {
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
// Short-circuit without rescheduling, if timeout is zero.
|
||||
if (timeout == 0) {
|
||||
return RESULT_TIMEOUT;
|
||||
}
|
||||
|
||||
return WaitForAddress(address, timeout);
|
||||
}
|
||||
} // namespace AddressArbiter
|
||||
} // namespace Kernel
|
||||
32
src/core/hle/kernel/address_arbiter.h
Normal file
32
src/core/hle/kernel/address_arbiter.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
namespace AddressArbiter {
|
||||
enum class ArbitrationType {
|
||||
WaitIfLessThan = 0,
|
||||
DecrementAndWaitIfLessThan = 1,
|
||||
WaitIfEqual = 2,
|
||||
};
|
||||
|
||||
enum class SignalType {
|
||||
Signal = 0,
|
||||
IncrementAndSignalIfEqual = 1,
|
||||
ModifyByWaitingCountAndSignalIfEqual = 2,
|
||||
};
|
||||
|
||||
ResultCode SignalToAddress(VAddr address, s32 num_to_wake);
|
||||
ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake);
|
||||
ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake);
|
||||
|
||||
ResultCode WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, bool should_decrement);
|
||||
ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout);
|
||||
} // namespace AddressArbiter
|
||||
|
||||
} // namespace Kernel
|
||||
@@ -20,13 +20,16 @@ enum {
|
||||
MaxConnectionsReached = 52,
|
||||
|
||||
// Confirmed Switch OS error codes
|
||||
MisalignedAddress = 102,
|
||||
InvalidAddress = 102,
|
||||
InvalidMemoryState = 106,
|
||||
InvalidProcessorId = 113,
|
||||
InvalidHandle = 114,
|
||||
InvalidCombination = 116,
|
||||
Timeout = 117,
|
||||
SynchronizationCanceled = 118,
|
||||
TooLarge = 119,
|
||||
InvalidEnumValue = 120,
|
||||
InvalidState = 125,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -39,14 +42,15 @@ constexpr ResultCode ERR_SESSION_CLOSED_BY_REMOTE(-1);
|
||||
constexpr ResultCode ERR_PORT_NAME_TOO_LONG(-1);
|
||||
constexpr ResultCode ERR_WRONG_PERMISSION(-1);
|
||||
constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1);
|
||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE(-1);
|
||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE(ErrorModule::Kernel, ErrCodes::InvalidEnumValue);
|
||||
constexpr ResultCode ERR_INVALID_ENUM_VALUE_FND(-1);
|
||||
constexpr ResultCode ERR_INVALID_COMBINATION(-1);
|
||||
constexpr ResultCode ERR_INVALID_COMBINATION_KERNEL(-1);
|
||||
constexpr ResultCode ERR_OUT_OF_MEMORY(-1);
|
||||
constexpr ResultCode ERR_INVALID_ADDRESS(-1);
|
||||
constexpr ResultCode ERR_INVALID_ADDRESS_STATE(-1);
|
||||
constexpr ResultCode ERR_INVALID_ADDRESS(ErrorModule::Kernel, ErrCodes::InvalidAddress);
|
||||
constexpr ResultCode ERR_INVALID_ADDRESS_STATE(ErrorModule::Kernel, ErrCodes::InvalidMemoryState);
|
||||
constexpr ResultCode ERR_INVALID_HANDLE(ErrorModule::Kernel, ErrCodes::InvalidHandle);
|
||||
constexpr ResultCode ERR_INVALID_STATE(ErrorModule::Kernel, ErrCodes::InvalidState);
|
||||
constexpr ResultCode ERR_INVALID_POINTER(-1);
|
||||
constexpr ResultCode ERR_INVALID_OBJECT_ADDR(-1);
|
||||
constexpr ResultCode ERR_NOT_AUTHORIZED(-1);
|
||||
|
||||
@@ -26,7 +26,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
|
||||
|
||||
u16 slot = next_free_slot;
|
||||
if (slot >= generations.size()) {
|
||||
NGLOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
|
||||
LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
|
||||
return ERR_OUT_OF_HANDLES;
|
||||
}
|
||||
next_free_slot = generations[slot];
|
||||
@@ -48,7 +48,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
|
||||
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||
SharedPtr<Object> object = GetGeneric(handle);
|
||||
if (object == nullptr) {
|
||||
NGLOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
||||
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
return Create(std::move(object));
|
||||
|
||||
@@ -120,7 +120,7 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
|
||||
std::make_shared<IPC::DomainMessageHeader>(rp.PopRaw<IPC::DomainMessageHeader>());
|
||||
} else {
|
||||
if (Session()->IsDomain())
|
||||
NGLOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
|
||||
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,11 +271,16 @@ std::vector<u8> HLERequestContext::ReadBuffer(int buffer_index) const {
|
||||
}
|
||||
|
||||
size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size, int buffer_index) const {
|
||||
if (size == 0) {
|
||||
LOG_WARNING(Core, "skip empty buffer write");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[buffer_index].Size()};
|
||||
const size_t buffer_size{GetWriteBufferSize(buffer_index)};
|
||||
if (size > buffer_size) {
|
||||
NGLOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
|
||||
buffer_size);
|
||||
LOG_CRITICAL(Core, "size ({:016X}) is greater than buffer_size ({:016X})", size,
|
||||
buffer_size);
|
||||
size = buffer_size; // TODO(bunnei): This needs to be HW tested
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
Handle requesting_thread_handle) {
|
||||
// The mutex address must be 4-byte aligned
|
||||
if ((address % sizeof(u32)) != 0) {
|
||||
return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress);
|
||||
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress);
|
||||
}
|
||||
|
||||
SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle);
|
||||
@@ -97,7 +97,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||
ResultCode Mutex::Release(VAddr address) {
|
||||
// The mutex address must be 4-byte aligned
|
||||
if ((address % sizeof(u32)) != 0) {
|
||||
return ResultCode(ErrorModule::Kernel, ErrCodes::MisalignedAddress);
|
||||
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress);
|
||||
}
|
||||
|
||||
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(GetCurrentThread(), address);
|
||||
|
||||
@@ -54,7 +54,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
||||
continue;
|
||||
} else if ((type & 0xF00) == 0xE00) { // 0x0FFF
|
||||
// Allowed interrupts list
|
||||
NGLOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
|
||||
LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
|
||||
} else if ((type & 0xF80) == 0xF00) { // 0x07FF
|
||||
// Allowed syscalls mask
|
||||
unsigned int index = ((descriptor >> 24) & 7) * 24;
|
||||
@@ -74,7 +74,7 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
||||
} else if ((type & 0xFFE) == 0xFF8) { // 0x001F
|
||||
// Mapped memory range
|
||||
if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) {
|
||||
NGLOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
|
||||
LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
|
||||
continue;
|
||||
}
|
||||
u32 end_desc = kernel_caps[i + 1];
|
||||
@@ -109,9 +109,9 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
|
||||
|
||||
int minor = kernel_version & 0xFF;
|
||||
int major = (kernel_version >> 8) & 0xFF;
|
||||
NGLOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor);
|
||||
LOG_INFO(Loader, "ExHeader kernel version: {}.{}", major, minor);
|
||||
} else {
|
||||
NGLOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor);
|
||||
LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x{:08X}", descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory cat
|
||||
case ResourceLimitCategory::OTHER:
|
||||
return resource_limits[static_cast<u8>(category)];
|
||||
default:
|
||||
NGLOG_CRITICAL(Kernel, "Unknown resource limit category");
|
||||
LOG_CRITICAL(Kernel, "Unknown resource limit category");
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
|
||||
case ResourceType::CPUTime:
|
||||
return current_cpu_time;
|
||||
default:
|
||||
NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
|
||||
LOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ u32 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
|
||||
case ResourceType::CPUTime:
|
||||
return max_cpu_time;
|
||||
default:
|
||||
NGLOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
|
||||
LOG_ERROR(Kernel, "Unknown resource type={:08X}", static_cast<u32>(resource));
|
||||
UNIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -99,11 +99,11 @@ void Scheduler::Reschedule() {
|
||||
Thread* next = PopNextReadyThread();
|
||||
|
||||
if (cur && next) {
|
||||
NGLOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId());
|
||||
LOG_TRACE(Kernel, "context switch {} -> {}", cur->GetObjectId(), next->GetObjectId());
|
||||
} else if (cur) {
|
||||
NGLOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId());
|
||||
LOG_TRACE(Kernel, "context switch {} -> idle", cur->GetObjectId());
|
||||
} else if (next) {
|
||||
NGLOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId());
|
||||
LOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId());
|
||||
}
|
||||
|
||||
SwitchContext(next);
|
||||
|
||||
@@ -71,7 +71,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||
return domain_request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||
|
||||
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
|
||||
NGLOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
|
||||
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
|
||||
|
||||
domain_request_handlers[object_id - 1] = nullptr;
|
||||
|
||||
@@ -81,8 +81,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||
}
|
||||
}
|
||||
|
||||
NGLOG_CRITICAL(IPC, "Unknown domain command={}",
|
||||
static_cast<int>(domain_message_header->command.Value()));
|
||||
LOG_CRITICAL(IPC, "Unknown domain command={}",
|
||||
static_cast<int>(domain_message_header->command.Value()));
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,16 +107,16 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
|
||||
// Error out if the requested permissions don't match what the creator process allows.
|
||||
if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
|
||||
NGLOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
LOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
// Error out if the provided permissions are not compatible with what the creator process needs.
|
||||
if (other_permissions != MemoryPermission::DontCare &&
|
||||
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
|
||||
NGLOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
LOG_ERROR(Kernel, "cannot map id={}, address=0x{:X} name={}, permissions don't match",
|
||||
GetObjectId(), address, name);
|
||||
return ERR_WRONG_PERMISSION;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
auto result = target_process->vm_manager.MapMemoryBlock(
|
||||
target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
|
||||
if (result.Failed()) {
|
||||
NGLOG_ERROR(
|
||||
LOG_ERROR(
|
||||
Kernel,
|
||||
"cannot map id={}, target_address=0x{:X} name={}, error mapping to virtual memory",
|
||||
GetObjectId(), target_address, name);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/kernel/address_arbiter.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
@@ -31,7 +32,7 @@ namespace Kernel {
|
||||
|
||||
/// Set the process heap to a given Size. It can both extend and shrink the heap.
|
||||
static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
|
||||
LOG_TRACE(Kernel_SVC, "called, heap_size=0x{:X}", heap_size);
|
||||
auto& process = *Core::CurrentProcess();
|
||||
CASCADE_RESULT(*heap_addr,
|
||||
process.HeapAllocate(Memory::HEAP_VADDR, heap_size, VMAPermission::ReadWrite));
|
||||
@@ -39,21 +40,21 @@ static ResultCode SetHeapSize(VAddr* heap_addr, u64 heap_size) {
|
||||
}
|
||||
|
||||
static ResultCode SetMemoryAttribute(VAddr addr, u64 size, u32 state0, u32 state1) {
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}", addr);
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, addr=0x{:X}", addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Maps a memory range into a different range.
|
||||
static ResultCode MapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||
src_addr, size);
|
||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||
src_addr, size);
|
||||
return Core::CurrentProcess()->MirrorMemory(dst_addr, src_addr, size);
|
||||
}
|
||||
|
||||
/// Unmaps a region that was previously mapped with svcMapMemory
|
||||
static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||
src_addr, size);
|
||||
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
|
||||
src_addr, size);
|
||||
return Core::CurrentProcess()->UnmapMemory(dst_addr, src_addr, size);
|
||||
}
|
||||
|
||||
@@ -68,11 +69,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
|
||||
if (port_name.size() > PortNameMaxLength)
|
||||
return ERR_PORT_NAME_TOO_LONG;
|
||||
|
||||
NGLOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
|
||||
LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
|
||||
|
||||
auto it = Service::g_kernel_named_ports.find(port_name);
|
||||
if (it == Service::g_kernel_named_ports.end()) {
|
||||
NGLOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
|
||||
LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
|
||||
return ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -90,11 +91,11 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
|
||||
static ResultCode SendSyncRequest(Handle handle) {
|
||||
SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle);
|
||||
if (!session) {
|
||||
NGLOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
||||
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
NGLOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
|
||||
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
|
||||
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
|
||||
@@ -105,7 +106,7 @@ static ResultCode SendSyncRequest(Handle handle) {
|
||||
|
||||
/// Get the ID for the specified thread.
|
||||
static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -118,7 +119,7 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
|
||||
|
||||
/// Get the ID of the specified process
|
||||
static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
|
||||
|
||||
const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle);
|
||||
if (!process) {
|
||||
@@ -148,8 +149,8 @@ static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thr
|
||||
/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
|
||||
static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 handle_count,
|
||||
s64 nano_seconds) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
|
||||
handles_address, handle_count, nano_seconds);
|
||||
LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}",
|
||||
handles_address, handle_count, nano_seconds);
|
||||
|
||||
if (!Memory::IsValidVirtualAddress(handles_address))
|
||||
return ERR_INVALID_POINTER;
|
||||
@@ -209,7 +210,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
|
||||
|
||||
/// Resumes a thread waiting on WaitSynchronization
|
||||
static ResultCode CancelSynchronization(Handle thread_handle) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -226,24 +227,24 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
|
||||
/// Attempts to locks a mutex, creating it if it does not already exist
|
||||
static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
Handle requesting_thread_handle) {
|
||||
NGLOG_TRACE(Kernel_SVC,
|
||||
"called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, "
|
||||
"requesting_current_thread_handle=0x{:08X}",
|
||||
holding_thread_handle, mutex_addr, requesting_thread_handle);
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called holding_thread_handle=0x{:08X}, mutex_addr=0x{:X}, "
|
||||
"requesting_current_thread_handle=0x{:08X}",
|
||||
holding_thread_handle, mutex_addr, requesting_thread_handle);
|
||||
|
||||
return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle);
|
||||
}
|
||||
|
||||
/// Unlock a mutex
|
||||
static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr);
|
||||
LOG_TRACE(Kernel_SVC, "called mutex_addr=0x{:X}", mutex_addr);
|
||||
|
||||
return Mutex::Release(mutex_addr);
|
||||
}
|
||||
|
||||
/// Break program execution
|
||||
static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
|
||||
NGLOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
|
||||
LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
@@ -251,13 +252,13 @@ static void Break(u64 unk_0, u64 unk_1, u64 unk_2) {
|
||||
static void OutputDebugString(VAddr address, s32 len) {
|
||||
std::string str(len, '\0');
|
||||
Memory::ReadBlock(address, str.data(), str.size());
|
||||
NGLOG_DEBUG(Debug_Emulated, "{}", str);
|
||||
LOG_DEBUG(Debug_Emulated, "{}", str);
|
||||
}
|
||||
|
||||
/// Gets system/memory information for the current process
|
||||
static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
|
||||
info_sub_id, handle);
|
||||
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
|
||||
info_sub_id, handle);
|
||||
|
||||
auto& vm_manager = Core::CurrentProcess()->vm_manager;
|
||||
|
||||
@@ -308,12 +309,17 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
*result = Core::CurrentProcess()->is_virtual_address_memory_enabled;
|
||||
break;
|
||||
case GetInfoType::TitleId:
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
case GetInfoType::PrivilegedProcessId:
|
||||
NGLOG_WARNING(Kernel_SVC,
|
||||
"(STUBBED) Attempted to query privileged process id bounds, returned 0");
|
||||
LOG_WARNING(Kernel_SVC,
|
||||
"(STUBBED) Attempted to query privileged process id bounds, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
case GetInfoType::UserExceptionContextAddr:
|
||||
LOG_WARNING(Kernel_SVC,
|
||||
"(STUBBED) Attempted to query user exception context address, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
default:
|
||||
@@ -325,14 +331,13 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
|
||||
/// Sets the thread activity
|
||||
static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, unknown=0x{:08X}", handle,
|
||||
unknown);
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, unknown=0x{:08X}", handle, unknown);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Gets the thread context
|
||||
static ResultCode GetThreadContext(Handle handle, VAddr addr) {
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr);
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x{:08X}, addr=0x{:X}", handle, addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -371,16 +376,15 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
|
||||
|
||||
/// Get which CPU core is executing the current thread
|
||||
static u32 GetCurrentProcessorNumber() {
|
||||
NGLOG_TRACE(Kernel_SVC, "called");
|
||||
LOG_TRACE(Kernel_SVC, "called");
|
||||
return GetCurrentThread()->processor_id;
|
||||
}
|
||||
|
||||
static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size,
|
||||
u32 permissions) {
|
||||
NGLOG_TRACE(
|
||||
Kernel_SVC,
|
||||
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
||||
shared_memory_handle, addr, size, permissions);
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
|
||||
shared_memory_handle, addr, size, permissions);
|
||||
|
||||
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
|
||||
if (!shared_memory) {
|
||||
@@ -400,15 +404,15 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
|
||||
return shared_memory->Map(Core::CurrentProcess().get(), addr, permissions_type,
|
||||
MemoryPermission::DontCare);
|
||||
default:
|
||||
NGLOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
|
||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size) {
|
||||
NGLOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
|
||||
shared_memory_handle, addr, size);
|
||||
LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
|
||||
shared_memory_handle, addr, size);
|
||||
|
||||
SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle);
|
||||
|
||||
@@ -436,19 +440,19 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_i
|
||||
memory_info->type = static_cast<u32>(vma->second.meminfo_state);
|
||||
}
|
||||
|
||||
NGLOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr);
|
||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} addr={:X}", process_handle, addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Query memory
|
||||
static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, VAddr addr) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, addr={:X}", addr);
|
||||
LOG_TRACE(Kernel_SVC, "called, addr={:X}", addr);
|
||||
return QueryProcessMemory(memory_info, page_info, CurrentProcess, addr);
|
||||
}
|
||||
|
||||
/// Exits the current process
|
||||
static void ExitProcess() {
|
||||
NGLOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id);
|
||||
LOG_INFO(Kernel_SVC, "Process {} exiting", Core::CurrentProcess()->process_id);
|
||||
|
||||
ASSERT_MSG(Core::CurrentProcess()->status == ProcessStatus::Running,
|
||||
"Process has already exited");
|
||||
@@ -524,17 +528,17 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule();
|
||||
|
||||
NGLOG_TRACE(Kernel_SVC,
|
||||
"called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, "
|
||||
"threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
|
||||
entry_point, name, arg, stack_top, priority, processor_id, *out_handle);
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, "
|
||||
"threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
|
||||
entry_point, name, arg, stack_top, priority, processor_id, *out_handle);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Starts the thread for the provided handle
|
||||
static ResultCode StartThread(Handle thread_handle) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -551,7 +555,7 @@ static ResultCode StartThread(Handle thread_handle) {
|
||||
|
||||
/// Called when a thread exits
|
||||
static void ExitThread() {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC());
|
||||
LOG_TRACE(Kernel_SVC, "called, pc=0x{:08X}", Core::CurrentArmInterface().GetPC());
|
||||
|
||||
ExitCurrentThread();
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
@@ -559,7 +563,7 @@ static void ExitThread() {
|
||||
|
||||
/// Sleep the current thread
|
||||
static void SleepThread(s64 nanoseconds) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
|
||||
LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds);
|
||||
|
||||
// Don't attempt to yield execution if there are no available threads to run,
|
||||
// this way we avoid a useless reschedule to the idle thread.
|
||||
@@ -575,10 +579,10 @@ static void SleepThread(s64 nanoseconds) {
|
||||
Core::System::GetInstance().PrepareReschedule();
|
||||
}
|
||||
|
||||
/// Signal process wide key atomic
|
||||
/// Wait process wide key atomic
|
||||
static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_variable_addr,
|
||||
Handle thread_handle, s64 nano_seconds) {
|
||||
NGLOG_TRACE(
|
||||
LOG_TRACE(
|
||||
Kernel_SVC,
|
||||
"called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}",
|
||||
mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
|
||||
@@ -605,8 +609,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
|
||||
|
||||
/// Signal process wide key
|
||||
static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
|
||||
condition_variable_addr, target);
|
||||
LOG_TRACE(Kernel_SVC, "called, condition_variable_addr=0x{:X}, target=0x{:08X}",
|
||||
condition_variable_addr, target);
|
||||
|
||||
auto RetrieveWaitingThreads =
|
||||
[](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr condvar_addr) {
|
||||
@@ -684,6 +688,57 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
// Wait for an address (via Address Arbiter)
|
||||
static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout) {
|
||||
LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, timeout={}",
|
||||
address, type, value, timeout);
|
||||
// If the passed address is a kernel virtual address, return invalid memory state.
|
||||
if (Memory::IsKernelVirtualAddress(address)) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
// If the address is not properly aligned to 4 bytes, return invalid address.
|
||||
if (address % sizeof(u32) != 0) {
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
switch (static_cast<AddressArbiter::ArbitrationType>(type)) {
|
||||
case AddressArbiter::ArbitrationType::WaitIfLessThan:
|
||||
return AddressArbiter::WaitForAddressIfLessThan(address, value, timeout, false);
|
||||
case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan:
|
||||
return AddressArbiter::WaitForAddressIfLessThan(address, value, timeout, true);
|
||||
case AddressArbiter::ArbitrationType::WaitIfEqual:
|
||||
return AddressArbiter::WaitForAddressIfEqual(address, value, timeout);
|
||||
default:
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Signals to an address (via Address Arbiter)
|
||||
static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to_wake) {
|
||||
LOG_WARNING(Kernel_SVC, "called, address=0x{:X}, type=0x{:X}, value=0x{:X}, num_to_wake=0x{:X}",
|
||||
address, type, value, num_to_wake);
|
||||
// If the passed address is a kernel virtual address, return invalid memory state.
|
||||
if (Memory::IsKernelVirtualAddress(address)) {
|
||||
return ERR_INVALID_ADDRESS_STATE;
|
||||
}
|
||||
// If the address is not properly aligned to 4 bytes, return invalid address.
|
||||
if (address % sizeof(u32) != 0) {
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
switch (static_cast<AddressArbiter::SignalType>(type)) {
|
||||
case AddressArbiter::SignalType::Signal:
|
||||
return AddressArbiter::SignalToAddress(address, num_to_wake);
|
||||
case AddressArbiter::SignalType::IncrementAndSignalIfEqual:
|
||||
return AddressArbiter::IncrementAndSignalToAddressIfEqual(address, value, num_to_wake);
|
||||
case AddressArbiter::SignalType::ModifyByWaitingCountAndSignalIfEqual:
|
||||
return AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(address, value,
|
||||
num_to_wake);
|
||||
default:
|
||||
return ERR_INVALID_ENUM_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/// This returns the total CPU ticks elapsed since the CPU was powered-on
|
||||
static u64 GetSystemTick() {
|
||||
const u64 result{CoreTiming::GetTicks()};
|
||||
@@ -696,13 +751,13 @@ static u64 GetSystemTick() {
|
||||
|
||||
/// Close a handle
|
||||
static ResultCode CloseHandle(Handle handle) {
|
||||
NGLOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
|
||||
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
|
||||
return g_handle_table.Close(handle);
|
||||
}
|
||||
|
||||
/// Reset an event
|
||||
static ResultCode ResetSignal(Handle handle) {
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle);
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle);
|
||||
auto event = g_handle_table.Get<Event>(handle);
|
||||
ASSERT(event != nullptr);
|
||||
event->Clear();
|
||||
@@ -711,14 +766,14 @@ static ResultCode ResetSignal(Handle handle) {
|
||||
|
||||
/// Creates a TransferMemory object
|
||||
static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32 permissions) {
|
||||
NGLOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr,
|
||||
size, permissions);
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size,
|
||||
permissions);
|
||||
*handle = 0;
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
|
||||
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -732,8 +787,8 @@ static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask)
|
||||
}
|
||||
|
||||
static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
||||
NGLOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
|
||||
mask, core);
|
||||
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
|
||||
mask, core);
|
||||
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle);
|
||||
if (!thread) {
|
||||
@@ -744,7 +799,7 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
||||
ASSERT(thread->owner_process->ideal_processor != THREADPROCESSORID_DEFAULT);
|
||||
// Set the target CPU to the one specified in the process' exheader.
|
||||
core = thread->owner_process->ideal_processor;
|
||||
mask = 1 << core;
|
||||
mask = 1ull << core;
|
||||
}
|
||||
|
||||
if (mask == 0) {
|
||||
@@ -761,7 +816,7 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
||||
}
|
||||
|
||||
// Error out if the input core isn't enabled in the input mask.
|
||||
if (core < Core::NUM_CPU_CORES && (mask & (1 << core)) == 0) {
|
||||
if (core < Core::NUM_CPU_CORES && (mask & (1ull << core)) == 0) {
|
||||
return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidCombination);
|
||||
}
|
||||
|
||||
@@ -772,8 +827,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
|
||||
|
||||
static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permissions,
|
||||
u32 remote_permissions) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
|
||||
local_permissions, remote_permissions);
|
||||
LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
|
||||
local_permissions, remote_permissions);
|
||||
auto sharedMemHandle =
|
||||
SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
|
||||
static_cast<MemoryPermission>(local_permissions),
|
||||
@@ -784,7 +839,7 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
|
||||
}
|
||||
|
||||
static ResultCode ClearEvent(Handle handle) {
|
||||
NGLOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
|
||||
LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
|
||||
|
||||
SharedPtr<Event> evt = g_handle_table.Get<Event>(handle);
|
||||
if (evt == nullptr)
|
||||
@@ -856,8 +911,8 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x31, nullptr, "GetResourceLimitCurrentValue"},
|
||||
{0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
|
||||
{0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
|
||||
{0x34, nullptr, "WaitForAddress"},
|
||||
{0x35, nullptr, "SignalToAddress"},
|
||||
{0x34, SvcWrap<WaitForAddress>, "WaitForAddress"},
|
||||
{0x35, SvcWrap<SignalToAddress>, "SignalToAddress"},
|
||||
{0x36, nullptr, "Unknown"},
|
||||
{0x37, nullptr, "Unknown"},
|
||||
{0x38, nullptr, "Unknown"},
|
||||
@@ -936,7 +991,7 @@ static const FunctionDef SVC_Table[] = {
|
||||
|
||||
static const FunctionDef* GetSVCInfo(u32 func_num) {
|
||||
if (func_num >= std::size(SVC_Table)) {
|
||||
NGLOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num);
|
||||
LOG_ERROR(Kernel_SVC, "Unknown svc=0x{:02X}", func_num);
|
||||
return nullptr;
|
||||
}
|
||||
return &SVC_Table[func_num];
|
||||
@@ -955,10 +1010,10 @@ void CallSVC(u32 immediate) {
|
||||
if (info->func) {
|
||||
info->func();
|
||||
} else {
|
||||
NGLOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
|
||||
LOG_CRITICAL(Kernel_SVC, "Unimplemented SVC function {}(..)", info->name);
|
||||
}
|
||||
} else {
|
||||
NGLOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
|
||||
LOG_CRITICAL(Kernel_SVC, "Unknown SVC function 0x{:X}", immediate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,20 @@ void SvcWrap() {
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(u64, u32, s32, s64)>
|
||||
void SvcWrap() {
|
||||
FuncReturn(
|
||||
func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF), (s64)PARAM(3))
|
||||
.raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(u64, u32, s32, s32)>
|
||||
void SvcWrap() {
|
||||
FuncReturn(func(PARAM(0), (u32)(PARAM(1) & 0xFFFFFFFF), (s32)(PARAM(2) & 0xFFFFFFFF),
|
||||
(s32)(PARAM(3) & 0xFFFFFFFF))
|
||||
.raw);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Function wrappers that return type u32
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
|
||||
const auto proper_handle = static_cast<Handle>(thread_handle);
|
||||
SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle);
|
||||
if (thread == nullptr) {
|
||||
NGLOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
|
||||
LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,11 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
|
||||
}
|
||||
}
|
||||
|
||||
if (thread->arb_wait_address != 0) {
|
||||
ASSERT(thread->status == THREADSTATUS_WAIT_ARB);
|
||||
thread->arb_wait_address = 0;
|
||||
}
|
||||
|
||||
if (resume)
|
||||
thread->ResumeFromWait();
|
||||
}
|
||||
@@ -179,6 +184,7 @@ void Thread::ResumeFromWait() {
|
||||
case THREADSTATUS_WAIT_SLEEP:
|
||||
case THREADSTATUS_WAIT_IPC:
|
||||
case THREADSTATUS_WAIT_MUTEX:
|
||||
case THREADSTATUS_WAIT_ARB:
|
||||
break;
|
||||
|
||||
case THREADSTATUS_READY:
|
||||
@@ -284,19 +290,19 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||
SharedPtr<Process> owner_process) {
|
||||
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
||||
if (priority > THREADPRIO_LOWEST) {
|
||||
NGLOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
|
||||
LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
|
||||
return ERR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (processor_id > THREADPROCESSORID_MAX) {
|
||||
NGLOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id);
|
||||
LOG_ERROR(Kernel_SVC, "Invalid processor id: {}", processor_id);
|
||||
return ERR_OUT_OF_RANGE_KERNEL;
|
||||
}
|
||||
|
||||
// TODO(yuriks): Other checks, returning 0xD9001BEA
|
||||
|
||||
if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) {
|
||||
NGLOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
|
||||
LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:016X}", name, entry_point);
|
||||
// TODO (bunnei): Find the correct error code to use here
|
||||
return ResultCode(-1);
|
||||
}
|
||||
@@ -337,8 +343,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
|
||||
auto& linheap_memory = memory_region->linear_heap_memory;
|
||||
|
||||
if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
|
||||
NGLOG_ERROR(Kernel_SVC,
|
||||
"Not enough space in region to allocate a new TLS page for thread");
|
||||
LOG_ERROR(Kernel_SVC,
|
||||
"Not enough space in region to allocate a new TLS page for thread");
|
||||
return ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ enum ThreadStatus {
|
||||
THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false
|
||||
THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true
|
||||
THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc
|
||||
THREADSTATUS_WAIT_ARB, ///< Waiting due to a SignalToAddress/WaitForAddress svc
|
||||
THREADSTATUS_DORMANT, ///< Created but not yet made ready
|
||||
THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated
|
||||
};
|
||||
@@ -230,6 +231,9 @@ public:
|
||||
VAddr mutex_wait_address; ///< If waiting on a Mutex, this is the mutex address
|
||||
Handle wait_handle; ///< The handle used to wait for the mutex.
|
||||
|
||||
// If waiting for an AddressArbiter, this is the address being waited on.
|
||||
VAddr arb_wait_address{0};
|
||||
|
||||
std::string name;
|
||||
|
||||
/// Handle used by guest emulated application to access this thread
|
||||
|
||||
@@ -78,7 +78,7 @@ void Timer::WakeupAllWaitingThreads() {
|
||||
}
|
||||
|
||||
void Timer::Signal(int cycles_late) {
|
||||
NGLOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
|
||||
LOG_TRACE(Kernel, "Timer {} fired", GetObjectId());
|
||||
|
||||
signaled = true;
|
||||
|
||||
@@ -98,7 +98,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
|
||||
timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
|
||||
|
||||
if (timer == nullptr) {
|
||||
NGLOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
|
||||
LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -242,12 +242,12 @@ void VMManager::RefreshMemoryBlockMappings(const std::vector<u8>* block) {
|
||||
void VMManager::LogLayout() const {
|
||||
for (const auto& p : vma_map) {
|
||||
const VirtualMemoryArea& vma = p.second;
|
||||
NGLOG_DEBUG(Kernel, "{:016X} - {:016X} size: {:016X} {}{}{} {}", vma.base,
|
||||
vma.base + vma.size, vma.size,
|
||||
(u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-',
|
||||
(u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-',
|
||||
(u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-',
|
||||
GetMemoryStateName(vma.meminfo_state));
|
||||
LOG_DEBUG(Kernel, "{:016X} - {:016X} size: {:016X} {}{}{} {}", vma.base,
|
||||
vma.base + vma.size, vma.size,
|
||||
(u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-',
|
||||
(u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-',
|
||||
(u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-',
|
||||
GetMemoryStateName(vma.meminfo_state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,22 +392,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
|
||||
}
|
||||
|
||||
u64 VMManager::GetTotalMemoryUsage() {
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0xF8000000;
|
||||
}
|
||||
|
||||
u64 VMManager::GetTotalHeapUsage() {
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetAddressSpaceBaseAddr() {
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x8000000;
|
||||
}
|
||||
|
||||
u64 VMManager::GetAddressSpaceSize() {
|
||||
NGLOG_WARNING(Kernel, "(STUBBED) called");
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return MAX_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
|
||||
private:
|
||||
void GetBase(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
ProfileBase profile_base{};
|
||||
IPC::ResponseBuilder rb{ctx, 16};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -72,14 +72,14 @@ public:
|
||||
|
||||
private:
|
||||
void CheckAvailability(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(true); // TODO: Check when this is supposed to return true and when not
|
||||
}
|
||||
|
||||
void GetAccountId(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0x12345678ABCDEF);
|
||||
@@ -87,14 +87,14 @@ private:
|
||||
};
|
||||
|
||||
void Module::Interface::GetUserExistence(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(true); // TODO: Check when this is supposed to return true and when not
|
||||
}
|
||||
|
||||
void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
|
||||
ctx.WriteBuffer(user_ids.data(), user_ids.size());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
@@ -102,7 +102,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
constexpr std::array<u128, 10> user_ids{DEFAULT_USER_ID};
|
||||
ctx.WriteBuffer(user_ids.data(), user_ids.size());
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
@@ -113,11 +113,11 @@ void Module::Interface::GetProfile(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProfile>();
|
||||
NGLOG_DEBUG(Service_ACC, "called");
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
}
|
||||
|
||||
void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -126,11 +126,11 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IManagerForApplication>();
|
||||
NGLOG_DEBUG(Service_ACC, "called");
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
}
|
||||
|
||||
void Module::Interface::GetLastOpenedUser(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_ACC, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 6};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(DEFAULT_USER_ID);
|
||||
|
||||
@@ -30,14 +30,14 @@ IWindowController::IWindowController() : ServiceFramework("IWindowController") {
|
||||
}
|
||||
|
||||
void IWindowController::GetAppletResourceUserId(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
}
|
||||
|
||||
void IWindowController::AcquireForegroundRights(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -56,20 +56,20 @@ IAudioController::IAudioController() : ServiceFramework("IAudioController") {
|
||||
}
|
||||
|
||||
void IAudioController::SetExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void IAudioController::GetMainAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(volume);
|
||||
}
|
||||
|
||||
void IAudioController::GetLibraryAppletExpectedMasterVolume(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(volume);
|
||||
@@ -174,14 +174,14 @@ void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
|
||||
@@ -192,14 +192,14 @@ void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestCo
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
|
||||
}
|
||||
|
||||
void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
|
||||
@@ -210,7 +210,7 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
|
||||
}
|
||||
|
||||
void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
|
||||
@@ -223,21 +223,21 @@ void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext&
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
|
||||
}
|
||||
|
||||
void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -247,7 +247,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext&
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(launchable_event);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
|
||||
@@ -260,14 +260,14 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx)
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(layer_id);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
|
||||
@@ -311,7 +311,7 @@ void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(event);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
|
||||
@@ -319,7 +319,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(15);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
|
||||
@@ -327,7 +327,7 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u8>(FocusState::InFocus));
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
|
||||
@@ -336,7 +336,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
@@ -346,7 +346,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
|
||||
: APM::PerformanceMode::Handheld));
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||
@@ -370,7 +370,7 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(buffer.size()));
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void Write(Kernel::HLERequestContext& ctx) {
|
||||
@@ -386,7 +386,7 @@ private:
|
||||
IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called, offset={}", offset);
|
||||
LOG_DEBUG(Service_AM, "called, offset={}", offset);
|
||||
}
|
||||
|
||||
void Read(Kernel::HLERequestContext& ctx) {
|
||||
@@ -402,7 +402,7 @@ private:
|
||||
IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called, offset={}", offset);
|
||||
LOG_DEBUG(Service_AM, "called, offset={}", offset);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -426,7 +426,7 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -467,21 +467,21 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(state_changed_event);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetResult(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void Start(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void PushInData(Kernel::HLERequestContext& ctx) {
|
||||
@@ -491,7 +491,7 @@ private:
|
||||
IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void PopOutData(Kernel::HLERequestContext& ctx) {
|
||||
@@ -501,7 +501,7 @@ private:
|
||||
|
||||
storage_stack.pop();
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
std::stack<std::shared_ptr<AM::IStorage>> storage_stack;
|
||||
@@ -526,7 +526,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::ILibraryAppletAccessor>();
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
||||
@@ -538,7 +538,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorage>(std::move(buffer));
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called, size={}", size);
|
||||
LOG_DEBUG(Service_AM, "called, size={}", size);
|
||||
}
|
||||
|
||||
IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
|
||||
@@ -561,7 +561,7 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF
|
||||
{32, nullptr, "BeginBlockingHomeButton"},
|
||||
{33, nullptr, "EndBlockingHomeButton"},
|
||||
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
|
||||
{50, nullptr, "GetPseudoDeviceId"},
|
||||
{50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
|
||||
{60, nullptr, "SetMediaPlaybackStateForApplication"},
|
||||
{65, nullptr, "IsGamePlayRecordingSupported"},
|
||||
{66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
|
||||
@@ -602,21 +602,21 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorage>(buffer);
|
||||
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(
|
||||
Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::EnsureSaveData(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
u128 uid = rp.PopRaw<u128>();
|
||||
|
||||
NGLOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
|
||||
LOG_WARNING(Service, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
|
||||
@@ -644,7 +644,7 @@ void IApplicationFunctions::SetTerminateResult(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
|
||||
@@ -652,7 +652,7 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(1);
|
||||
rb.Push<u64>(0);
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
@@ -660,20 +660,20 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US));
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
|
||||
@@ -681,7 +681,18 @@ void IApplicationFunctions::NotifyRunning(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
|
||||
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 6};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
// Returns a 128-bit UUID
|
||||
rb.Push<u64>(0);
|
||||
rb.Push<u64>(0);
|
||||
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||
@@ -706,7 +717,7 @@ IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions"
|
||||
void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||
}
|
||||
|
||||
IGlobalStateController::IGlobalStateController() : ServiceFramework("IGlobalStateController") {
|
||||
|
||||
@@ -138,6 +138,7 @@ private:
|
||||
void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx);
|
||||
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
|
||||
void NotifyRunning(Kernel::HLERequestContext& ctx);
|
||||
void GetPseudoDeviceId(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
|
||||
|
||||
@@ -33,63 +33,63 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetSelfController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISelfController>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetWindowController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IWindowController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetAudioController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetProcessWindingController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProcessWindingController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ILibraryAppletCreator>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationFunctions>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
@@ -120,70 +120,70 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetSelfController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISelfController>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetWindowController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IWindowController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetAudioController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ILibraryAppletCreator>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetHomeMenuFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IHomeMenuFunctions>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetGlobalStateController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IGlobalStateController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetApplicationCreator(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationCreator>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
};
|
||||
@@ -192,21 +192,21 @@ void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISystemAppletProxy>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
|
||||
|
||||
@@ -33,56 +33,56 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetWindowController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IWindowController>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetSelfController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISelfController>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ILibraryAppletCreator>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationFunctions>();
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
|
||||
@@ -92,7 +92,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationProxy>(nvflinger);
|
||||
NGLOG_DEBUG(Service_AM, "called");
|
||||
LOG_DEBUG(Service_AM, "called");
|
||||
}
|
||||
|
||||
AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
|
||||
|
||||
@@ -27,14 +27,14 @@ void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
NGLOG_WARNING(Service_AOC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AOC, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void AOC_U::ListAddOnContent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
NGLOG_WARNING(Service_AOC, "(STUBBED) called");
|
||||
LOG_WARNING(Service_AOC, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
|
||||
@@ -29,8 +29,8 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode),
|
||||
config);
|
||||
LOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode),
|
||||
config);
|
||||
}
|
||||
|
||||
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
|
||||
@@ -42,7 +42,7 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0); // Performance configuration
|
||||
|
||||
NGLOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode));
|
||||
LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/hle/service/audio/audrec_u.h"
|
||||
#include "core/hle/service/audio/audren_u.h"
|
||||
#include "core/hle/service/audio/codecctl.h"
|
||||
#include "core/hle/service/audio/hwopus.h"
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
@@ -17,6 +18,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<AudRecU>()->InstallAsService(service_manager);
|
||||
std::make_shared<AudRenU>()->InstallAsService(service_manager);
|
||||
std::make_shared<CodecCtl>()->InstallAsService(service_manager);
|
||||
std::make_shared<HwOpus>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
|
||||
@@ -60,14 +60,14 @@ public:
|
||||
|
||||
private:
|
||||
void GetAudioOutState(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_Audio, "called");
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u32>(audio_out_state));
|
||||
}
|
||||
|
||||
void StartAudioOut(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
// Start audio
|
||||
audio_out_state = AudioState::Started;
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
}
|
||||
|
||||
void StopAudioOut(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
// Stop audio
|
||||
audio_out_state = AudioState::Stopped;
|
||||
@@ -89,7 +89,7 @@ private:
|
||||
}
|
||||
|
||||
void RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -97,7 +97,7 @@ private:
|
||||
}
|
||||
|
||||
void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
const u64 key{rp.Pop<u64>()};
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
}
|
||||
|
||||
void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
// TODO(st4rk): This is how libtransistor currently implements the
|
||||
// GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address
|
||||
@@ -164,7 +164,7 @@ private:
|
||||
};
|
||||
|
||||
void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
const std::string audio_interface = "AudioInterface";
|
||||
@@ -180,7 +180,7 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
if (!audio_out_interface) {
|
||||
audio_out_interface = std::make_shared<IAudioOut>();
|
||||
|
||||
@@ -17,7 +17,8 @@ constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)};
|
||||
|
||||
class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
|
||||
public:
|
||||
IAudioRenderer() : ServiceFramework("IAudioRenderer") {
|
||||
IAudioRenderer(AudioRendererParameter audren_params)
|
||||
: ServiceFramework("IAudioRenderer"), worker_params(audren_params) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetAudioRendererSampleRate"},
|
||||
{1, nullptr, "GetAudioRendererSampleCount"},
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
|
||||
// Start the audio event
|
||||
CoreTiming::ScheduleEvent(audio_ticks, audio_event);
|
||||
voice_status_list.reserve(worker_params.voice_count);
|
||||
}
|
||||
~IAudioRenderer() {
|
||||
CoreTiming::UnscheduleEvent(audio_event, 0);
|
||||
@@ -57,30 +59,63 @@ private:
|
||||
}
|
||||
|
||||
void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_Audio, "{}", ctx.Description());
|
||||
AudioRendererResponseData response_data{};
|
||||
UpdateDataHeader config{};
|
||||
auto buf = ctx.ReadBuffer();
|
||||
std::memcpy(&config, buf.data(), sizeof(UpdateDataHeader));
|
||||
u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4);
|
||||
|
||||
response_data.section_0_size =
|
||||
static_cast<u32>(response_data.state_entries.size() * sizeof(AudioRendererStateEntry));
|
||||
response_data.section_1_size = static_cast<u32>(response_data.section_1.size());
|
||||
response_data.section_2_size = static_cast<u32>(response_data.section_2.size());
|
||||
response_data.section_3_size = static_cast<u32>(response_data.section_3.size());
|
||||
response_data.section_4_size = static_cast<u32>(response_data.section_4.size());
|
||||
response_data.section_5_size = static_cast<u32>(response_data.section_5.size());
|
||||
response_data.total_size = sizeof(AudioRendererResponseData);
|
||||
std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count);
|
||||
std::memcpy(mem_pool_info.data(),
|
||||
buf.data() + sizeof(UpdateDataHeader) + config.behavior_size,
|
||||
memory_pool_count * sizeof(MemoryPoolInfo));
|
||||
|
||||
for (unsigned i = 0; i < response_data.state_entries.size(); i++) {
|
||||
// 4 = Busy and 5 = Ready?
|
||||
response_data.state_entries[i].state = 5;
|
||||
std::vector<VoiceInfo> voice_info(worker_params.voice_count);
|
||||
std::memcpy(voice_info.data(),
|
||||
buf.data() + sizeof(UpdateDataHeader) + config.behavior_size +
|
||||
config.memory_pools_size + config.voice_resource_size,
|
||||
worker_params.voice_count * sizeof(VoiceInfo));
|
||||
|
||||
UpdateDataHeader response_data{worker_params};
|
||||
|
||||
ASSERT(ctx.GetWriteBufferSize() == response_data.total_size);
|
||||
|
||||
std::vector<u8> output(response_data.total_size);
|
||||
std::memcpy(output.data(), &response_data, sizeof(UpdateDataHeader));
|
||||
std::vector<MemoryPoolEntry> memory_pool(memory_pool_count);
|
||||
for (unsigned i = 0; i < memory_pool.size(); i++) {
|
||||
if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach)
|
||||
memory_pool[i].state = MemoryPoolStates::Attached;
|
||||
else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach)
|
||||
memory_pool[i].state = MemoryPoolStates::Detached;
|
||||
else
|
||||
memory_pool[i].state = mem_pool_info[i].pool_state;
|
||||
}
|
||||
std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(),
|
||||
response_data.memory_pools_size);
|
||||
|
||||
ctx.WriteBuffer(&response_data, response_data.total_size);
|
||||
for (unsigned i = 0; i < voice_info.size(); i++) {
|
||||
if (voice_info[i].is_new) {
|
||||
voice_status_list[i].played_sample_count = 0;
|
||||
voice_status_list[i].wave_buffer_consumed = 0;
|
||||
} else if (voice_info[i].play_state == (u8)PlayStates::Started) {
|
||||
for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) {
|
||||
voice_status_list[i].played_sample_count +=
|
||||
(voice_info[i].wave_buffer[buff_idx].end_sample_offset -
|
||||
voice_info[i].wave_buffer[buff_idx].start_sample_offset) /
|
||||
2;
|
||||
voice_status_list[i].wave_buffer_consumed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size,
|
||||
voice_status_list.data(), response_data.voices_size);
|
||||
|
||||
ctx.WriteBuffer(output);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void StartAudioRenderer(Kernel::HLERequestContext& ctx) {
|
||||
@@ -88,7 +123,7 @@ private:
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void StopAudioRenderer(Kernel::HLERequestContext& ctx) {
|
||||
@@ -96,7 +131,7 @@ private:
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void QuerySystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
@@ -106,51 +141,132 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(system_event);
|
||||
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
}
|
||||
|
||||
struct AudioRendererStateEntry {
|
||||
u32_le state;
|
||||
enum class MemoryPoolStates : u32 { // Should be LE
|
||||
Invalid = 0x0,
|
||||
Unknown = 0x1,
|
||||
RequestDetach = 0x2,
|
||||
Detached = 0x3,
|
||||
RequestAttach = 0x4,
|
||||
Attached = 0x5,
|
||||
Released = 0x6,
|
||||
};
|
||||
|
||||
enum class PlayStates : u8 {
|
||||
Started = 0,
|
||||
Stopped = 1,
|
||||
};
|
||||
|
||||
struct MemoryPoolEntry {
|
||||
MemoryPoolStates state;
|
||||
u32_le unknown_4;
|
||||
u32_le unknown_8;
|
||||
u32_le unknown_c;
|
||||
};
|
||||
static_assert(sizeof(AudioRendererStateEntry) == 0x10,
|
||||
"AudioRendererStateEntry has wrong size");
|
||||
static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
|
||||
|
||||
struct AudioRendererResponseData {
|
||||
u32_le unknown_0;
|
||||
u32_le section_5_size;
|
||||
u32_le section_0_size;
|
||||
u32_le section_1_size;
|
||||
u32_le unknown_10;
|
||||
u32_le section_2_size;
|
||||
u32_le unknown_18;
|
||||
u32_le section_3_size;
|
||||
u32_le section_4_size;
|
||||
u32_le unknown_24;
|
||||
u32_le unknown_28;
|
||||
u32_le unknown_2c;
|
||||
u32_le unknown_30;
|
||||
u32_le unknown_34;
|
||||
u32_le unknown_38;
|
||||
u32_le total_size;
|
||||
|
||||
std::array<AudioRendererStateEntry, 0x18e> state_entries;
|
||||
|
||||
std::array<u8, 0x600> section_1;
|
||||
std::array<u8, 0xe0> section_2;
|
||||
std::array<u8, 0x20> section_3;
|
||||
std::array<u8, 0x10> section_4;
|
||||
std::array<u8, 0xb0> section_5;
|
||||
struct MemoryPoolInfo {
|
||||
u64_le pool_address;
|
||||
u64_le pool_size;
|
||||
MemoryPoolStates pool_state;
|
||||
INSERT_PADDING_WORDS(3); // Unknown
|
||||
};
|
||||
static_assert(sizeof(AudioRendererResponseData) == 0x20e0,
|
||||
"AudioRendererResponseData has wrong size");
|
||||
static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
|
||||
|
||||
struct UpdateDataHeader {
|
||||
UpdateDataHeader() {}
|
||||
|
||||
UpdateDataHeader(const AudioRendererParameter& config) {
|
||||
revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
|
||||
behavior_size = 0xb0;
|
||||
memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
|
||||
voices_size = config.voice_count * 0x10;
|
||||
effects_size = config.effect_count * 0x10;
|
||||
sinks_size = config.sink_count * 0x20;
|
||||
performance_manager_size = 0x10;
|
||||
total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size +
|
||||
voices_size + effects_size + sinks_size + performance_manager_size;
|
||||
}
|
||||
|
||||
u32_le revision;
|
||||
u32_le behavior_size;
|
||||
u32_le memory_pools_size;
|
||||
u32_le voices_size;
|
||||
u32_le voice_resource_size;
|
||||
u32_le effects_size;
|
||||
u32_le mixes_size;
|
||||
u32_le sinks_size;
|
||||
u32_le performance_manager_size;
|
||||
INSERT_PADDING_WORDS(6);
|
||||
u32_le total_size;
|
||||
};
|
||||
static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
|
||||
|
||||
struct BiquadFilter {
|
||||
u8 enable;
|
||||
INSERT_PADDING_BYTES(1);
|
||||
s16_le numerator[3];
|
||||
s16_le denominator[2];
|
||||
};
|
||||
static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
|
||||
|
||||
struct WaveBuffer {
|
||||
u64_le buffer_addr;
|
||||
u64_le buffer_sz;
|
||||
s32_le start_sample_offset;
|
||||
s32_le end_sample_offset;
|
||||
u8 loop;
|
||||
u8 end_of_stream;
|
||||
u8 sent_to_server;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
u64 context_addr;
|
||||
u64 context_sz;
|
||||
INSERT_PADDING_BYTES(8);
|
||||
};
|
||||
static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
|
||||
|
||||
struct VoiceInfo {
|
||||
u32_le id;
|
||||
u32_le node_id;
|
||||
u8 is_new;
|
||||
u8 is_in_use;
|
||||
u8 play_state;
|
||||
u8 sample_format;
|
||||
u32_le sample_rate;
|
||||
u32_le priority;
|
||||
u32_le sorting_order;
|
||||
u32_le channel_count;
|
||||
float_le pitch;
|
||||
float_le volume;
|
||||
BiquadFilter biquad_filter[2];
|
||||
u32_le wave_buffer_count;
|
||||
u16_le wave_buffer_head;
|
||||
INSERT_PADDING_BYTES(6);
|
||||
u64_le additional_params_addr;
|
||||
u64_le additional_params_sz;
|
||||
u32_le mix_id;
|
||||
u32_le splitter_info_id;
|
||||
WaveBuffer wave_buffer[4];
|
||||
u32_le voice_channel_resource_ids[6];
|
||||
INSERT_PADDING_BYTES(24);
|
||||
};
|
||||
static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
|
||||
|
||||
struct VoiceOutStatus {
|
||||
u64_le played_sample_count;
|
||||
u32_le wave_buffer_consumed;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
};
|
||||
static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
|
||||
|
||||
/// This is used to trigger the audio event callback.
|
||||
CoreTiming::EventType* audio_event;
|
||||
|
||||
Kernel::SharedPtr<Kernel::Event> system_event;
|
||||
AudioRendererParameter worker_params;
|
||||
std::vector<VoiceOutStatus> voice_status_list;
|
||||
};
|
||||
|
||||
class IAudioDevice final : public ServiceFramework<IAudioDevice> {
|
||||
@@ -179,7 +295,7 @@ public:
|
||||
|
||||
private:
|
||||
void ListAudioDeviceName(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
const std::string audio_interface = "AudioInterface";
|
||||
@@ -191,7 +307,7 @@ private:
|
||||
}
|
||||
|
||||
void SetAudioDeviceOutputVolume(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
f32 volume = static_cast<f32>(rp.Pop<u32>());
|
||||
@@ -204,7 +320,7 @@ private:
|
||||
}
|
||||
|
||||
void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
const std::string audio_interface = "AudioDevice";
|
||||
@@ -216,7 +332,7 @@ private:
|
||||
}
|
||||
|
||||
void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
buffer_event->Signal();
|
||||
|
||||
@@ -226,7 +342,7 @@ private:
|
||||
}
|
||||
|
||||
void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(1);
|
||||
@@ -248,31 +364,33 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") {
|
||||
}
|
||||
|
||||
void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
auto params = rp.PopRaw<AudioRendererParameter>();
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<Audio::IAudioRenderer>();
|
||||
rb.PushIpcInterface<Audio::IAudioRenderer>(std::move(params));
|
||||
|
||||
NGLOG_DEBUG(Service_Audio, "called");
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
}
|
||||
|
||||
void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
auto params = rp.PopRaw<WorkerBufferParameters>();
|
||||
auto params = rp.PopRaw<AudioRendererParameter>();
|
||||
|
||||
u64 buffer_sz = Common::AlignUp(4 * params.unknown8, 0x40);
|
||||
buffer_sz += params.unknownC * 1024;
|
||||
buffer_sz += 0x940 * (params.unknownC + 1);
|
||||
u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40);
|
||||
buffer_sz += params.unknown_c * 1024;
|
||||
buffer_sz += 0x940 * (params.unknown_c + 1);
|
||||
buffer_sz += 0x3F0 * params.voice_count;
|
||||
buffer_sz += Common::AlignUp(8 * (params.unknownC + 1), 0x10);
|
||||
buffer_sz += Common::AlignUp(8 * (params.unknown_c + 1), 0x10);
|
||||
buffer_sz += Common::AlignUp(8 * params.voice_count, 0x10);
|
||||
buffer_sz +=
|
||||
Common::AlignUp((0x3C0 * (params.sink_count + params.unknownC) + 4 * params.sample_count) *
|
||||
(params.unknown8 + 6),
|
||||
Common::AlignUp((0x3C0 * (params.sink_count + params.unknown_c) + 4 * params.sample_count) *
|
||||
(params.unknown_8 + 6),
|
||||
0x40);
|
||||
|
||||
if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) {
|
||||
u32 count = params.unknownC + 1;
|
||||
if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) {
|
||||
u32 count = params.unknown_c + 1;
|
||||
u64 node_count = Common::AlignUp(count, 0x40);
|
||||
u64 node_state_buffer_sz =
|
||||
4 * (node_count * node_count) + 0xC * node_count + 2 * (node_count / 8);
|
||||
@@ -287,20 +405,20 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
buffer_sz += 0x20 * (params.effect_count + 4 * params.voice_count) + 0x50;
|
||||
if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) {
|
||||
buffer_sz += 0xE0 * params.unknown2c;
|
||||
if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) {
|
||||
buffer_sz += 0xE0 * params.unknown_2c;
|
||||
buffer_sz += 0x20 * params.splitter_count;
|
||||
buffer_sz += Common::AlignUp(4 * params.unknown2c, 0x10);
|
||||
buffer_sz += Common::AlignUp(4 * params.unknown_2c, 0x10);
|
||||
}
|
||||
buffer_sz = Common::AlignUp(buffer_sz, 0x40) + 0x170 * params.sink_count;
|
||||
u64 output_sz = buffer_sz + 0x280 * params.sink_count + 0x4B0 * params.effect_count +
|
||||
((params.voice_count * 256) | 0x40);
|
||||
|
||||
if (params.unknown1c >= 1) {
|
||||
if (params.unknown_1c >= 1) {
|
||||
output_sz = Common::AlignUp(((16 * params.sink_count + 16 * params.effect_count +
|
||||
16 * params.voice_count + 16) +
|
||||
0x658) *
|
||||
(params.unknown1c + 1) +
|
||||
(params.unknown_1c + 1) +
|
||||
0xc0,
|
||||
0x40) +
|
||||
output_sz;
|
||||
@@ -312,7 +430,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(output_sz);
|
||||
|
||||
NGLOG_DEBUG(Service_Audio, "called, buffer_size=0x{:X}", output_sz);
|
||||
LOG_DEBUG(Service_Audio, "called, buffer_size=0x{:X}", output_sz);
|
||||
}
|
||||
|
||||
void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) {
|
||||
@@ -321,14 +439,14 @@ void AudRenU::GetAudioDevice(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<Audio::IAudioDevice>();
|
||||
|
||||
NGLOG_DEBUG(Service_Audio, "called");
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
}
|
||||
|
||||
bool AudRenU::IsFeatureSupported(AudioFeatures feature, u32_le revision) const {
|
||||
u32_be version_num = (revision - Common::MakeMagic('R', 'E', 'V', '0')); // Byte swap
|
||||
switch (feature) {
|
||||
case AudioFeatures::Splitter:
|
||||
return version_num >= 2;
|
||||
return version_num >= 2u;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,24 @@ class HLERequestContext;
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
struct AudioRendererParameter {
|
||||
u32_le sample_rate;
|
||||
u32_le sample_count;
|
||||
u32_le unknown_8;
|
||||
u32_le unknown_c;
|
||||
u32_le voice_count;
|
||||
u32_le sink_count;
|
||||
u32_le effect_count;
|
||||
u32_le unknown_1c;
|
||||
u8 unknown_20;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
u32_le splitter_count;
|
||||
u32_le unknown_2c;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
u32_le revision;
|
||||
};
|
||||
static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
|
||||
|
||||
class AudRenU final : public ServiceFramework<AudRenU> {
|
||||
public:
|
||||
explicit AudRenU();
|
||||
@@ -22,25 +40,6 @@ private:
|
||||
void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);
|
||||
void GetAudioDevice(Kernel::HLERequestContext& ctx);
|
||||
|
||||
struct WorkerBufferParameters {
|
||||
u32_le sample_rate;
|
||||
u32_le sample_count;
|
||||
u32_le unknown8;
|
||||
u32_le unknownC;
|
||||
u32_le voice_count;
|
||||
u32_le sink_count;
|
||||
u32_le effect_count;
|
||||
u32_le unknown1c;
|
||||
u8 unknown20;
|
||||
u8 padding1[3];
|
||||
u32_le splitter_count;
|
||||
u32_le unknown2c;
|
||||
u8 padding2[4];
|
||||
u32_le magic;
|
||||
};
|
||||
static_assert(sizeof(WorkerBufferParameters) == 52,
|
||||
"WorkerBufferParameters is an invalid size");
|
||||
|
||||
enum class AudioFeatures : u32 {
|
||||
Splitter,
|
||||
};
|
||||
|
||||
29
src/core/hle/service/audio/hwopus.cpp
Normal file
29
src/core/hle/service/audio/hwopus.cpp
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.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/audio/hwopus.h"
|
||||
|
||||
namespace Service::Audio {
|
||||
|
||||
void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0x4000);
|
||||
}
|
||||
|
||||
HwOpus::HwOpus() : ServiceFramework("hwopus") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Initialize"},
|
||||
{1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"},
|
||||
{2, nullptr, "InitializeMultiStream"},
|
||||
{3, nullptr, "GetWorkBufferSizeMultiStream"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Service::Audio
|
||||
20
src/core/hle/service/audio/hwopus.h
Normal file
20
src/core/hle/service/audio/hwopus.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// 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::Audio {
|
||||
|
||||
class HwOpus final : public ServiceFramework<HwOpus> {
|
||||
public:
|
||||
explicit HwOpus();
|
||||
~HwOpus() = default;
|
||||
|
||||
private:
|
||||
void GetWorkBufferSize(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Service::Audio
|
||||
@@ -36,7 +36,7 @@ void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IBcatService>();
|
||||
NGLOG_DEBUG(Service_BCAT, "called");
|
||||
LOG_DEBUG(Service_BCAT, "called");
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
|
||||
@@ -16,13 +16,13 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
void Module::Interface::ThrowFatalWithPolicy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx);
|
||||
u32 error_code = rp.Pop<u32>();
|
||||
NGLOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x{:X}", error_code);
|
||||
LOG_WARNING(Service_Fatal, "(STUBBED) called, error_code=0x{:X}", error_code);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_Fatal, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Fatal, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -25,14 +25,14 @@ ResultCode RegisterFileSystem(std::unique_ptr<FileSys::FileSystemFactory>&& fact
|
||||
ASSERT_MSG(inserted, "Tried to register more than one system with same id code");
|
||||
|
||||
auto& filesystem = result.first->second;
|
||||
NGLOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}",
|
||||
filesystem->GetName(), static_cast<u32>(type));
|
||||
LOG_DEBUG(Service_FS, "Registered file system {} with id code 0x{:08X}", filesystem->GetName(),
|
||||
static_cast<u32>(type));
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
|
||||
FileSys::Path& path) {
|
||||
NGLOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type));
|
||||
LOG_TRACE(Service_FS, "Opening FileSystem with type={}", static_cast<u32>(type));
|
||||
|
||||
auto itr = filesystem_map.find(type);
|
||||
if (itr == filesystem_map.end()) {
|
||||
@@ -44,7 +44,7 @@ ResultVal<std::unique_ptr<FileSys::FileSystemBackend>> OpenFileSystem(Type type,
|
||||
}
|
||||
|
||||
ResultCode FormatFileSystem(Type type) {
|
||||
NGLOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type));
|
||||
LOG_TRACE(Service_FS, "Formatting FileSystem with type={}", static_cast<u32>(type));
|
||||
|
||||
auto itr = filesystem_map.find(type);
|
||||
if (itr == filesystem_map.end()) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <cinttypes>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/directory.h"
|
||||
#include "core/file_sys/filesystem.h"
|
||||
@@ -35,7 +36,7 @@ private:
|
||||
const s64 offset = rp.Pop<s64>();
|
||||
const s64 length = rp.Pop<s64>();
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
|
||||
LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
|
||||
|
||||
// Error checking
|
||||
if (length < 0) {
|
||||
@@ -87,7 +88,7 @@ private:
|
||||
const s64 offset = rp.Pop<s64>();
|
||||
const s64 length = rp.Pop<s64>();
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
|
||||
LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
|
||||
|
||||
// Error checking
|
||||
if (length < 0) {
|
||||
@@ -124,7 +125,7 @@ private:
|
||||
const s64 offset = rp.Pop<s64>();
|
||||
const s64 length = rp.Pop<s64>();
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
|
||||
LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length);
|
||||
|
||||
// Error checking
|
||||
if (length < 0) {
|
||||
@@ -152,7 +153,7 @@ private:
|
||||
}
|
||||
|
||||
void Flush(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_FS, "called");
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
backend->Flush();
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
@@ -163,7 +164,7 @@ private:
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 size = rp.Pop<u64>();
|
||||
backend->SetSize(size);
|
||||
NGLOG_DEBUG(Service_FS, "called, size={}", size);
|
||||
LOG_DEBUG(Service_FS, "called, size={}", size);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -171,7 +172,7 @@ private:
|
||||
|
||||
void GetSize(Kernel::HLERequestContext& ctx) {
|
||||
const u64 size = backend->GetSize();
|
||||
NGLOG_DEBUG(Service_FS, "called, size={}", size);
|
||||
LOG_DEBUG(Service_FS, "called, size={}", size);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -197,7 +198,7 @@ private:
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 unk = rp.Pop<u64>();
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called, unk=0x{:X}", unk);
|
||||
LOG_DEBUG(Service_FS, "called, unk=0x{:X}", unk);
|
||||
|
||||
// Calculate how many entries we can fit in the output buffer
|
||||
u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
|
||||
@@ -219,7 +220,7 @@ private:
|
||||
}
|
||||
|
||||
void GetEntryCount(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_FS, "called");
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
u64 count = backend->GetEntryCount();
|
||||
|
||||
@@ -258,14 +259,12 @@ public:
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto file_buffer = ctx.ReadBuffer();
|
||||
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
|
||||
|
||||
std::string name(file_buffer.begin(), end);
|
||||
std::string name = Common::StringFromBuffer(file_buffer);
|
||||
|
||||
u64 mode = rp.Pop<u64>();
|
||||
u32 size = rp.Pop<u32>();
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size);
|
||||
LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(backend->CreateFile(name, size));
|
||||
@@ -275,11 +274,9 @@ public:
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto file_buffer = ctx.ReadBuffer();
|
||||
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
|
||||
std::string name = Common::StringFromBuffer(file_buffer);
|
||||
|
||||
std::string name(file_buffer.begin(), end);
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called file {}", name);
|
||||
LOG_DEBUG(Service_FS, "called file {}", name);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(backend->DeleteFile(name));
|
||||
@@ -289,11 +286,9 @@ public:
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto file_buffer = ctx.ReadBuffer();
|
||||
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
|
||||
std::string name = Common::StringFromBuffer(file_buffer);
|
||||
|
||||
std::string name(file_buffer.begin(), end);
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called directory {}", name);
|
||||
LOG_DEBUG(Service_FS, "called directory {}", name);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(backend->CreateDirectory(name));
|
||||
@@ -305,15 +300,13 @@ public:
|
||||
std::vector<u8> buffer;
|
||||
buffer.resize(ctx.BufferDescriptorX()[0].Size());
|
||||
Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size());
|
||||
auto end = std::find(buffer.begin(), buffer.end(), '\0');
|
||||
std::string src_name(buffer.begin(), end);
|
||||
std::string src_name = Common::StringFromBuffer(buffer);
|
||||
|
||||
buffer.resize(ctx.BufferDescriptorX()[1].Size());
|
||||
Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size());
|
||||
end = std::find(buffer.begin(), buffer.end(), '\0');
|
||||
std::string dst_name(buffer.begin(), end);
|
||||
std::string dst_name = Common::StringFromBuffer(buffer);
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name);
|
||||
LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(backend->RenameFile(src_name, dst_name));
|
||||
@@ -323,13 +316,11 @@ public:
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto file_buffer = ctx.ReadBuffer();
|
||||
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
|
||||
|
||||
std::string name(file_buffer.begin(), end);
|
||||
std::string name = Common::StringFromBuffer(file_buffer);
|
||||
|
||||
auto mode = static_cast<FileSys::Mode>(rp.Pop<u32>());
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode));
|
||||
LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode));
|
||||
|
||||
auto result = backend->OpenFile(name, mode);
|
||||
if (result.Failed()) {
|
||||
@@ -349,14 +340,12 @@ public:
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto file_buffer = ctx.ReadBuffer();
|
||||
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
|
||||
|
||||
std::string name(file_buffer.begin(), end);
|
||||
std::string name = Common::StringFromBuffer(file_buffer);
|
||||
|
||||
// TODO(Subv): Implement this filter.
|
||||
u32 filter_flags = rp.Pop<u32>();
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags);
|
||||
LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags);
|
||||
|
||||
auto result = backend->OpenDirectory(name);
|
||||
if (result.Failed()) {
|
||||
@@ -376,11 +365,9 @@ public:
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto file_buffer = ctx.ReadBuffer();
|
||||
auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0');
|
||||
std::string name = Common::StringFromBuffer(file_buffer);
|
||||
|
||||
std::string name(file_buffer.begin(), end);
|
||||
|
||||
NGLOG_DEBUG(Service_FS, "called file {}", name);
|
||||
LOG_DEBUG(Service_FS, "called file {}", name);
|
||||
|
||||
auto result = backend->GetEntryType(name);
|
||||
if (result.Failed()) {
|
||||
@@ -395,7 +382,7 @@ public:
|
||||
}
|
||||
|
||||
void Commit(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -511,14 +498,14 @@ void FSP_SRV::TryLoadRomFS() {
|
||||
}
|
||||
|
||||
void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_FS, "called");
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
FileSys::Path unused;
|
||||
auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap();
|
||||
@@ -535,14 +522,14 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
|
||||
auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
|
||||
u128 uid = rp.PopRaw<u128>();
|
||||
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called uid = {:016X}{:016X}", uid[1], uid[0]);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
FileSys::Path unused;
|
||||
auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap();
|
||||
@@ -553,7 +540,7 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -561,12 +548,12 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_FS, "called");
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
TryLoadRomFS();
|
||||
if (!romfs) {
|
||||
// TODO (bunnei): Find the right error code to use here
|
||||
NGLOG_CRITICAL(Service_FS, "no file system interface available!");
|
||||
LOG_CRITICAL(Service_FS, "no file system interface available!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultCode(-1));
|
||||
return;
|
||||
@@ -575,7 +562,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||
// Attempt to open a StorageBackend interface to the RomFS
|
||||
auto storage = romfs->OpenFile({}, {});
|
||||
if (storage.Failed()) {
|
||||
NGLOG_CRITICAL(Service_FS, "no storage interface available!");
|
||||
LOG_CRITICAL(Service_FS, "no storage interface available!");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(storage.Code());
|
||||
return;
|
||||
@@ -587,7 +574,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess");
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called, using OpenDataStorageByCurrentProcess");
|
||||
OpenDataStorageByCurrentProcess(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Service::Friend {
|
||||
void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_Friend, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Friend, "(STUBBED) called");
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(shared_mem);
|
||||
NGLOG_DEBUG(Service_HID, "called");
|
||||
LOG_DEBUG(Service_HID, "called");
|
||||
}
|
||||
|
||||
void LoadInputDevices() {
|
||||
@@ -84,6 +84,10 @@ private:
|
||||
|
||||
for (size_t controller = 0; controller < mem.controllers.size(); controller++) {
|
||||
for (int index = 0; index < HID_NUM_LAYOUTS; index++) {
|
||||
// TODO(DarkLordZach): Is this layout/controller config actually invalid?
|
||||
if (controller == Controller_Handheld && index == Layout_Single)
|
||||
continue;
|
||||
|
||||
ControllerLayout& layout = mem.controllers[controller].layouts[index];
|
||||
layout.header.num_entries = HID_NUM_ENTRIES;
|
||||
layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
|
||||
@@ -94,7 +98,6 @@ private:
|
||||
layout.header.latest_entry = (layout.header.latest_entry + 1) % HID_NUM_ENTRIES;
|
||||
|
||||
ControllerInputEntry& entry = layout.entries[layout.header.latest_entry];
|
||||
entry.connection_state = ConnectionState_Connected | ConnectionState_Wired;
|
||||
entry.timestamp++;
|
||||
// TODO(shinyquagsire23): Is this always identical to timestamp?
|
||||
entry.timestamp_2++;
|
||||
@@ -103,6 +106,8 @@ private:
|
||||
if (controller != Controller_Handheld)
|
||||
continue;
|
||||
|
||||
entry.connection_state = ConnectionState_Connected | ConnectionState_Wired;
|
||||
|
||||
// TODO(shinyquagsire23): Set up some LUTs for each layout mapping in the future?
|
||||
// For now everything is just the default handheld layout, but split Joy-Con will
|
||||
// rotate the face buttons and directions for certain layouts.
|
||||
@@ -262,7 +267,7 @@ private:
|
||||
void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -394,144 +399,144 @@ private:
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAppletResource>(applet_resource);
|
||||
NGLOG_DEBUG(Service_HID, "called");
|
||||
LOG_DEBUG(Service_HID, "called");
|
||||
}
|
||||
|
||||
void ActivateDebugPad(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ActivateMouse(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ActivateKeyboard(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void ActivateNpad(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(event);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(joy_hold_type);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SendVibrationValue(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IActiveVibrationDeviceList>();
|
||||
NGLOG_DEBUG(Service_HID, "called");
|
||||
LOG_DEBUG(Service_HID, "called");
|
||||
}
|
||||
|
||||
void SendVibrationValues(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Service::HID {
|
||||
// Begin enums and output structs
|
||||
|
||||
constexpr u32 HID_NUM_ENTRIES = 17;
|
||||
constexpr u32 HID_NUM_LAYOUTS = 2;
|
||||
constexpr u32 HID_NUM_LAYOUTS = 7;
|
||||
constexpr s32 HID_JOYSTICK_MAX = 0x8000;
|
||||
constexpr s32 HID_JOYSTICK_MIN = -0x8000;
|
||||
|
||||
|
||||
@@ -141,19 +141,19 @@ private:
|
||||
if (header.IsTailLog()) {
|
||||
switch (header.severity) {
|
||||
case MessageHeader::Severity::Trace:
|
||||
NGLOG_TRACE(Debug_Emulated, "{}", log_stream.str());
|
||||
LOG_TRACE(Debug_Emulated, "{}", log_stream.str());
|
||||
break;
|
||||
case MessageHeader::Severity::Info:
|
||||
NGLOG_INFO(Debug_Emulated, "{}", log_stream.str());
|
||||
LOG_INFO(Debug_Emulated, "{}", log_stream.str());
|
||||
break;
|
||||
case MessageHeader::Severity::Warning:
|
||||
NGLOG_WARNING(Debug_Emulated, "{}", log_stream.str());
|
||||
LOG_WARNING(Debug_Emulated, "{}", log_stream.str());
|
||||
break;
|
||||
case MessageHeader::Severity::Error:
|
||||
NGLOG_ERROR(Debug_Emulated, "{}", log_stream.str());
|
||||
LOG_ERROR(Debug_Emulated, "{}", log_stream.str());
|
||||
break;
|
||||
case MessageHeader::Severity::Critical:
|
||||
NGLOG_CRITICAL(Debug_Emulated, "{}", log_stream.str());
|
||||
LOG_CRITICAL(Debug_Emulated, "{}", log_stream.str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,7 @@ void LM::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<Logger>();
|
||||
|
||||
NGLOG_DEBUG(Service_LM, "called");
|
||||
LOG_DEBUG(Service_LM, "called");
|
||||
}
|
||||
|
||||
LM::LM() : ServiceFramework("lm") {
|
||||
|
||||
50
src/core/hle/service/mm/mm_u.cpp
Normal file
50
src/core/hle/service/mm/mm_u.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// 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_session.h"
|
||||
#include "core/hle/service/mm/mm_u.h"
|
||||
|
||||
namespace Service::MM {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<MM_U>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
void MM_U::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_MM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void MM_U::SetAndWait(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
min = rp.Pop<u32>();
|
||||
max = rp.Pop<u32>();
|
||||
current = min;
|
||||
|
||||
LOG_WARNING(Service_MM, "(STUBBED) called, min=0x{:X}, max=0x{:X}", min, max);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void MM_U::Get(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_MM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(current);
|
||||
}
|
||||
|
||||
MM_U::MM_U() : ServiceFramework("mm:u") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "InitializeOld"}, {1, nullptr, "FinalizeOld"},
|
||||
{2, nullptr, "SetAndWaitOld"}, {3, nullptr, "GetOld"},
|
||||
{4, &MM_U::Initialize, "Initialize"}, {5, nullptr, "Finalize"},
|
||||
{6, &MM_U::SetAndWait, "SetAndWait"}, {7, &MM_U::Get, "Get"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Service::MM
|
||||
29
src/core/hle/service/mm/mm_u.h
Normal file
29
src/core/hle/service/mm/mm_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/service/service.h"
|
||||
|
||||
namespace Service::MM {
|
||||
|
||||
class MM_U final : public ServiceFramework<MM_U> {
|
||||
public:
|
||||
MM_U();
|
||||
~MM_U() = default;
|
||||
|
||||
private:
|
||||
void Initialize(Kernel::HLERequestContext& ctx);
|
||||
void SetAndWait(Kernel::HLERequestContext& ctx);
|
||||
void Get(Kernel::HLERequestContext& ctx);
|
||||
|
||||
u32 min{0};
|
||||
u32 max{0};
|
||||
u32 current{0};
|
||||
};
|
||||
|
||||
/// Registers all MM services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Service::MM
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/nfp/nfp.h"
|
||||
#include "core/hle/service/nfp/nfp_user.h"
|
||||
|
||||
@@ -18,7 +20,7 @@ public:
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IUser::Initialize, "Initialize"},
|
||||
{1, nullptr, "Finalize"},
|
||||
{2, nullptr, "ListDevices"},
|
||||
{2, &IUser::ListDevices, "ListDevices"},
|
||||
{3, nullptr, "StartDetection"},
|
||||
{4, nullptr, "StopDetection"},
|
||||
{5, nullptr, "Mount"},
|
||||
@@ -33,28 +35,120 @@ public:
|
||||
{14, nullptr, "GetRegisterInfo"},
|
||||
{15, nullptr, "GetCommonInfo"},
|
||||
{16, nullptr, "GetModelInfo"},
|
||||
{17, nullptr, "AttachActivateEvent"},
|
||||
{18, nullptr, "AttachDeactivateEvent"},
|
||||
{19, nullptr, "GetState"},
|
||||
{20, nullptr, "GetDeviceState"},
|
||||
{21, nullptr, "GetNpadId"},
|
||||
{17, &IUser::AttachActivateEvent, "AttachActivateEvent"},
|
||||
{18, &IUser::AttachDeactivateEvent, "AttachDeactivateEvent"},
|
||||
{19, &IUser::GetState, "GetState"},
|
||||
{20, &IUser::GetDeviceState, "GetDeviceState"},
|
||||
{21, &IUser::GetNpadId, "GetNpadId"},
|
||||
{22, nullptr, "GetApplicationArea2"},
|
||||
{23, nullptr, "AttachAvailabilityChangeEvent"},
|
||||
{23, &IUser::AttachAvailabilityChangeEvent, "AttachAvailabilityChangeEvent"},
|
||||
{24, nullptr, "RecreateApplicationArea"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
activate_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "IUser:ActivateEvent");
|
||||
deactivate_event =
|
||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "IUser:DeactivateEvent");
|
||||
availability_change_event =
|
||||
Kernel::Event::Create(Kernel::ResetType::OneShot, "IUser:AvailabilityChangeEvent");
|
||||
}
|
||||
|
||||
private:
|
||||
enum class State : u32 {
|
||||
NonInitialized = 0,
|
||||
Initialized = 1,
|
||||
};
|
||||
|
||||
enum class DeviceState : u32 {
|
||||
Initialized = 0,
|
||||
};
|
||||
|
||||
void Initialize(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NFP, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called");
|
||||
|
||||
state = State::Initialized;
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void ListDevices(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u32 array_size = rp.Pop<u32>();
|
||||
|
||||
ctx.WriteBuffer(&device_handle, sizeof(device_handle));
|
||||
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called, array_size={}", array_size);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void AttachActivateEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 dev_handle = rp.Pop<u64>();
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(activate_event);
|
||||
}
|
||||
|
||||
void AttachDeactivateEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 dev_handle = rp.Pop<u64>();
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(deactivate_event);
|
||||
}
|
||||
|
||||
void GetState(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(static_cast<u32>(state));
|
||||
}
|
||||
|
||||
void GetDeviceState(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(static_cast<u32>(device_state));
|
||||
}
|
||||
|
||||
void GetNpadId(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 dev_handle = rp.Pop<u64>();
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(npad_id);
|
||||
}
|
||||
|
||||
void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 dev_handle = rp.Pop<u64>();
|
||||
LOG_WARNING(Service_NFP, "(STUBBED) called, dev_handle=0x{:X}", dev_handle);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(availability_change_event);
|
||||
}
|
||||
|
||||
const u64 device_handle{0xDEAD};
|
||||
const HID::ControllerID npad_id{HID::Controller_Player1};
|
||||
State state{State::NonInitialized};
|
||||
DeviceState device_state{DeviceState::Initialized};
|
||||
Kernel::SharedPtr<Kernel::Event> activate_event;
|
||||
Kernel::SharedPtr<Kernel::Event> deactivate_event;
|
||||
Kernel::SharedPtr<Kernel::Event> availability_change_event;
|
||||
};
|
||||
|
||||
void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_NFP, "called");
|
||||
LOG_DEBUG(Service_NFP, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IUser>();
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
{8, nullptr, "SetPriority"},
|
||||
{9, nullptr, "SetNetworkProfileId"},
|
||||
{10, nullptr, "SetRejectable"},
|
||||
{11, nullptr, "SetConnectionConfirmationOption"},
|
||||
{11, &IRequest::SetConnectionConfirmationOption, "SetConnectionConfirmationOption"},
|
||||
{12, nullptr, "SetPersistent"},
|
||||
{13, nullptr, "SetInstant"},
|
||||
{14, nullptr, "SetSustainable"},
|
||||
@@ -62,24 +62,33 @@ public:
|
||||
|
||||
private:
|
||||
void GetRequestState(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void GetResult(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(event1, event2);
|
||||
}
|
||||
|
||||
void Cancel(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void SetConnectionConfirmationOption(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -105,7 +114,7 @@ public:
|
||||
|
||||
private:
|
||||
void GetClientId(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(0);
|
||||
@@ -116,7 +125,7 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IScanRequest>();
|
||||
|
||||
NGLOG_DEBUG(Service_NIFM, "called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
}
|
||||
void CreateRequest(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
@@ -124,10 +133,10 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IRequest>();
|
||||
|
||||
NGLOG_DEBUG(Service_NIFM, "called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
}
|
||||
void RemoveNetworkProfile(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -137,7 +146,7 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<INetworkProfile>();
|
||||
|
||||
NGLOG_DEBUG(Service_NIFM, "called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -187,14 +196,14 @@ void Module::Interface::CreateGeneralServiceOld(Kernel::HLERequestContext& ctx)
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IGeneralService>();
|
||||
NGLOG_DEBUG(Service_NIFM, "called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
}
|
||||
|
||||
void Module::Interface::CreateGeneralService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IGeneralService>();
|
||||
NGLOG_DEBUG(Service_NIFM, "called");
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
|
||||
@@ -52,7 +52,7 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
|
||||
ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE);
|
||||
file.ReadBytes(shared_font->data(), shared_font->size());
|
||||
} else {
|
||||
NGLOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath);
|
||||
LOG_WARNING(Service_NS, "Unable to load shared font: {}", filepath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u32 shared_font_type{rp.Pop<u32>()};
|
||||
|
||||
NGLOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type);
|
||||
LOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type);
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -69,7 +69,7 @@ void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u32 font_id{rp.Pop<u32>()};
|
||||
|
||||
NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id);
|
||||
LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(static_cast<u32>(LoadState::Done));
|
||||
@@ -79,7 +79,7 @@ void PL_U::GetSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u32 font_id{rp.Pop<u32>()};
|
||||
|
||||
NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id);
|
||||
LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size);
|
||||
@@ -89,7 +89,7 @@ void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u32 font_id{rp.Pop<u32>()};
|
||||
|
||||
NGLOG_DEBUG(Service_NS, "called, font_id={}", font_id);
|
||||
LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset);
|
||||
@@ -110,7 +110,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
|
||||
Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
|
||||
"PL_U:shared_font_mem");
|
||||
|
||||
NGLOG_DEBUG(Service_NS, "called");
|
||||
LOG_DEBUG(Service_NS, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(shared_font_mem);
|
||||
@@ -119,7 +119,7 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
|
||||
void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
|
||||
NGLOG_DEBUG(Service_NS, "called, language_code=%lx", language_code);
|
||||
LOG_DEBUG(Service_NS, "called, language_code=%lx", language_code);
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
std::vector<u32> font_codes;
|
||||
std::vector<u32> font_offsets;
|
||||
|
||||
@@ -20,9 +20,9 @@ u32 nvdisp_disp0::ioctl(Ioctl command, const std::vector<u8>& input, std::vector
|
||||
void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height,
|
||||
u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform) {
|
||||
VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
|
||||
NGLOG_WARNING(Service,
|
||||
"Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",
|
||||
addr, offset, width, height, stride, format);
|
||||
LOG_WARNING(Service,
|
||||
"Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",
|
||||
addr, offset, width, height, stride, format);
|
||||
|
||||
using PixelFormat = Tegra::FramebufferConfig::PixelFormat;
|
||||
const Tegra::FramebufferConfig framebuffer{
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvmap.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocInitalizeExCommand:
|
||||
@@ -40,15 +42,15 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vecto
|
||||
u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlInitalizeEx params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlAllocSpace params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages,
|
||||
params.page_size, params.flags);
|
||||
LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages,
|
||||
params.page_size, params.flags);
|
||||
|
||||
auto& gpu = Core::System::GetInstance().GPU();
|
||||
const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)};
|
||||
@@ -65,7 +67,7 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>&
|
||||
u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
size_t num_entries = input.size() / sizeof(IoctlRemapEntry);
|
||||
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries);
|
||||
|
||||
std::vector<IoctlRemapEntry> entries(num_entries);
|
||||
std::memcpy(entries.data(), input.data(), input.size());
|
||||
@@ -73,8 +75,8 @@ u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output)
|
||||
auto& gpu = Core::System::GetInstance().GPU();
|
||||
|
||||
for (const auto& entry : entries) {
|
||||
NGLOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}",
|
||||
entry.offset, entry.nvmap_handle, entry.pages);
|
||||
LOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}",
|
||||
entry.offset, entry.nvmap_handle, entry.pages);
|
||||
Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10;
|
||||
|
||||
auto object = nvmap_dev->GetObject(entry.nvmap_handle);
|
||||
@@ -96,11 +98,11 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou
|
||||
IoctlMapBufferEx params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
|
||||
NGLOG_DEBUG(Service_NVDRV,
|
||||
"called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
|
||||
", offset={}",
|
||||
params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size,
|
||||
params.offset);
|
||||
LOG_DEBUG(Service_NVDRV,
|
||||
"called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
|
||||
", offset={}",
|
||||
params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size,
|
||||
params.offset);
|
||||
|
||||
if (!params.nvmap_handle) {
|
||||
return 0;
|
||||
@@ -146,7 +148,7 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
|
||||
IoctlUnmapBuffer params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
|
||||
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
|
||||
|
||||
auto& gpu = Core::System::GetInstance().GPU();
|
||||
|
||||
@@ -154,6 +156,9 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
|
||||
|
||||
ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping");
|
||||
|
||||
// Remove this memory region from the rasterizer cache.
|
||||
VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size);
|
||||
|
||||
params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size);
|
||||
|
||||
buffer_mappings.erase(itr->second.offset);
|
||||
@@ -165,7 +170,7 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou
|
||||
u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlBindChannel params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
|
||||
LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
|
||||
channel = params.fd;
|
||||
return 0;
|
||||
}
|
||||
@@ -173,8 +178,8 @@ u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& ou
|
||||
u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetVaRegions params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
|
||||
params.buf_size);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
|
||||
params.buf_size);
|
||||
|
||||
params.buf_size = 0x30;
|
||||
params.regions[0].offset = 0x04000000;
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocGetConfigCommand:
|
||||
@@ -29,8 +29,8 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<
|
||||
u32 nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IocGetConfigParams params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(),
|
||||
params.param_str.data());
|
||||
LOG_DEBUG(Service_NVDRV, "called, setting={}!{}", params.domain_str.data(),
|
||||
params.param_str.data());
|
||||
|
||||
if (!strcmp(params.domain_str.data(), "nv")) {
|
||||
if (!strcmp(params.param_str.data(), "NV_MEMORY_PROFILER")) {
|
||||
@@ -53,9 +53,9 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
|
||||
bool is_async) {
|
||||
IocCtrlEventWaitParams params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
NGLOG_WARNING(Service_NVDRV,
|
||||
"(STUBBED) called, syncpt_id={}, threshold={}, timeout={}, is_async={}",
|
||||
params.syncpt_id, params.threshold, params.timeout, is_async);
|
||||
LOG_WARNING(Service_NVDRV,
|
||||
"(STUBBED) called, syncpt_id={}, threshold={}, timeout={}, is_async={}",
|
||||
params.syncpt_id, params.threshold, params.timeout, is_async);
|
||||
|
||||
// TODO(Subv): Implement actual syncpt waiting.
|
||||
params.value = 0;
|
||||
@@ -64,7 +64,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
// TODO(bunnei): Implement this.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocGetCharacteristicsCommand:
|
||||
@@ -26,13 +26,17 @@ u32 nvhost_ctrl_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vec
|
||||
return ZCullGetInfo(input, output);
|
||||
case IoctlCommand::IocZbcSetTable:
|
||||
return ZBCSetTable(input, output);
|
||||
case IoctlCommand::IocZbcQueryTable:
|
||||
return ZBCQueryTable(input, output);
|
||||
case IoctlCommand::IocFlushL2:
|
||||
return FlushL2(input, output);
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented ioctl");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
IoctlCharacteristics params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
params.gc.arch = 0x120;
|
||||
@@ -79,8 +83,8 @@ u32 nvhost_ctrl_gpu::GetCharacteristics(const std::vector<u8>& input, std::vecto
|
||||
u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGpuGetTpcMasksArgs params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_INFO(Service_NVDRV, "called, mask=0x{:X}, mask_buf_addr=0x{:X}", params.mask_buf_size,
|
||||
params.mask_buf_addr);
|
||||
LOG_INFO(Service_NVDRV, "called, mask=0x{:X}, mask_buf_addr=0x{:X}", params.mask_buf_size,
|
||||
params.mask_buf_addr);
|
||||
// TODO(ogniK): Confirm value on hardware
|
||||
if (params.mask_buf_size)
|
||||
params.tpc_mask_size = 4 * 1; // 4 * num_gpc
|
||||
@@ -91,7 +95,7 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>&
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
IoctlActiveSlotMask params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
params.slot = 0x07;
|
||||
@@ -101,7 +105,7 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
IoctlZcullGetCtxSize params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
params.size = 0x1;
|
||||
@@ -110,7 +114,7 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
IoctlNvgpuGpuZcullGetInfoArgs params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
params.width_align_pixels = 0x20;
|
||||
@@ -128,7 +132,7 @@ u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>&
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
IoctlZbcSetTable params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
// TODO(ogniK): What does this even actually do?
|
||||
@@ -136,4 +140,22 @@ u32 nvhost_ctrl_gpu::ZBCSetTable(const std::vector<u8>& input, std::vector<u8>&
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
IoctlZbcQueryTable params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
// TODO : To implement properly
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_ctrl_gpu::FlushL2(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
IoctlFlushL2 params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
// TODO : To implement properly
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -26,6 +26,18 @@ private:
|
||||
IocZcullGetCtxSizeCommand = 0x80044701,
|
||||
IocZcullGetInfo = 0x80284702,
|
||||
IocZbcSetTable = 0x402C4703,
|
||||
IocZbcQueryTable = 0xC0344704,
|
||||
IocFlushL2 = 0x40084707,
|
||||
IocInvalICache = 0x4008470D,
|
||||
IocSetMmudebugMode = 0x4008470E,
|
||||
IocSetSmDebugMode = 0x4010470F,
|
||||
IocWaitForPause = 0xC0084710,
|
||||
IocGetTcpExceptionEnStatus = 0x80084711,
|
||||
IocNumVsms = 0x80084712,
|
||||
IocVsmsMapping = 0xC0044713,
|
||||
IocGetErrorChannelUserData = 0xC008471B,
|
||||
IocGetGpuTime = 0xC010471C,
|
||||
IocGetCpuTimeCorrelationInfo = 0xC108471D,
|
||||
};
|
||||
|
||||
struct IoctlGpuCharacteristics {
|
||||
@@ -127,12 +139,31 @@ private:
|
||||
};
|
||||
static_assert(sizeof(IoctlZbcSetTable) == 44, "IoctlZbcSetTable is incorrect size");
|
||||
|
||||
struct IoctlZbcQueryTable {
|
||||
u32_le color_ds[4];
|
||||
u32_le color_l2[4];
|
||||
u32_le depth;
|
||||
u32_le ref_cnt;
|
||||
u32_le format;
|
||||
u32_le type;
|
||||
u32_le index_size;
|
||||
};
|
||||
static_assert(sizeof(IoctlZbcQueryTable) == 52, "IoctlZbcQueryTable is incorrect size");
|
||||
|
||||
struct IoctlFlushL2 {
|
||||
u32_le flush; // l2_flush | l2_invalidate << 1 | fb_flush << 2
|
||||
u32_le reserved;
|
||||
};
|
||||
static_assert(sizeof(IoctlFlushL2) == 8, "IoctlFlushL2 is incorrect size");
|
||||
|
||||
u32 GetCharacteristics(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 ZBCSetTable(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
u32 FlushL2(const std::vector<u8>& input, std::vector<u8>& output);
|
||||
};
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocSetNVMAPfdCommand:
|
||||
@@ -51,13 +51,13 @@ u32 nvhost_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u
|
||||
u32 nvhost_gpu::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetNvmapFD params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
||||
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
||||
nvmap_fd = params.nvmap_fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
IoctlClientData params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
user_data = params.data;
|
||||
@@ -65,7 +65,7 @@ u32 nvhost_gpu::SetClientData(const std::vector<u8>& input, std::vector<u8>& out
|
||||
}
|
||||
|
||||
u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
IoctlClientData params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
params.data = user_data;
|
||||
@@ -75,8 +75,8 @@ u32 nvhost_gpu::GetClientData(const std::vector<u8>& input, std::vector<u8>& out
|
||||
|
||||
u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
std::memcpy(&zcull_params, input.data(), input.size());
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va,
|
||||
zcull_params.mode);
|
||||
LOG_DEBUG(Service_NVDRV, "called, gpu_va={:X}, mode={:X}", zcull_params.gpu_va,
|
||||
zcull_params.mode);
|
||||
std::memcpy(output.data(), &zcull_params, output.size());
|
||||
return 0;
|
||||
}
|
||||
@@ -84,26 +84,26 @@ u32 nvhost_gpu::ZCullBind(const std::vector<u8>& input, std::vector<u8>& output)
|
||||
u32 nvhost_gpu::SetErrorNotifier(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetErrorNotifier params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}",
|
||||
params.offset, params.size, params.mem);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, offset={:X}, size={:X}, mem={:X}", params.offset,
|
||||
params.size, params.mem);
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_gpu::SetChannelPriority(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
std::memcpy(&channel_priority, input.data(), input.size());
|
||||
NGLOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority);
|
||||
LOG_DEBUG(Service_NVDRV, "(STUBBED) called, priority={:X}", channel_priority);
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlAllocGpfifoEx2 params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_WARNING(Service_NVDRV,
|
||||
"(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
|
||||
"unk1={:X}, unk2={:X}, unk3={:X}",
|
||||
params.num_entries, params.flags, params.unk0, params.unk1, params.unk2,
|
||||
params.unk3);
|
||||
LOG_WARNING(Service_NVDRV,
|
||||
"(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
|
||||
"unk1={:X}, unk2={:X}, unk3={:X}",
|
||||
params.num_entries, params.flags, params.unk0, params.unk1, params.unk2,
|
||||
params.unk3);
|
||||
params.fence_out.id = 0;
|
||||
params.fence_out.value = 0;
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
@@ -113,20 +113,21 @@ u32 nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8>& ou
|
||||
u32 nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlAllocObjCtx params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num,
|
||||
params.flags);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, class_num={:X}, flags={:X}", params.class_num,
|
||||
params.flags);
|
||||
params.obj_id = 0x0;
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
if (input.size() < sizeof(IoctlSubmitGpfifo))
|
||||
if (input.size() < sizeof(IoctlSubmitGpfifo)) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
IoctlSubmitGpfifo params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo));
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
|
||||
params.gpfifo, params.num_entries, params.flags);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
|
||||
params.gpfifo, params.num_entries, params.flags);
|
||||
|
||||
auto entries = std::vector<IoctlGpfifoEntry>();
|
||||
entries.resize(params.num_entries);
|
||||
@@ -145,7 +146,7 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp
|
||||
u32 nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlGetWaitbase params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase));
|
||||
NGLOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
||||
LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
||||
params.value = 0; // Seems to be hard coded at 0
|
||||
std::memcpy(output.data(), ¶ms, output.size());
|
||||
return 0;
|
||||
@@ -154,7 +155,7 @@ u32 nvhost_gpu::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& outpu
|
||||
u32 nvhost_gpu::ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlChannelSetTimeout params{};
|
||||
std::memcpy(¶ms, input.data(), sizeof(IoctlChannelSetTimeout));
|
||||
NGLOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout);
|
||||
LOG_INFO(Service_NVDRV, "called, timeout=0x{:X}", params.timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
namespace Service::Nvidia::Devices {
|
||||
|
||||
u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
LOG_DEBUG(Service_NVDRV, "called, command=0x{:08X}, input_size=0x{:X}, output_size=0x{:X}",
|
||||
command.raw, input.size(), output.size());
|
||||
|
||||
switch (static_cast<IoctlCommand>(command.raw)) {
|
||||
case IoctlCommand::IocSetNVMAPfdCommand:
|
||||
@@ -24,7 +24,7 @@ u32 nvhost_nvdec::ioctl(Ioctl command, const std::vector<u8>& input, std::vector
|
||||
u32 nvhost_nvdec::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IoctlSetNvmapFD params{};
|
||||
std::memcpy(¶ms, input.data(), input.size());
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
||||
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
||||
nvmap_fd = params.nvmap_fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
u32 handle = next_handle++;
|
||||
handles[handle] = std::move(object);
|
||||
|
||||
NGLOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
|
||||
LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
|
||||
|
||||
params.handle = handle;
|
||||
|
||||
@@ -73,7 +73,7 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
object->addr = params.addr;
|
||||
object->status = Object::Status::Allocated;
|
||||
|
||||
NGLOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
|
||||
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
|
||||
|
||||
std::memcpy(output.data(), ¶ms, sizeof(params));
|
||||
return 0;
|
||||
@@ -83,7 +83,7 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IocGetIdParams params;
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
|
||||
NGLOG_WARNING(Service_NVDRV, "called");
|
||||
LOG_WARNING(Service_NVDRV, "called");
|
||||
|
||||
auto object = GetObject(params.handle);
|
||||
ASSERT(object);
|
||||
@@ -98,7 +98,7 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IocFromIdParams params;
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
|
||||
auto itr = std::find_if(handles.begin(), handles.end(),
|
||||
[&](const auto& entry) { return entry.second->id == params.id; });
|
||||
@@ -119,7 +119,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IocParamParams params;
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
|
||||
|
||||
auto object = GetObject(params.handle);
|
||||
ASSERT(object);
|
||||
@@ -148,6 +148,7 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
}
|
||||
|
||||
u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
// TODO(Subv): These flags are unconfirmed.
|
||||
enum FreeFlags {
|
||||
Freed = 0,
|
||||
NotFreedYet = 1,
|
||||
@@ -156,20 +157,26 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||
IocFreeParams params;
|
||||
std::memcpy(¶ms, input.data(), sizeof(params));
|
||||
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
|
||||
auto itr = handles.find(params.handle);
|
||||
ASSERT(itr != handles.end());
|
||||
|
||||
ASSERT(itr->second->refcount > 0);
|
||||
|
||||
itr->second->refcount--;
|
||||
|
||||
params.refcount = itr->second->refcount;
|
||||
params.size = itr->second->size;
|
||||
|
||||
if (itr->second->refcount == 0)
|
||||
if (itr->second->refcount == 0) {
|
||||
params.flags = Freed;
|
||||
else
|
||||
// The address of the nvmap is written to the output if we're finally freeing it, otherwise
|
||||
// 0 is written.
|
||||
params.address = itr->second->addr;
|
||||
} else {
|
||||
params.flags = NotFreedYet;
|
||||
params.address = 0;
|
||||
}
|
||||
|
||||
handles.erase(params.handle);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
struct IocFreeParams {
|
||||
u32_le handle;
|
||||
INSERT_PADDING_BYTES(4);
|
||||
u64_le refcount;
|
||||
u64_le address;
|
||||
u32_le size;
|
||||
u32_le flags;
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace Service::Nvidia {
|
||||
|
||||
void NVDRV::Open(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
|
||||
const auto& buffer = ctx.ReadBuffer();
|
||||
std::string device_name(buffer.begin(), buffer.end());
|
||||
@@ -25,7 +25,7 @@ void NVDRV::Open(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
u32 fd = rp.Pop<u32>();
|
||||
@@ -41,7 +41,7 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void NVDRV::Close(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_DEBUG(Service_NVDRV, "called");
|
||||
LOG_DEBUG(Service_NVDRV, "called");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
u32 fd = rp.Pop<u32>();
|
||||
@@ -53,7 +53,7 @@ void NVDRV::Close(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
@@ -63,7 +63,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
u32 fd = rp.Pop<u32>();
|
||||
u32 event_id = rp.Pop<u32>();
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
@@ -75,14 +75,14 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
pid = rp.Pop<u64>();
|
||||
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid);
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid);
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
|
||||
void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, IGBPBuffer& igbp_buffer) {
|
||||
buffer.igbp_buffer = igbp_buffer;
|
||||
buffer.status = Buffer::Status::Free;
|
||||
|
||||
NGLOG_WARNING(Service, "Adding graphics buffer {}", slot);
|
||||
LOG_WARNING(Service, "Adding graphics buffer {}", slot);
|
||||
|
||||
queue.emplace_back(buffer);
|
||||
|
||||
@@ -94,7 +94,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
|
||||
}
|
||||
|
||||
u32 BufferQueue::Query(QueryType type) {
|
||||
NGLOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type));
|
||||
LOG_WARNING(Service, "(STUBBED) called type={}", static_cast<u32>(type));
|
||||
switch (type) {
|
||||
case QueryType::NativeWindowFormat:
|
||||
// TODO(Subv): Use an enum for this
|
||||
|
||||
@@ -48,7 +48,7 @@ NVFlinger::~NVFlinger() {
|
||||
}
|
||||
|
||||
u64 NVFlinger::OpenDisplay(const std::string& name) {
|
||||
NGLOG_WARNING(Service, "Opening display {}", name);
|
||||
LOG_WARNING(Service, "Opening display {}", name);
|
||||
|
||||
// TODO(Subv): Currently we only support the Default display.
|
||||
ASSERT(name == "Default");
|
||||
|
||||
@@ -112,7 +112,7 @@ public:
|
||||
|
||||
private:
|
||||
void Initialize(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service_PCTL, "(STUBBED) called");
|
||||
LOG_WARNING(Service_PCTL, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
@@ -122,14 +122,14 @@ void Module::Interface::CreateService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IParentalControlService>();
|
||||
NGLOG_DEBUG(Service_PCTL, "called");
|
||||
LOG_DEBUG(Service_PCTL, "called");
|
||||
}
|
||||
|
||||
void Module::Interface::CreateServiceWithoutInitialize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IParentalControlService>();
|
||||
NGLOG_DEBUG(Service_PCTL, "called");
|
||||
LOG_DEBUG(Service_PCTL, "called");
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
|
||||
@@ -27,7 +27,7 @@ PlayReport::PlayReport(const char* name) : ServiceFramework(name) {
|
||||
|
||||
void PlayReport::SaveReportWithUser(Kernel::HLERequestContext& ctx) {
|
||||
// TODO(ogniK): Do we want to add play report?
|
||||
NGLOG_WARNING(Service_PREPO, "(STUBBED) called");
|
||||
LOG_WARNING(Service_PREPO, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "core/hle/service/friend/friend.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/lm/lm.h"
|
||||
#include "core/hle/service/mm/mm_u.h"
|
||||
#include "core/hle/service/nfp/nfp.h"
|
||||
#include "core/hle/service/nifm/nifm.h"
|
||||
#include "core/hle/service/ns/ns.h"
|
||||
@@ -121,7 +122,7 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
|
||||
}
|
||||
buf.push_back('}');
|
||||
|
||||
NGLOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf));
|
||||
LOG_ERROR(Service, "unknown / unimplemented {}", fmt::to_string(buf));
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
@@ -132,7 +133,7 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) {
|
||||
return ReportUnimplementedFunction(ctx, info);
|
||||
}
|
||||
|
||||
NGLOG_TRACE(
|
||||
LOG_TRACE(
|
||||
Service, "{}",
|
||||
MakeFunctionString(info->name, GetServiceName().c_str(), ctx.CommandBuffer()).c_str());
|
||||
handler_invoker(this, info->handler_callback, ctx);
|
||||
@@ -191,6 +192,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
|
||||
Friend::InstallInterfaces(*sm);
|
||||
HID::InstallInterfaces(*sm);
|
||||
LM::InstallInterfaces(*sm);
|
||||
MM::InstallInterfaces(*sm);
|
||||
NFP::InstallInterfaces(*sm);
|
||||
NIFM::InstallInterfaces(*sm);
|
||||
NS::InstallInterfaces(*sm);
|
||||
@@ -204,12 +206,12 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
|
||||
VI::InstallInterfaces(*sm, nv_flinger);
|
||||
Set::InstallInterfaces(*sm);
|
||||
|
||||
NGLOG_DEBUG(Service, "initialized OK");
|
||||
LOG_DEBUG(Service, "initialized OK");
|
||||
}
|
||||
|
||||
/// Shutdown ServiceManager
|
||||
void Shutdown() {
|
||||
g_kernel_named_ports.clear();
|
||||
NGLOG_DEBUG(Service, "shutdown OK");
|
||||
LOG_DEBUG(Service, "shutdown OK");
|
||||
}
|
||||
} // namespace Service
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
namespace Service::Set {
|
||||
|
||||
void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
u32 id = rp.Pop<u32>();
|
||||
|
||||
static constexpr std::array<LanguageCode, 17> available_language_codes = {{
|
||||
LanguageCode::JA,
|
||||
LanguageCode::EN_US,
|
||||
@@ -40,7 +37,7 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(available_language_codes.size()));
|
||||
|
||||
NGLOG_DEBUG(Service_SET, "called");
|
||||
LOG_DEBUG(Service_SET, "called");
|
||||
}
|
||||
|
||||
SET::SET() : ServiceFramework("set") {
|
||||
@@ -50,7 +47,7 @@ SET::SET() : ServiceFramework("set") {
|
||||
{2, nullptr, "MakeLanguageCode"},
|
||||
{3, nullptr, "GetAvailableLanguageCodeCount"},
|
||||
{4, nullptr, "GetRegionCode"},
|
||||
{5, nullptr, "GetAvailableLanguageCodes2"},
|
||||
{5, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes2"},
|
||||
{6, nullptr, "GetAvailableLanguageCodeCount2"},
|
||||
{7, nullptr, "GetKeyCodeMap"},
|
||||
{8, nullptr, "GetQuestFlag"},
|
||||
|
||||
@@ -16,7 +16,7 @@ void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
|
||||
NGLOG_WARNING(Service_SET, "(STUBBED) called");
|
||||
LOG_WARNING(Service_SET, "(STUBBED) called");
|
||||
}
|
||||
|
||||
SET_SYS::SET_SYS() : ServiceFramework("set:sys") {
|
||||
|
||||
@@ -17,7 +17,7 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(1); // Converted sessions start with 1 request handler
|
||||
|
||||
NGLOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId());
|
||||
LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId());
|
||||
}
|
||||
|
||||
void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
|
||||
@@ -29,11 +29,11 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
|
||||
Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client};
|
||||
rb.PushMoveObjects(session);
|
||||
|
||||
NGLOG_DEBUG(Service, "called, session={}", session->GetObjectId());
|
||||
LOG_DEBUG(Service, "called, session={}", session->GetObjectId());
|
||||
}
|
||||
|
||||
void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) {
|
||||
NGLOG_WARNING(Service, "(STUBBED) called, using DuplicateSession");
|
||||
LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession");
|
||||
|
||||
DuplicateSession(ctx);
|
||||
}
|
||||
@@ -43,7 +43,7 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0x500);
|
||||
|
||||
NGLOG_WARNING(Service, "(STUBBED) called");
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
Controller::Controller() : ServiceFramework("IpcController") {
|
||||
|
||||
@@ -86,7 +86,7 @@ SM::~SM() = default;
|
||||
void SM::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
NGLOG_DEBUG(Service_SM, "called");
|
||||
LOG_DEBUG(Service_SM, "called");
|
||||
}
|
||||
|
||||
void SM::GetService(Kernel::HLERequestContext& ctx) {
|
||||
@@ -102,8 +102,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
|
||||
if (client_port.Failed()) {
|
||||
IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0);
|
||||
rb.Push(client_port.Code());
|
||||
NGLOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name,
|
||||
client_port.Code().raw);
|
||||
LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, client_port.Code().raw);
|
||||
if (name.length() == 0)
|
||||
return; // LibNX Fix
|
||||
UNIMPLEMENTED();
|
||||
@@ -113,7 +112,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
|
||||
auto session = client_port.Unwrap()->Connect();
|
||||
ASSERT(session.Succeeded());
|
||||
if (session.Succeeded()) {
|
||||
NGLOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId());
|
||||
LOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId());
|
||||
IPC::ResponseBuilder rb =
|
||||
rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles);
|
||||
rb.Push(session.Code());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user