Compare commits

..

1 Commits

Author SHA1 Message Date
Kelebek1 1d3bc0a08f Use ScratchBuffer to reduce memory allocations in audio_core 2023-02-10 22:22:29 +00:00
268 changed files with 3140 additions and 9292 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ parameters:
steps:
- script: choco install vulkan-sdk
displayName: 'Install vulkan-sdk'
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DENABLE_LTO=ON -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
- script: refreshenv && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw /GA /Gr /Ob2" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DYUZU_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DYUZU_CRASH_DUMPS=ON .. && cd ..
displayName: 'Configure CMake'
- task: MSBuild@1
displayName: 'Build'
+3
View File
@@ -13,6 +13,9 @@
[submodule "dynarmic"]
path = externals/dynarmic
url = https://github.com/MerryMage/dynarmic.git
[submodule "libressl"]
path = externals/libressl
url = https://github.com/citra-emu/ext-libressl-portable.git
[submodule "libusb"]
path = externals/libusb/libusb
url = https://github.com/libusb/libusb.git
+27 -8
View File
@@ -56,8 +56,6 @@ option(YUZU_USE_BUNDLED_VCPKG "Use vcpkg for yuzu dependencies" "${MSVC}")
option(YUZU_CHECK_SUBMODULES "Check if submodules are present" ON)
option(YUZU_ENABLE_LTO "Enable link-time optimization" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_FASTER_LD "Check if a faster linker is available" ON "NOT WIN32" OFF)
if (YUZU_USE_BUNDLED_VCPKG)
@@ -67,9 +65,6 @@ if (YUZU_USE_BUNDLED_VCPKG)
if (YUZU_CRASH_DUMPS)
list(APPEND VCPKG_MANIFEST_FEATURES "dbghelp")
endif()
if (ENABLE_WEB_SERVICE)
list(APPEND VCPKG_MANIFEST_FEATURES "web-service")
endif()
include(${CMAKE_SOURCE_DIR}/externals/vcpkg/scripts/buildsystems/vcpkg.cmake)
elseif(NOT "$ENV{VCPKG_TOOLCHAIN_FILE}" STREQUAL "")
@@ -210,7 +205,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
# =======================================================================
# Enforce the search mode of non-required packages for better and shorter failure messages
find_package(Boost 1.73.0 REQUIRED context)
find_package(enet 1.3 MODULE)
find_package(fmt 9 REQUIRED)
find_package(inih MODULE)
@@ -247,13 +241,26 @@ endif()
if (ENABLE_WEB_SERVICE)
find_package(cpp-jwt 1.4 CONFIG)
find_package(httplib 0.12 MODULE)
find_package(httplib 0.11 MODULE)
endif()
if (YUZU_TESTS)
find_package(Catch2 3.0.1 REQUIRED)
endif()
find_package(Boost 1.73.0 COMPONENTS context)
if (Boost_FOUND)
set(Boost_LIBRARIES Boost::boost)
# Conditionally add Boost::context only if the found Boost package provides it
# The old version is missing Boost::context, so we want to avoid adding in that case
# The new version requires adding Boost::context to prevent linking issues
if (TARGET Boost::context)
list(APPEND Boost_LIBRARIES Boost::context)
endif()
else()
message(FATAL_ERROR "Boost 1.73.0 or newer not found")
endif()
# boost:asio has functions that require AcceptEx et al
if (MINGW)
find_library(MSWSOCK_LIBRARY mswsock REQUIRED)
@@ -450,6 +457,14 @@ if (ENABLE_SDL2)
endif()
endif()
# Reexport some targets that are named differently when using the upstream CmakeConfig
# In order to ALIAS targets to a new name, they first need to be IMPORTED_GLOBAL
# Dynarmic checks for target `boost` and so we want to make sure it can find it through our system instead of using their external
if (TARGET Boost::boost)
set_target_properties(Boost::boost PROPERTIES IMPORTED_GLOBAL TRUE)
add_library(boost ALIAS Boost::boost)
endif()
# List of all FFmpeg components required
set(FFmpeg_COMPONENTS
avcodec
@@ -565,7 +580,11 @@ function(create_target_directory_groups target_name)
endfunction()
# Prevent boost from linking against libs when building
target_link_libraries(Boost::headers INTERFACE Boost::disable_autolinking)
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
-DBOOST_SYSTEM_NO_LIB
-DBOOST_DATE_TIME_NO_LIB
-DBOOST_REGEX_NO_LIB
)
# Adjustments for MSVC + Ninja
if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja")
add_compile_options(
+31 -6
View File
@@ -102,16 +102,41 @@ add_subdirectory(sirit EXCLUDE_FROM_ALL)
# httplib
if (ENABLE_WEB_SERVICE AND NOT TARGET httplib::httplib)
set(HTTPLIB_REQUIRE_OPENSSL ON)
add_subdirectory(cpp-httplib EXCLUDE_FROM_ALL)
if (NOT WIN32)
find_package(OpenSSL 1.1)
if (OPENSSL_FOUND)
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
endif()
endif()
if (WIN32 OR NOT OPENSSL_FOUND)
# LibreSSL
set(LIBRESSL_SKIP_INSTALL ON)
set(OPENSSLDIR "/etc/ssl/")
add_subdirectory(libressl EXCLUDE_FROM_ALL)
target_include_directories(ssl INTERFACE ./libressl/include)
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
get_directory_property(OPENSSL_LIBRARIES
DIRECTORY libressl
DEFINITION OPENSSL_LIBS)
endif()
add_library(httplib INTERFACE)
target_include_directories(httplib INTERFACE ./cpp-httplib)
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
if (WIN32)
target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
endif()
add_library(httplib::httplib ALIAS httplib)
endif()
# cpp-jwt
if (ENABLE_WEB_SERVICE AND NOT TARGET cpp-jwt::cpp-jwt)
set(CPP_JWT_BUILD_EXAMPLES OFF)
set(CPP_JWT_BUILD_TESTS OFF)
set(CPP_JWT_USE_VENDORED_NLOHMANN_JSON OFF)
add_subdirectory(cpp-jwt EXCLUDE_FROM_ALL)
add_library(cpp-jwt INTERFACE)
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
add_library(cpp-jwt::cpp-jwt ALIAS cpp-jwt)
endif()
# Opus
Vendored Submodule
+1
Submodule externals/libressl added at 8929f818fd
+11 -9
View File
@@ -48,7 +48,7 @@ public:
*
* @param out_buffers - The buffers which were registered.
*/
void RegisterBuffers(std::vector<AudioBuffer>& out_buffers) {
void RegisterBuffers(std::span<AudioBuffer> out_buffers, u32& out_size) {
std::scoped_lock l{lock};
const s32 to_register{std::min(std::min(appended_count, BufferAppendLimit),
BufferAppendLimit - registered_count)};
@@ -59,7 +59,7 @@ public:
index += N;
}
out_buffers.push_back(buffers[index]);
out_buffers[out_size++] = buffers[index];
registered_count++;
registered_index = (registered_index + 1) % append_limit;
@@ -162,7 +162,7 @@ public:
* @param max_buffers - Maximum number of buffers to released.
* @return The number of buffers released.
*/
u32 GetRegisteredAppendedBuffers(std::vector<AudioBuffer>& buffers_flushed, u32 max_buffers) {
u32 GetRegisteredAppendedBuffers(std::span<AudioBuffer> out_buffers, u32 max_buffers) {
std::scoped_lock l{lock};
if (registered_count + appended_count == 0) {
return 0;
@@ -174,19 +174,20 @@ public:
return 0;
}
u32 buffers_flushed{0};
while (registered_count > 0) {
auto index{registered_index - registered_count};
if (index < 0) {
index += N;
}
buffers_flushed.push_back(buffers[index]);
out_buffers[buffers_flushed++] = buffers[index];
registered_count--;
released_count++;
released_index = (released_index + 1) % append_limit;
if (buffers_flushed.size() >= buffers_to_flush) {
if (buffers_flushed >= buffers_to_flush) {
break;
}
}
@@ -197,18 +198,18 @@ public:
index += N;
}
buffers_flushed.push_back(buffers[index]);
out_buffers[buffers_flushed++] = buffers[index];
appended_count--;
released_count++;
released_index = (released_index + 1) % append_limit;
if (buffers_flushed.size() >= buffers_to_flush) {
if (buffers_flushed >= buffers_to_flush) {
break;
}
}
return static_cast<u32>(buffers_flushed.size());
return buffers_flushed;
}
/**
@@ -270,8 +271,9 @@ public:
*/
bool FlushBuffers(u32& buffers_released) {
std::scoped_lock l{lock};
std::vector<AudioBuffer> buffers_flushed{};
static Common::ScratchBuffer<AudioBuffer> buffers_flushed{};
buffers_flushed.resize_destructive(append_limit);
buffers_released = GetRegisteredAppendedBuffers(buffers_flushed, append_limit);
if (registered_count > 0) {
+9 -7
View File
@@ -6,6 +6,7 @@
#include "audio_core/device/audio_buffer.h"
#include "audio_core/device/device_session.h"
#include "audio_core/sink/sink_stream.h"
#include "common/scratch_buffer.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/memory.h"
@@ -79,21 +80,22 @@ void DeviceSession::ClearBuffers() {
}
}
void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) const {
for (const auto& buffer : buffers) {
void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers, u32 out_size) const {
static Common::ScratchBuffer<s16> samples{};
for (u32 i = 0; i < out_size; i++) {
Sink::SinkBuffer new_buffer{
.frames = buffer.size / (channel_count * sizeof(s16)),
.frames = buffers[i].size / (channel_count * sizeof(s16)),
.frames_played = 0,
.tag = buffer.tag,
.tag = buffers[i].tag,
.consumed = false,
};
if (type == Sink::StreamType::In) {
std::vector<s16> samples{};
stream->AppendBuffer(new_buffer, samples);
} else {
std::vector<s16> samples(buffer.size / sizeof(s16));
system.Memory().ReadBlockUnsafe(buffer.samples, samples.data(), buffer.size);
samples.resize_destructive(buffers[i].size / sizeof(s16));
system.Memory().ReadBlockUnsafe(buffers[i].samples, samples.data(), buffers[i].size);
stream->AppendBuffer(new_buffer, samples);
}
}
+1 -1
View File
@@ -62,7 +62,7 @@ public:
*
* @param buffers - The buffers to play.
*/
void AppendBuffers(std::span<const AudioBuffer> buffers) const;
void AppendBuffers(std::span<const AudioBuffer> buffers, u32 out_size) const;
/**
* (Audio In only) Pop samples from the backend, and write them back to this buffer's address.
+8 -6
View File
@@ -89,9 +89,10 @@ Result System::Start() {
session->Start();
state = State::Started;
std::vector<AudioBuffer> buffers_to_flush{};
buffers.RegisterBuffers(buffers_to_flush);
session->AppendBuffers(buffers_to_flush);
std::array<AudioBuffer, BufferAppendLimit> buffers_to_flush{};
u32 out_size{0};
buffers.RegisterBuffers(buffers_to_flush, out_size);
session->AppendBuffers(buffers_to_flush, out_size);
session->SetRingSize(static_cast<u32>(buffers_to_flush.size()));
return ResultSuccess;
@@ -134,9 +135,10 @@ bool System::AppendBuffer(const AudioInBuffer& buffer, const u64 tag) {
void System::RegisterBuffers() {
if (state == State::Started) {
std::vector<AudioBuffer> registered_buffers{};
buffers.RegisterBuffers(registered_buffers);
session->AppendBuffers(registered_buffers);
std::array<AudioBuffer, BufferAppendLimit> registered_buffers{};
u32 out_size{0};
buffers.RegisterBuffers(registered_buffers, out_size);
session->AppendBuffers(registered_buffers, out_size);
}
}
+8 -6
View File
@@ -89,9 +89,10 @@ Result System::Start() {
session->Start();
state = State::Started;
std::vector<AudioBuffer> buffers_to_flush{};
buffers.RegisterBuffers(buffers_to_flush);
session->AppendBuffers(buffers_to_flush);
std::array<AudioBuffer, BufferAppendLimit> buffers_to_flush{};
u32 out_size{0};
buffers.RegisterBuffers(buffers_to_flush, out_size);
session->AppendBuffers(buffers_to_flush, out_size);
session->SetRingSize(static_cast<u32>(buffers_to_flush.size()));
return ResultSuccess;
@@ -134,9 +135,10 @@ bool System::AppendBuffer(const AudioOutBuffer& buffer, u64 tag) {
void System::RegisterBuffers() {
if (state == State::Started) {
std::vector<AudioBuffer> registered_buffers{};
buffers.RegisterBuffers(registered_buffers);
session->AppendBuffers(registered_buffers);
std::array<AudioBuffer, BufferAppendLimit> registered_buffers{};
u32 out_size{0};
buffers.RegisterBuffers(registered_buffers, out_size);
session->AppendBuffers(registered_buffers, out_size);
}
}
@@ -132,7 +132,7 @@ void AudioRenderer::CreateSinkStreams() {
}
void AudioRenderer::ThreadFunc() {
static constexpr char name[]{"AudioRenderer"};
constexpr char name[]{"AudioRenderer"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
@@ -251,8 +251,8 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
const auto& parameter{
*reinterpret_cast<BiquadFilterInfo::ParameterVersion1*>(effect_info.GetParameter())};
const auto state{reinterpret_cast<VoiceState::BiquadFilterState*>(
effect_info.GetStateBuffer() + channel * sizeof(VoiceState::BiquadFilterState))};
const auto state{
reinterpret_cast<VoiceState::BiquadFilterState*>(effect_info.GetStateBuffer())};
cmd.input = buffer_offset + parameter.inputs[channel];
cmd.output = buffer_offset + parameter.outputs[channel];
@@ -46,7 +46,7 @@ void CommandGenerator::GenerateDataSourceCommand(VoiceInfo& voice_info,
while (destination != nullptr) {
if (destination->IsConfigured()) {
auto mix_id{destination->GetMixId()};
if (mix_id < mix_context.GetCount() && mix_id != UnusedSplitterId) {
if (mix_id < mix_context.GetCount()) {
auto mix_info{mix_context.GetInfo(mix_id)};
command_buffer.GenerateDepopPrepareCommand(
voice_info.node_id, voice_state, render_context.depop_buffer,
@@ -8,6 +8,7 @@
#include "audio_core/renderer/command/resample/resample.h"
#include "common/fixed_point.h"
#include "common/logging/log.h"
#include "common/scratch_buffer.h"
#include "core/memory.h"
namespace AudioCore::AudioRenderer {
@@ -29,6 +30,7 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
const DecodeArg& req) {
constexpr s32 min{std::numeric_limits<s16>::min()};
constexpr s32 max{std::numeric_limits<s16>::max()};
static Common::ScratchBuffer<T> samples;
if (req.buffer == 0 || req.buffer_size == 0) {
return 0;
@@ -49,7 +51,7 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
const u64 size{channel_count * samples_to_decode};
const u64 size_bytes{size * sizeof(T)};
std::vector<T> samples(size);
samples.resize_destructive(size);
memory.ReadBlockUnsafe(source, samples.data(), size_bytes);
if constexpr (std::is_floating_point_v<T>) {
@@ -73,7 +75,7 @@ static u32 DecodePcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
}
const VAddr source{req.buffer + ((req.start_offset + req.offset) * sizeof(T))};
std::vector<T> samples(samples_to_decode);
samples.resize_destructive(samples_to_decode);
memory.ReadBlockUnsafe(source, samples.data(), samples_to_decode * sizeof(T));
if constexpr (std::is_floating_point_v<T>) {
@@ -103,6 +105,7 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
const DecodeArg& req) {
constexpr u32 SamplesPerFrame{14};
constexpr u32 NibblesPerFrame{16};
static Common::ScratchBuffer<u8> wavebuffer;
if (req.buffer == 0 || req.buffer_size == 0) {
return 0;
@@ -138,7 +141,7 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
}
const auto size{std::max((samples_to_process / 8U) * SamplesPerFrame, 8U)};
std::vector<u8> wavebuffer(size);
wavebuffer.resize_destructive(size);
memory.ReadBlockUnsafe(req.buffer + position_in_frame / 2, wavebuffer.data(),
wavebuffer.size());
@@ -227,6 +230,8 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer,
* @param args - The wavebuffer data, and information for how to decode it.
*/
void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args) {
Common::ScratchBuffer<s16> temp_buffer(TempBufferSize);
auto& voice_state{*args.voice_state};
auto remaining_sample_count{args.sample_count};
auto fraction{voice_state.fraction};
@@ -256,9 +261,8 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf
bool is_buffer_starved{false};
u32 offset{voice_state.offset};
std::memset(temp_buffer.data(), 0, temp_buffer.size() * sizeof(s16));
auto output_buffer{args.output};
std::vector<s16> temp_buffer(TempBufferSize, 0);
while (remaining_sample_count > 0) {
const auto samples_to_write{std::min(remaining_sample_count, max_remaining_sample_count)};
+39 -91
View File
@@ -4,7 +4,6 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/aux_.h"
#include "audio_core/renderer/effect/aux_.h"
#include "core/core.h"
#include "core/memory.h"
namespace AudioCore::AudioRenderer {
@@ -20,24 +19,10 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
return;
}
AuxInfo::AuxInfoDsp info{};
auto info_ptr{&info};
bool host_safe{(aux_info & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp))};
if (host_safe) [[likely]] {
info_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(aux_info);
} else {
memory.ReadBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
info_ptr->read_offset = 0;
info_ptr->write_offset = 0;
info_ptr->total_sample_count = 0;
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(aux_info, info_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
auto info{reinterpret_cast<AuxInfo::AuxInfoDsp*>(memory.GetPointer(aux_info))};
info->read_offset = 0;
info->write_offset = 0;
info->total_sample_count = 0;
}
/**
@@ -55,10 +40,11 @@ static void ResetAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr aux_in
* @param update_count - If non-zero, send_info_ will be updated.
* @return Number of samples written.
*/
static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
[[maybe_unused]] u32 sample_count, CpuAddr send_buffer, u32 count_max,
std::span<const s32> input, u32 write_count_, u32 write_offset,
u32 update_count) {
static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr send_info_,
[[maybe_unused]] u32 sample_count, const CpuAddr send_buffer,
const u32 count_max, std::span<const s32> input,
const u32 write_count_, const u32 write_offset,
const u32 update_count) {
if (write_count_ > count_max) {
LOG_ERROR(Service_Audio,
"write_count must be smaller than count_max! write_count {}, count_max {}",
@@ -66,11 +52,6 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
return 0;
}
if (send_info_ == 0) {
LOG_ERROR(Service_Audio, "send_info_ is 0!");
return 0;
}
if (input.empty()) {
LOG_ERROR(Service_Audio, "input buffer is empty!");
return 0;
@@ -86,47 +67,33 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
}
AuxInfo::AuxInfoDsp send_info{};
auto send_ptr = &send_info;
bool host_safe = (send_info_ & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
memory.ReadBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp));
if (host_safe) [[likely]] {
send_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(send_info_);
} else {
memory.ReadBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
u32 target_write_offset{send_ptr->write_offset + write_offset};
if (target_write_offset > count_max) {
u32 target_write_offset{send_info.write_offset + write_offset};
if (target_write_offset > count_max || write_count_ == 0) {
return 0;
}
u32 write_count{write_count_};
u32 read_pos{0};
u32 write_pos{0};
while (write_count > 0) {
u32 to_write{std::min(count_max - target_write_offset, write_count)};
const auto write_addr = send_buffer + target_write_offset * sizeof(s32);
bool write_safe{(write_addr & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - (write_addr + to_write * sizeof(s32)))};
if (write_safe) [[likely]] {
auto ptr = memory.GetPointer(write_addr);
std::memcpy(ptr, &input[read_pos], to_write * sizeof(s32));
} else {
if (to_write > 0) {
memory.WriteBlockUnsafe(send_buffer + target_write_offset * sizeof(s32),
&input[read_pos], to_write * sizeof(s32));
&input[write_pos], to_write * sizeof(s32));
}
target_write_offset = (target_write_offset + to_write) % count_max;
write_count -= to_write;
read_pos += to_write;
write_pos += to_write;
}
if (update_count) {
send_ptr->write_offset = (send_ptr->write_offset + update_count) % count_max;
send_info.write_offset = (send_info.write_offset + update_count) % count_max;
}
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(send_info_, send_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
memory.WriteBlockUnsafe(send_info_, &send_info, sizeof(AuxInfo::AuxInfoDsp));
return write_count_;
}
@@ -135,7 +102,7 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
* Read the given memory at return_buffer into the output mix buffer, and update return_info_ if
* update_count is set, to notify the game that an update happened.
*
* @param memory - Core memory for reading.
* @param memory - Core memory for writing.
* @param return_info_ - Meta information for where to read the mix buffer.
* @param return_buffer - Memory address to read the samples from.
* @param count_max - Maximum number of samples in the receiving buffer.
@@ -145,21 +112,16 @@ static u32 WriteAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr send_info_,
* @param update_count - If non-zero, send_info_ will be updated.
* @return Number of samples read.
*/
static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
CpuAddr return_buffer, u32 count_max, std::span<s32> output,
u32 read_count_, u32 read_offset, u32 update_count) {
static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, const CpuAddr return_info_,
const CpuAddr return_buffer, const u32 count_max, std::span<s32> output,
const u32 count_, const u32 read_offset, const u32 update_count) {
if (count_max == 0) {
return 0;
}
if (read_count_ > count_max) {
if (count_ > count_max) {
LOG_ERROR(Service_Audio, "count must be smaller than count_max! count {}, count_max {}",
read_count_, count_max);
return 0;
}
if (return_info_ == 0) {
LOG_ERROR(Service_Audio, "return_info_ is 0!");
count_, count_max);
return 0;
}
@@ -174,49 +136,35 @@ static u32 ReadAuxBufferDsp(Core::Memory::Memory& memory, CpuAddr return_info_,
}
AuxInfo::AuxInfoDsp return_info{};
auto return_ptr = &return_info;
bool host_safe = (return_info_ & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - sizeof(AuxInfo::AuxInfoDsp));
memory.ReadBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp));
if (host_safe) [[likely]] {
return_ptr = memory.GetPointer<AuxInfo::AuxInfoDsp>(return_info_);
} else {
memory.ReadBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
u32 target_read_offset{return_ptr->read_offset + read_offset};
u32 target_read_offset{return_info.read_offset + read_offset};
if (target_read_offset > count_max) {
return 0;
}
u32 read_count{read_count_};
u32 write_pos{0};
u32 read_count{count_};
u32 read_pos{0};
while (read_count > 0) {
u32 to_read{std::min(count_max - target_read_offset, read_count)};
const auto read_addr = return_buffer + target_read_offset * sizeof(s32);
bool read_safe{(read_addr & Core::Memory::YUZU_PAGEMASK) <=
(Core::Memory::YUZU_PAGESIZE - (read_addr + to_read * sizeof(s32)))};
if (read_safe) [[likely]] {
auto ptr = memory.GetPointer(read_addr);
std::memcpy(&output[write_pos], ptr, to_read * sizeof(s32));
} else {
if (to_read > 0) {
memory.ReadBlockUnsafe(return_buffer + target_read_offset * sizeof(s32),
&output[write_pos], to_read * sizeof(s32));
&output[read_pos], to_read * sizeof(s32));
}
target_read_offset = (target_read_offset + to_read) % count_max;
read_count -= to_read;
write_pos += to_read;
read_pos += to_read;
}
if (update_count) {
return_ptr->read_offset = (return_ptr->read_offset + update_count) % count_max;
return_info.read_offset = (return_info.read_offset + update_count) % count_max;
}
if (!host_safe) [[unlikely]] {
memory.WriteBlockUnsafe(return_info_, return_ptr, sizeof(AuxInfo::AuxInfoDsp));
}
memory.WriteBlockUnsafe(return_info_, &return_info, sizeof(AuxInfo::AuxInfoDsp));
return read_count_;
return count_;
}
void AuxCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor,
@@ -241,7 +189,7 @@ void AuxCommand::Process(const ADSP::CommandListProcessor& processor) {
update_count)};
if (read != processor.sample_count) {
std::memset(&output_buffer[read], 0, (processor.sample_count - read) * sizeof(s32));
std::memset(&output_buffer[read], 0, processor.sample_count - read);
}
} else {
ResetAuxBufferDsp(*processor.memory, send_buffer_info);
@@ -4,7 +4,6 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/biquad_filter.h"
#include "audio_core/renderer/voice/voice_state.h"
#include "common/bit_cast.h"
namespace AudioCore::AudioRenderer {
/**
@@ -20,21 +19,21 @@ namespace AudioCore::AudioRenderer {
void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b_, std::array<s16, 2>& a_,
VoiceState::BiquadFilterState& state, const u32 sample_count) {
constexpr f64 min{std::numeric_limits<s32>::min()};
constexpr f64 max{std::numeric_limits<s32>::max()};
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
std::array<f64, 3> b{Common::FixedPoint<50, 14>::from_base(b_[0]).to_double(),
Common::FixedPoint<50, 14>::from_base(b_[1]).to_double(),
Common::FixedPoint<50, 14>::from_base(b_[2]).to_double()};
std::array<f64, 2> a{Common::FixedPoint<50, 14>::from_base(a_[0]).to_double(),
Common::FixedPoint<50, 14>::from_base(a_[1]).to_double()};
std::array<f64, 4> s{Common::BitCast<f64>(state.s0), Common::BitCast<f64>(state.s1),
Common::BitCast<f64>(state.s2), Common::BitCast<f64>(state.s3)};
std::array<f64, 4> s{state.s0.to_double(), state.s1.to_double(), state.s2.to_double(),
state.s3.to_double()};
for (u32 i = 0; i < sample_count; i++) {
f64 in_sample{static_cast<f64>(input[i])};
auto sample{in_sample * b[0] + s[0] * b[1] + s[1] * b[2] + s[2] * a[0] + s[3] * a[1]};
output[i] = static_cast<s32>(std::clamp(sample, min, max));
output[i] = static_cast<s32>(std::clamp(static_cast<s64>(sample), min, max));
s[1] = s[0];
s[0] = in_sample;
@@ -42,10 +41,10 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
s[2] = sample;
}
state.s0 = Common::BitCast<s64>(s[0]);
state.s1 = Common::BitCast<s64>(s[1]);
state.s2 = Common::BitCast<s64>(s[2]);
state.s3 = Common::BitCast<s64>(s[3]);
state.s0 = s[0];
state.s1 = s[1];
state.s2 = s[2];
state.s3 = s[3];
}
/**
@@ -59,20 +58,29 @@ void ApplyBiquadFilterFloat(std::span<s32> output, std::span<const s32> input,
* @param sample_count - Number of samples to process.
*/
static void ApplyBiquadFilterInt(std::span<s32> output, std::span<const s32> input,
std::array<s16, 3>& b, std::array<s16, 2>& a,
std::array<s16, 3>& b_, std::array<s16, 2>& a_,
VoiceState::BiquadFilterState& state, const u32 sample_count) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
std::array<Common::FixedPoint<50, 14>, 3> b{
Common::FixedPoint<50, 14>::from_base(b_[0]),
Common::FixedPoint<50, 14>::from_base(b_[1]),
Common::FixedPoint<50, 14>::from_base(b_[2]),
};
std::array<Common::FixedPoint<50, 14>, 3> a{
Common::FixedPoint<50, 14>::from_base(a_[0]),
Common::FixedPoint<50, 14>::from_base(a_[1]),
};
for (u32 i = 0; i < sample_count; i++) {
const s64 in_sample{input[i]};
const s64 sample{in_sample * b[0] + state.s0};
const s64 out_sample{std::clamp<s64>((sample + (1 << 13)) >> 14, min, max)};
s64 in_sample{input[i]};
auto sample{in_sample * b[0] + state.s0};
const auto out_sample{std::clamp(sample.to_long(), min, max)};
output[i] = static_cast<s32>(out_sample);
state.s0 = state.s1 + b[1] * in_sample + a[0] * out_sample;
state.s1 = b[2] * in_sample + a[1] * out_sample;
state.s1 = 0 + b[2] * in_sample + a[1] * out_sample;
}
}
@@ -8,6 +8,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/compressor.h"
#include "audio_core/renderer/effect/compressor.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
@@ -44,8 +45,8 @@ static void InitializeCompressorEffect(const CompressorInfo::ParameterVersion2&
static void ApplyCompressorEffect(const CompressorInfo::ParameterVersion2& params,
CompressorInfo::State& state, bool enabled,
std::vector<std::span<const s32>> input_buffers,
std::vector<std::span<s32>> output_buffers, u32 sample_count) {
std::span<std::span<const s32>> input_buffers,
std::span<std::span<s32>> output_buffers, u32 sample_count) {
if (enabled) {
auto state_00{state.unk_00};
auto state_04{state.unk_04};
@@ -124,8 +125,10 @@ void CompressorCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
}
void CompressorCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (s16 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -3,6 +3,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/delay.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
/**
@@ -74,8 +75,8 @@ static void InitializeDelayEffect(const DelayInfo::ParameterVersion1& params,
*/
template <size_t NumChannels>
static void ApplyDelay(const DelayInfo::ParameterVersion1& params, DelayInfo::State& state,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
std::span<std::span<const s32>> inputs, std::span<std::span<s32>> outputs,
const u32 sample_count) {
for (u32 sample_index = 0; sample_index < sample_count; sample_index++) {
std::array<Common::FixedPoint<50, 14>, NumChannels> input_samples{};
for (u32 channel = 0; channel < NumChannels; channel++) {
@@ -153,8 +154,8 @@ static void ApplyDelay(const DelayInfo::ParameterVersion1& params, DelayInfo::St
* @param sample_count - Number of samples to process.
*/
static void ApplyDelayEffect(const DelayInfo::ParameterVersion1& params, DelayInfo::State& state,
const bool enabled, std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
const bool enabled, std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
if (!IsChannelCountValid(params.channel_count)) {
LOG_ERROR(Service_Audio, "Invalid delay channels {}", params.channel_count);
@@ -208,8 +209,10 @@ void DelayCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proce
}
void DelayCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (s16 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -6,6 +6,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/i3dl2_reverb.h"
#include "common/polyfill_ranges.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
@@ -244,16 +245,16 @@ template <size_t NumChannels>
static void ApplyI3dl2ReverbEffect(I3dl2ReverbInfo::State& state,
std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
};
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3,
};
static constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
constexpr std::array<u8, I3dl2ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
2, 0, 0, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 0, 0, 0, 0, 5, 5, 5,
};
@@ -408,8 +409,10 @@ void I3dl2ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor&
}
void I3dl2ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -3,6 +3,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/light_limiter.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
/**
@@ -47,8 +48,8 @@ static void InitializeLightLimiterEffect(const LightLimiterInfo::ParameterVersio
*/
static void ApplyLightLimiterEffect(const LightLimiterInfo::ParameterVersion2& params,
LightLimiterInfo::State& state, const bool enabled,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count,
std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count,
LightLimiterInfo::StatisticsInternal* statistics) {
constexpr s64 min{std::numeric_limits<s32>::min()};
constexpr s64 max{std::numeric_limits<s32>::max()};
@@ -147,8 +148,10 @@ void LightLimiterVersion1Command::Dump([[maybe_unused]] const ADSP::CommandListP
}
void LightLimiterVersion1Command::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -190,8 +193,10 @@ void LightLimiterVersion2Command::Dump([[maybe_unused]] const ADSP::CommandListP
}
void LightLimiterVersion2Command::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -7,6 +7,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/effect/reverb.h"
#include "common/polyfill_ranges.h"
#include "common/scratch_buffer.h"
namespace AudioCore::AudioRenderer {
@@ -250,18 +251,18 @@ static Common::FixedPoint<50, 14> Axfx2AllPassTick(ReverbInfo::ReverbDelayLine&
*/
template <size_t NumChannels>
static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes1Ch{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes2Ch{
0, 0, 1, 1, 0, 1, 0, 0, 1, 1,
};
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes4Ch{
0, 0, 1, 1, 0, 1, 2, 2, 3, 3,
};
static constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
constexpr std::array<u8, ReverbInfo::MaxDelayTaps> OutTapIndexes6Ch{
0, 0, 1, 1, 2, 2, 4, 4, 5, 5,
};
@@ -368,8 +369,8 @@ static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, Rever
* @param sample_count - Number of samples to process.
*/
static void ApplyReverbEffect(const ReverbInfo::ParameterVersion2& params, ReverbInfo::State& state,
const bool enabled, std::vector<std::span<const s32>>& inputs,
std::vector<std::span<s32>>& outputs, const u32 sample_count) {
const bool enabled, std::span<std::span<const s32>> inputs,
std::span<std::span<s32>> outputs, const u32 sample_count) {
if (enabled) {
switch (params.channel_count) {
case 0:
@@ -411,8 +412,10 @@ void ReverbCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& proc
}
void ReverbCommand::Process(const ADSP::CommandListProcessor& processor) {
std::vector<std::span<const s32>> input_buffers(parameter.channel_count);
std::vector<std::span<s32>> output_buffers(parameter.channel_count);
static Common::ScratchBuffer<std::span<const s32>> input_buffers{};
static Common::ScratchBuffer<std::span<s32>> output_buffers{};
input_buffers.resize_destructive(parameter.channel_count);
output_buffers.resize_destructive(parameter.channel_count);
for (u32 i = 0; i < parameter.channel_count; i++) {
input_buffers[i] = processor.mix_buffers.subspan(inputs[i] * processor.sample_count,
@@ -19,24 +19,24 @@ namespace AudioCore::AudioRenderer {
static void SrcProcessFrame(std::span<s32> output, std::span<const s32> input,
const u32 target_sample_count, const u32 source_sample_count,
UpsamplerState* state) {
static constexpr u32 WindowSize = 10;
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
constexpr u32 WindowSize = 10;
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc1{
0.95376587f, -0.12872314f, 0.060028076f, -0.032470703f, 0.017669678f,
-0.009124756f, 0.004272461f, -0.001739502f, 0.000579834f, -0.000091552734f,
};
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc2{
0.8230896f, -0.19161987f, 0.093444824f, -0.05090332f, 0.027557373f,
-0.014038086f, 0.0064697266f, -0.002532959f, 0.00079345703f, -0.00012207031f,
};
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc3{
0.6298828f, -0.19274902f, 0.09725952f, -0.05319214f, 0.028625488f,
-0.014373779f, 0.006500244f, -0.0024719238f, 0.0007324219f, -0.000091552734f,
};
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc4{
0.4057312f, -0.1468811f, 0.07601929f, -0.041656494f, 0.022216797f,
-0.011016846f, 0.004852295f, -0.0017700195f, 0.00048828125f, -0.000030517578f,
};
static constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
constexpr std::array<Common::FixedPoint<17, 15>, WindowSize> WindowedSinc5{
0.1854248f, -0.075164795f, 0.03967285f, -0.021728516f, 0.011474609f,
-0.005584717f, 0.0024108887f, -0.0008239746f, 0.00021362305f, 0.0f,
};
@@ -5,6 +5,7 @@
#include "audio_core/renderer/adsp/command_list_processor.h"
#include "audio_core/renderer/command/sink/circular_buffer.h"
#include "common/scratch_buffer.h"
#include "core/memory.h"
namespace AudioCore::AudioRenderer {
@@ -24,7 +25,9 @@ void CircularBufferSinkCommand::Process(const ADSP::CommandListProcessor& proces
constexpr s32 min{std::numeric_limits<s16>::min()};
constexpr s32 max{std::numeric_limits<s16>::max()};
std::vector<s16> output(processor.sample_count);
static Common::ScratchBuffer<s16> output{};
output.resize_destructive(processor.sample_count);
for (u32 channel = 0; channel < input_count; channel++) {
auto input{processor.mix_buffers.subspan(inputs[channel] * processor.sample_count,
processor.sample_count)};
@@ -33,7 +33,8 @@ void DeviceSinkCommand::Process(const ADSP::CommandListProcessor& processor) {
.consumed{false},
};
std::vector<s16> samples(out_buffer.frames * input_count);
static Common::ScratchBuffer<s16> samples{};
samples.resize_destructive(out_buffer.frames * input_count);
for (u32 channel = 0; channel < input_count; channel++) {
const auto offset{inputs[channel] * out_buffer.frames};
+1 -1
View File
@@ -127,7 +127,7 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
render_device = params.rendering_device;
execution_mode = params.execution_mode;
core.Memory().ZeroBlock(*core.ApplicationProcess(), transfer_memory->GetSourceAddress(),
core.Memory().ZeroBlock(*core.Kernel().CurrentProcess(), transfer_memory->GetSourceAddress(),
transfer_memory_size);
// Note: We're not actually using the transfer memory because it's a pain to code for.
+1 -1
View File
@@ -94,7 +94,7 @@ bool SystemManager::Remove(System& system_) {
}
void SystemManager::ThreadFunc() {
static constexpr char name[]{"AudioRenderSystemManager"};
constexpr char name[]{"AudioRenderSystemManager"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
+4 -4
View File
@@ -19,10 +19,10 @@ struct VoiceState {
* State of the voice's biquad filter.
*/
struct BiquadFilterState {
s64 s0;
s64 s1;
s64 s2;
s64 s3;
Common::FixedPoint<50, 14> s0;
Common::FixedPoint<50, 14> s1;
Common::FixedPoint<50, 14> s2;
Common::FixedPoint<50, 14> s3;
};
/**
+2 -1
View File
@@ -9,6 +9,7 @@
#include "audio_core/sink/sink.h"
#include "audio_core/sink/sink_stream.h"
#include "common/scratch_buffer.h"
namespace Core {
class System;
@@ -20,7 +21,7 @@ public:
explicit NullSinkStreamImpl(Core::System& system_, StreamType type_)
: SinkStream{system_, type_} {}
~NullSinkStreamImpl() override {}
void AppendBuffer(SinkBuffer&, std::vector<s16>&) override {}
void AppendBuffer(SinkBuffer&, Common::ScratchBuffer<s16>&) override {}
std::vector<s16> ReleaseBuffer(u64) override {
return {};
}
+9 -7
View File
@@ -17,7 +17,7 @@
namespace AudioCore::Sink {
void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
void SinkStream::AppendBuffer(SinkBuffer& buffer, Common::ScratchBuffer<s16>& samples) {
if (type == StreamType::In) {
queue.enqueue(buffer);
queued_buffers++;
@@ -35,7 +35,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
if (system_channels == 6 && device_channels == 2) {
// We're given 6 channels, but our device only outputs 2, so downmix.
static constexpr std::array<f32, 4> down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f};
constexpr std::array<f32, 4> down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f};
for (u32 read_index = 0, write_index = 0; read_index < samples.size();
read_index += system_channels, write_index += device_channels) {
@@ -71,7 +71,9 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
// We need moar samples! Not all games will provide 6 channel audio.
// TODO: Implement some upmixing here. Currently just passthrough, with other
// channels left as silence.
std::vector<s16> new_samples(samples.size() / system_channels * device_channels, 0);
static Common::ScratchBuffer<s16> new_samples{};
new_samples.resize_destructive(samples.size() / system_channels * device_channels);
std::memset(new_samples.data(), 0, new_samples.size() * sizeof(s16));
for (u32 read_index = 0, write_index = 0; read_index < samples.size();
read_index += system_channels, write_index += device_channels) {
@@ -100,7 +102,7 @@ void SinkStream::AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples) {
}
}
samples_buffer.Push(samples);
samples_buffer.Push(samples.data(), samples.size());
queue.enqueue(buffer);
queued_buffers++;
}
@@ -202,7 +204,7 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
// If we're paused or going to shut down, we don't want to consume buffers as coretiming is
// paused and we'll desync, so just play silence.
if (system.IsPaused() || system.IsShuttingDown()) {
static constexpr std::array<s16, 6> silence{};
constexpr std::array<s16, 6> silence{};
for (size_t i = frames_written; i < num_frames; i++) {
std::memcpy(&output_buffer[i * frame_size], &silence[0], frame_size_bytes);
}
@@ -270,7 +272,7 @@ void SinkStream::Stall() {
if (stalled_lock) {
return;
}
stalled_lock = system.StallApplication();
stalled_lock = system.StallProcesses();
}
void SinkStream::Unstall() {
@@ -278,7 +280,7 @@ void SinkStream::Unstall() {
if (!stalled_lock) {
return;
}
system.UnstallApplication();
system.UnstallProcesses();
stalled_lock.unlock();
}
+2 -1
View File
@@ -14,6 +14,7 @@
#include "common/common_types.h"
#include "common/reader_writer_queue.h"
#include "common/ring_buffer.h"
#include "common/scratch_buffer.h"
namespace Core {
class System;
@@ -169,7 +170,7 @@ public:
* @param buffer - Audio buffer information to be queued.
* @param samples - The s16 samples to be queue for playback.
*/
virtual void AppendBuffer(SinkBuffer& buffer, std::vector<s16>& samples);
virtual void AppendBuffer(SinkBuffer& buffer, Common::ScratchBuffer<s16>& samples);
/**
* Release a buffer. Audio In only, will fill a buffer with recorded samples.
+1 -1
View File
@@ -176,7 +176,7 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC Boost::context Boost::headers fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle)
if (YUZU_USE_PRECOMPILED_HEADERS)
+18 -1
View File
@@ -23,7 +23,24 @@ public:
buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {}
~ScratchBuffer() = default;
ScratchBuffer(ScratchBuffer&&) = default;
ScratchBuffer(ScratchBuffer&& rhs) {
last_requested_size = rhs.last_requested_size;
buffer_capacity = rhs.buffer_capacity;
buffer = std::move(rhs.buffer);
rhs.last_requested_size = 0;
rhs.buffer_capacity = 0;
}
void operator=(ScratchBuffer&& rhs) {
last_requested_size = rhs.last_requested_size;
buffer_capacity = rhs.buffer_capacity;
buffer = std::move(rhs.buffer);
rhs.last_requested_size = 0;
rhs.buffer_capacity = 0;
}
/// This will only grow the buffer's capacity if size is greater than the current capacity.
/// The previously held data will remain intact.
-13
View File
@@ -59,7 +59,6 @@ void LogSettings() {
values.use_asynchronous_gpu_emulation.GetValue());
log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
log_setting("Renderer_AsyncASTC", values.async_astc.GetValue());
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
@@ -77,13 +76,6 @@ void LogSettings() {
log_setting("Debugging_GDBStub", values.use_gdbstub.GetValue());
log_setting("Input_EnableMotion", values.motion_enabled.GetValue());
log_setting("Input_EnableVibration", values.vibration_enabled.GetValue());
log_setting("Input_EnableTouch", values.touchscreen.enabled);
log_setting("Input_EnableMouse", values.mouse_enabled.GetValue());
log_setting("Input_EnableKeyboard", values.keyboard_enabled.GetValue());
log_setting("Input_EnableRingController", values.enable_ring_controller.GetValue());
log_setting("Input_EnableIrSensor", values.enable_ir_sensor.GetValue());
log_setting("Input_EnableCustomJoycon", values.enable_joycon_driver.GetValue());
log_setting("Input_EnableCustomProController", values.enable_procon_driver.GetValue());
log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue());
}
@@ -207,11 +199,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.renderer_backend.SetGlobal(true);
values.renderer_force_max_clock.SetGlobal(true);
values.vulkan_device.SetGlobal(true);
values.fullscreen_mode.SetGlobal(true);
values.aspect_ratio.SetGlobal(true);
values.resolution_setup.SetGlobal(true);
values.scaling_filter.SetGlobal(true);
values.anti_aliasing.SetGlobal(true);
values.max_anisotropy.SetGlobal(true);
values.use_speed_limit.SetGlobal(true);
values.speed_limit.SetGlobal(true);
@@ -220,7 +208,6 @@ void RestoreGlobalState(bool is_powered_on) {
values.use_asynchronous_gpu_emulation.SetGlobal(true);
values.nvdec_emulation.SetGlobal(true);
values.accelerate_astc.SetGlobal(true);
values.async_astc.SetGlobal(true);
values.use_vsync.SetGlobal(true);
values.shader_backend.SetGlobal(true);
values.use_asynchronous_shaders.SetGlobal(true);
-2
View File
@@ -453,7 +453,6 @@ struct Values {
SwitchableSetting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"};
SwitchableSetting<bool> async_astc{false, "async_astc"};
SwitchableSetting<bool> use_vsync{true, "use_vsync"};
SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL,
ShaderBackend::SPIRV, "shader_backend"};
@@ -489,7 +488,6 @@ struct Values {
Setting<bool> enable_raw_input{false, "enable_raw_input"};
Setting<bool> controller_navigation{true, "controller_navigation"};
Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"};
Setting<bool> enable_procon_driver{false, "enable_procon_driver"};
SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"};
SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
+17 -8
View File
@@ -225,8 +225,6 @@ add_library(core STATIC
hle/kernel/k_memory_manager.h
hle/kernel/k_memory_region.h
hle/kernel/k_memory_region_type.h
hle/kernel/k_object_name.cpp
hle/kernel/k_object_name.h
hle/kernel/k_page_bitmap.h
hle/kernel/k_page_buffer.cpp
hle/kernel/k_page_buffer.h
@@ -312,7 +310,6 @@ add_library(core STATIC
hle/kernel/svc/svc_event.cpp
hle/kernel/svc/svc_exception.cpp
hle/kernel/svc/svc_info.cpp
hle/kernel/svc/svc_insecure_memory.cpp
hle/kernel/svc/svc_interrupt_event.cpp
hle/kernel/svc/svc_io_pool.cpp
hle/kernel/svc/svc_ipc.cpp
@@ -386,6 +383,8 @@ add_library(core STATIC
hle/service/am/omm.h
hle/service/am/spsm.cpp
hle/service/am/spsm.h
hle/service/am/tcap.cpp
hle/service/am/tcap.h
hle/service/aoc/aoc_u.cpp
hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp
@@ -396,18 +395,28 @@ add_library(core STATIC
hle/service/apm/apm_interface.h
hle/service/audio/audctl.cpp
hle/service/audio/audctl.h
hle/service/audio/auddbg.cpp
hle/service/audio/auddbg.h
hle/service/audio/audin_a.cpp
hle/service/audio/audin_a.h
hle/service/audio/audin_u.cpp
hle/service/audio/audin_u.h
hle/service/audio/audio.cpp
hle/service/audio/audio.h
hle/service/audio/audout_a.cpp
hle/service/audio/audout_a.h
hle/service/audio/audout_u.cpp
hle/service/audio/audout_u.h
hle/service/audio/audrec_a.cpp
hle/service/audio/audrec_a.h
hle/service/audio/audrec_u.cpp
hle/service/audio/audrec_u.h
hle/service/audio/audren_a.cpp
hle/service/audio/audren_a.h
hle/service/audio/audren_u.cpp
hle/service/audio/audren_u.h
hle/service/audio/codecctl.cpp
hle/service/audio/codecctl.h
hle/service/audio/errors.h
hle/service/audio/hwopus.cpp
hle/service/audio/hwopus.h
@@ -702,6 +711,8 @@ add_library(core STATIC
hle/service/sm/sm_controller.h
hle/service/sockets/bsd.cpp
hle/service/sockets/bsd.h
hle/service/sockets/ethc.cpp
hle/service/sockets/ethc.h
hle/service/sockets/nsd.cpp
hle/service/sockets/nsd.h
hle/service/sockets/sfdnsres.cpp
@@ -768,6 +779,8 @@ add_library(core STATIC
hle/service/vi/vi_s.h
hle/service/vi/vi_u.cpp
hle/service/vi/vi_u.h
hle/service/wlan/wlan.cpp
hle/service/wlan/wlan.h
internal_network/network.cpp
internal_network/network.h
internal_network/network_interface.cpp
@@ -832,7 +845,7 @@ endif()
create_target_directory_groups(core)
target_link_libraries(core PUBLIC common PRIVATE audio_core network video_core)
target_link_libraries(core PUBLIC Boost::headers PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::opus)
if (MINGW)
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
endif()
@@ -861,7 +874,3 @@ endif()
if (YUZU_USE_PRECOMPILED_HEADERS)
target_precompile_headers(core PRIVATE precompiled_headers.h)
endif()
if (YUZU_ENABLE_LTO)
set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
+3 -3
View File
@@ -43,9 +43,9 @@ void ARM_Interface::SymbolicateBacktrace(Core::System& system, std::vector<Backt
std::map<std::string, Symbols::Symbols> symbols;
for (const auto& module : modules) {
symbols.insert_or_assign(
module.second, Symbols::GetSymbols(module.first, system.Memory(),
system.ApplicationProcess()->Is64BitProcess()));
symbols.insert_or_assign(module.second,
Symbols::GetSymbols(module.first, system.Memory(),
system.CurrentProcess()->Is64BitProcess()));
}
for (auto& entry : out) {
-1
View File
@@ -5,7 +5,6 @@
#include <array>
#include <span>
#include <string>
#include <vector>
#include <dynarmic/interface/halt_reason.h>
+21 -21
View File
@@ -186,7 +186,7 @@ struct System::Impl {
void Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
kernel.SuspendApplication(false);
kernel.Suspend(false);
core_timing.SyncPause(false);
is_paused.store(false, std::memory_order_relaxed);
}
@@ -195,7 +195,7 @@ struct System::Impl {
std::unique_lock<std::mutex> lk(suspend_guard);
core_timing.SyncPause(true);
kernel.SuspendApplication(true);
kernel.Suspend(true);
is_paused.store(true, std::memory_order_relaxed);
}
@@ -203,17 +203,17 @@ struct System::Impl {
return is_paused.load(std::memory_order_relaxed);
}
std::unique_lock<std::mutex> StallApplication() {
std::unique_lock<std::mutex> StallProcesses() {
std::unique_lock<std::mutex> lk(suspend_guard);
kernel.SuspendApplication(true);
kernel.Suspend(true);
core_timing.SyncPause(true);
return lk;
}
void UnstallApplication() {
void UnstallProcesses() {
if (!IsPaused()) {
core_timing.SyncPause(false);
kernel.SuspendApplication(false);
kernel.Suspend(false);
}
}
@@ -221,7 +221,7 @@ struct System::Impl {
debugger = std::make_unique<Debugger>(system, port);
}
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
// Setting changes may require a full system reinitialization (e.g., disabling multicore).
@@ -273,7 +273,7 @@ struct System::Impl {
return SystemResultStatus::ErrorGetLoader;
}
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
SystemResultStatus init_result{SetupForMainProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
@@ -302,7 +302,7 @@ struct System::Impl {
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
}
AddGlueRegistrationForProcess(*app_loader, *main_process);
kernel.MakeApplicationProcess(main_process);
kernel.MakeCurrentProcess(main_process);
kernel.InitializeCores();
// Initialize cheat engine
@@ -585,12 +585,12 @@ void System::DetachDebugger() {
}
}
std::unique_lock<std::mutex> System::StallApplication() {
return impl->StallApplication();
std::unique_lock<std::mutex> System::StallProcesses() {
return impl->StallProcesses();
}
void System::UnstallApplication() {
impl->UnstallApplication();
void System::UnstallProcesses() {
impl->UnstallProcesses();
}
void System::InitializeDebugger() {
@@ -648,8 +648,8 @@ const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const {
return impl->kernel.GlobalSchedulerContext();
}
Kernel::KProcess* System::ApplicationProcess() {
return impl->kernel.ApplicationProcess();
Kernel::KProcess* System::CurrentProcess() {
return impl->kernel.CurrentProcess();
}
Core::DeviceMemory& System::DeviceMemory() {
@@ -660,8 +660,8 @@ const Core::DeviceMemory& System::DeviceMemory() const {
return *impl->device_memory;
}
const Kernel::KProcess* System::ApplicationProcess() const {
return impl->kernel.ApplicationProcess();
const Kernel::KProcess* System::CurrentProcess() const {
return impl->kernel.CurrentProcess();
}
ARM_Interface& System::ArmInterface(std::size_t core_index) {
@@ -760,8 +760,8 @@ const Core::SpeedLimiter& System::SpeedLimiter() const {
return impl->speed_limiter;
}
u64 System::GetApplicationProcessProgramID() const {
return impl->kernel.ApplicationProcess()->GetProgramID();
u64 System::GetCurrentProcessProgramID() const {
return impl->kernel.CurrentProcess()->GetProgramID();
}
Loader::ResultStatus System::GetGameName(std::string& out) const {
@@ -880,11 +880,11 @@ bool System::GetExitLock() const {
return impl->exit_lock;
}
void System::SetApplicationProcessBuildID(const CurrentBuildProcessID& id) {
void System::SetCurrentProcessBuildID(const CurrentBuildProcessID& id) {
impl->build_id = id;
}
const System::CurrentBuildProcessID& System::GetApplicationProcessBuildID() const {
const System::CurrentBuildProcessID& System::GetCurrentProcessBuildID() const {
return impl->build_id;
}
+9 -9
View File
@@ -184,8 +184,8 @@ public:
/// Forcibly detach the debugger if it is running.
void DetachDebugger();
std::unique_lock<std::mutex> StallApplication();
void UnstallApplication();
std::unique_lock<std::mutex> StallProcesses();
void UnstallProcesses();
/**
* Initialize the debugger.
@@ -295,11 +295,11 @@ public:
/// Gets the manager for the guest device memory
[[nodiscard]] const Core::DeviceMemory& DeviceMemory() const;
/// Provides a pointer to the application process
[[nodiscard]] Kernel::KProcess* ApplicationProcess();
/// Provides a pointer to the current process
[[nodiscard]] Kernel::KProcess* CurrentProcess();
/// Provides a constant pointer to the application process.
[[nodiscard]] const Kernel::KProcess* ApplicationProcess() const;
/// Provides a constant pointer to the current process.
[[nodiscard]] const Kernel::KProcess* CurrentProcess() const;
/// Provides a reference to the core timing instance.
[[nodiscard]] Timing::CoreTiming& CoreTiming();
@@ -331,7 +331,7 @@ public:
/// Provides a constant reference to the speed limiter
[[nodiscard]] const Core::SpeedLimiter& SpeedLimiter() const;
[[nodiscard]] u64 GetApplicationProcessProgramID() const;
[[nodiscard]] u64 GetCurrentProcessProgramID() const;
/// Gets the name of the current game
[[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
@@ -396,8 +396,8 @@ public:
void SetExitLock(bool locked);
[[nodiscard]] bool GetExitLock() const;
void SetApplicationProcessBuildID(const CurrentBuildProcessID& id);
[[nodiscard]] const CurrentBuildProcessID& GetApplicationProcessBuildID() const;
void SetCurrentProcessBuildID(const CurrentBuildProcessID& id);
[[nodiscard]] const CurrentBuildProcessID& GetCurrentProcessBuildID() const;
/// Register a host thread as an emulated CPU Core.
void RegisterCoreThread(std::size_t id);
+1 -1
View File
@@ -45,7 +45,7 @@ CoreTiming::~CoreTiming() {
}
void CoreTiming::ThreadEntry(CoreTiming& instance) {
static constexpr char name[] = "HostTiming";
constexpr char name[] = "HostTiming";
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
+14 -14
View File
@@ -96,7 +96,7 @@ static std::string EscapeXML(std::string_view data) {
GDBStub::GDBStub(DebuggerBackend& backend_, Core::System& system_)
: DebuggerFrontend(backend_), system{system_} {
if (system.ApplicationProcess()->Is64BitProcess()) {
if (system.CurrentProcess()->Is64BitProcess()) {
arch = std::make_unique<GDBStubA64>();
} else {
arch = std::make_unique<GDBStubA32>();
@@ -340,15 +340,15 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) {
success = true;
break;
case BreakpointType::WriteWatch:
success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
success = system.CurrentProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
break;
case BreakpointType::ReadWatch:
success = system.ApplicationProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
success = system.CurrentProcess()->InsertWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
break;
case BreakpointType::AccessWatch:
success = system.ApplicationProcess()->InsertWatchpoint(
success = system.CurrentProcess()->InsertWatchpoint(
system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
break;
case BreakpointType::Hardware:
@@ -391,15 +391,15 @@ void GDBStub::HandleBreakpointRemove(std::string_view command) {
break;
}
case BreakpointType::WriteWatch:
success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Write);
break;
case BreakpointType::ReadWatch:
success = system.ApplicationProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
success = system.CurrentProcess()->RemoveWatchpoint(system, addr, size,
Kernel::DebugWatchpointType::Read);
break;
case BreakpointType::AccessWatch:
success = system.ApplicationProcess()->RemoveWatchpoint(
success = system.CurrentProcess()->RemoveWatchpoint(
system, addr, size, Kernel::DebugWatchpointType::ReadOrWrite);
break;
case BreakpointType::Hardware:
@@ -482,7 +482,7 @@ static std::optional<std::string> GetNameFromThreadType64(Core::Memory::Memory&
static std::optional<std::string> GetThreadName(Core::System& system,
const Kernel::KThread* thread) {
if (system.ApplicationProcess()->Is64BitProcess()) {
if (system.CurrentProcess()->Is64BitProcess()) {
return GetNameFromThreadType64(system.Memory(), thread);
} else {
return GetNameFromThreadType32(system.Memory(), thread);
@@ -555,7 +555,7 @@ void GDBStub::HandleQuery(std::string_view command) {
SendReply(fmt::format("TextSeg={:x}", main->first));
} else {
SendReply(fmt::format("TextSeg={:x}",
system.ApplicationProcess()->PageTable().GetCodeRegionStart()));
system.CurrentProcess()->PageTable().GetCodeRegionStart()));
}
} else if (command.starts_with("Xfer:libraries:read::")) {
Loader::AppLoader::Modules modules;
@@ -729,7 +729,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
std::string_view command_str{reinterpret_cast<const char*>(&command[0]), command.size()};
std::string reply;
auto* process = system.ApplicationProcess();
auto* process = system.CurrentProcess();
auto& page_table = process->PageTable();
const char* commands = "Commands:\n"
+10 -4
View File
@@ -41,8 +41,9 @@ static void PutSIMDRegister(std::array<u32, 64>& simd_regs, size_t offset, const
// For sample XML files see the GDB source /gdb/features
// This XML defines what the registers are for this specific ARM device
std::string_view GDBStubA64::GetTargetXML() const {
return R"(<?xml version="1.0"?>
std::string GDBStubA64::GetTargetXML() const {
constexpr const char* target_xml =
R"(<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>aarch64</architecture>
@@ -177,6 +178,8 @@ std::string_view GDBStubA64::GetTargetXML() const {
<reg name="fpcr" bitsize="32"/>
</feature>
</target>)";
return target_xml;
}
std::string GDBStubA64::RegRead(const Kernel::KThread* thread, size_t id) const {
@@ -267,8 +270,9 @@ u32 GDBStubA64::BreakpointInstruction() const {
return 0xd4200000;
}
std::string_view GDBStubA32::GetTargetXML() const {
return R"(<?xml version="1.0"?>
std::string GDBStubA32::GetTargetXML() const {
constexpr const char* target_xml =
R"(<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>arm</architecture>
@@ -374,6 +378,8 @@ std::string_view GDBStubA32::GetTargetXML() const {
<reg name="fpscr" bitsize="32" type="int" group="float" regnum="80"/>
</feature>
</target>)";
return target_xml;
}
std::string GDBStubA32::RegRead(const Kernel::KThread* thread, size_t id) const {
+3 -3
View File
@@ -16,7 +16,7 @@ namespace Core {
class GDBStubArch {
public:
virtual ~GDBStubArch() = default;
virtual std::string_view GetTargetXML() const = 0;
virtual std::string GetTargetXML() const = 0;
virtual std::string RegRead(const Kernel::KThread* thread, size_t id) const = 0;
virtual void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const = 0;
virtual std::string ReadRegisters(const Kernel::KThread* thread) const = 0;
@@ -27,7 +27,7 @@ public:
class GDBStubA64 final : public GDBStubArch {
public:
std::string_view GetTargetXML() const override;
std::string GetTargetXML() const override;
std::string RegRead(const Kernel::KThread* thread, size_t id) const override;
void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override;
std::string ReadRegisters(const Kernel::KThread* thread) const override;
@@ -47,7 +47,7 @@ private:
class GDBStubA32 final : public GDBStubArch {
public:
std::string_view GetTargetXML() const override;
std::string GetTargetXML() const override;
std::string RegRead(const Kernel::KThread* thread, size_t id) const override;
void RegWrite(Kernel::KThread* thread, size_t id, std::string_view value) const override;
std::string ReadRegisters(const Kernel::KThread* thread) const override;
+4 -4
View File
@@ -41,12 +41,12 @@ static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
return IPSFileType::Error;
}
static constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
constexpr std::array<u8, 5> patch_magic{{'P', 'A', 'T', 'C', 'H'}};
if (std::equal(magic.begin(), magic.end(), patch_magic.begin())) {
return IPSFileType::IPS;
}
static constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
constexpr std::array<u8, 5> ips32_magic{{'I', 'P', 'S', '3', '2'}};
if (std::equal(magic.begin(), magic.end(), ips32_magic.begin())) {
return IPSFileType::IPS32;
}
@@ -55,12 +55,12 @@ static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
}
static bool IsEOF(IPSFileType type, const std::vector<u8>& data) {
static constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
constexpr std::array<u8, 3> eof{{'E', 'O', 'F'}};
if (type == IPSFileType::IPS && std::equal(data.begin(), data.end(), eof.begin())) {
return true;
}
static constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
constexpr std::array<u8, 4> eeof{{'E', 'E', 'O', 'F'}};
return type == IPSFileType::IPS32 && std::equal(data.begin(), data.end(), eeof.begin());
}
+1 -1
View File
@@ -71,7 +71,7 @@ static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bo
}
static std::string GetCNMTName(TitleType type, u64 title_id) {
static constexpr std::array<const char*, 9> TITLE_TYPE_NAMES{
constexpr std::array<const char*, 9> TITLE_TYPE_NAMES{
"SystemProgram",
"SystemData",
"SystemUpdate",
+1 -1
View File
@@ -172,7 +172,7 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
// be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
if (title_id == 0) {
title_id = system.GetApplicationProcessProgramID();
title_id = system.GetCurrentProcessProgramID();
}
}
+1 -2
View File
@@ -23,8 +23,7 @@ void EmulatedConsole::SetTouchParams() {
// We can't use mouse as touch if native mouse is enabled
if (!Settings::values.mouse_enabled) {
touch_params[index++] =
Common::ParamPackage{"engine:mouse,axis_x:0,axis_y:1,button:0,port:2"};
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
}
touch_params[index++] =
+2 -32
View File
@@ -363,17 +363,7 @@ void EmulatedController::ReloadInput() {
SetMotion(callback, index);
},
});
// Restore motion state
auto& emulated_motion = controller.motion_values[index].emulated;
auto& motion = controller.motion_state[index];
emulated_motion.ResetRotations();
emulated_motion.ResetQuaternion();
motion.accel = emulated_motion.GetAcceleration();
motion.gyro = emulated_motion.GetGyroscope();
motion.rotation = emulated_motion.GetRotations();
motion.orientation = emulated_motion.GetOrientation();
motion.is_at_rest = !emulated_motion.IsMoving(motion_sensitivity);
motion_devices[index]->ForceUpdate();
}
for (std::size_t index = 0; index < camera_devices.size(); ++index) {
@@ -967,7 +957,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
raw_status.gyro.y.value,
raw_status.gyro.z.value,
});
emulated.SetUserGyroThreshold(raw_status.gyro.x.properties.threshold);
emulated.SetGyroThreshold(raw_status.gyro.x.properties.threshold);
emulated.UpdateRotation(raw_status.delta_timestamp);
emulated.UpdateOrientation(raw_status.delta_timestamp);
force_update_motion = raw_status.force_update;
@@ -1294,26 +1284,6 @@ void EmulatedController::SetLedPattern() {
}
}
void EmulatedController::SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode) {
for (auto& motion : controller.motion_values) {
switch (mode) {
case GyroscopeZeroDriftMode::Loose:
motion_sensitivity = motion.emulated.IsAtRestLoose;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdLoose);
break;
case GyroscopeZeroDriftMode::Tight:
motion_sensitivity = motion.emulated.IsAtRestThight;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdThight);
break;
case GyroscopeZeroDriftMode::Standard:
default:
motion_sensitivity = motion.emulated.IsAtRestStandard;
motion.emulated.SetGyroThreshold(motion.emulated.ThresholdStandard);
break;
}
}
}
void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) {
supported_style_tag = supported_styles;
if (!is_connected) {
+1 -4
View File
@@ -398,9 +398,6 @@ public:
/// Asks the output device to change the player led pattern
void SetLedPattern();
/// Changes sensitivity of the motion sensor
void SetGyroscopeZeroDriftMode(GyroscopeZeroDriftMode mode);
/**
* Adds a callback to the list of events
* @param update_callback A ConsoleUpdateCallback that will be triggered
@@ -526,7 +523,7 @@ private:
bool is_connected{false};
bool is_configuring{false};
bool system_buttons_enabled{true};
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
f32 motion_sensitivity{0.01f};
bool force_update_motion{false};
u32 turbo_button_state{0};
+37 -43
View File
@@ -19,53 +19,49 @@ void EmulatedDevices::ReloadFromSettings() {
void EmulatedDevices::ReloadInput() {
// If you load any device here add the equivalent to the UnloadInput() function
// Native Mouse is mapped on port 1, pad 0
const Common::ParamPackage mouse_params{"engine:mouse,port:1,pad:0"};
// Keyboard keys is mapped on port 1, pad 0 for normal keys, pad 1 for moddifier keys
const Common::ParamPackage keyboard_params{"engine:keyboard,port:1"};
std::size_t key_index = 0;
for (auto& mouse_device : mouse_button_devices) {
Common::ParamPackage mouse_button_params = mouse_params;
mouse_button_params.Set("button", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_button_params);
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("button", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_params);
key_index++;
}
Common::ParamPackage mouse_position_params = mouse_params;
mouse_position_params.Set("axis_x", 0);
mouse_position_params.Set("axis_y", 1);
mouse_position_params.Set("deadzone", 0.0f);
mouse_position_params.Set("range", 1.0f);
mouse_position_params.Set("threshold", 0.0f);
mouse_stick_device = Common::Input::CreateInputDevice(mouse_position_params);
mouse_stick_device =
Common::Input::CreateInputDeviceFromString("engine:mouse,axis_x:0,axis_y:1");
// First two axis are reserved for mouse position
key_index = 2;
for (auto& mouse_device : mouse_wheel_devices) {
Common::ParamPackage mouse_wheel_params = mouse_params;
mouse_wheel_params.Set("axis", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_wheel_params);
for (auto& mouse_device : mouse_analog_devices) {
Common::ParamPackage mouse_params;
mouse_params.Set("engine", "mouse");
mouse_params.Set("axis", static_cast<int>(key_index));
mouse_device = Common::Input::CreateInputDevice(mouse_params);
key_index++;
}
key_index = 0;
for (auto& keyboard_device : keyboard_devices) {
Common::ParamPackage keyboard_key_params = keyboard_params;
keyboard_key_params.Set("button", static_cast<int>(key_index));
keyboard_key_params.Set("pad", 0);
keyboard_device = Common::Input::CreateInputDevice(keyboard_key_params);
// Keyboard keys are only mapped on port 1, pad 0
Common::ParamPackage keyboard_params;
keyboard_params.Set("engine", "keyboard");
keyboard_params.Set("button", static_cast<int>(key_index));
keyboard_params.Set("port", 1);
keyboard_params.Set("pad", 0);
keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
key_index++;
}
key_index = 0;
for (auto& keyboard_device : keyboard_modifier_devices) {
Common::ParamPackage keyboard_moddifier_params = keyboard_params;
keyboard_moddifier_params.Set("button", static_cast<int>(key_index));
keyboard_moddifier_params.Set("pad", 1);
keyboard_device = Common::Input::CreateInputDevice(keyboard_moddifier_params);
// Keyboard moddifiers are only mapped on port 1, pad 1
Common::ParamPackage keyboard_params;
keyboard_params.Set("engine", "keyboard");
keyboard_params.Set("button", static_cast<int>(key_index));
keyboard_params.Set("port", 1);
keyboard_params.Set("pad", 1);
keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
key_index++;
}
@@ -81,14 +77,14 @@ void EmulatedDevices::ReloadInput() {
});
}
for (std::size_t index = 0; index < mouse_wheel_devices.size(); ++index) {
if (!mouse_wheel_devices[index]) {
for (std::size_t index = 0; index < mouse_analog_devices.size(); ++index) {
if (!mouse_analog_devices[index]) {
continue;
}
mouse_wheel_devices[index]->SetCallback({
mouse_analog_devices[index]->SetCallback({
.on_change =
[this, index](const Common::Input::CallbackStatus& callback) {
SetMouseWheel(callback, index);
SetMouseAnalog(callback, index);
},
});
}
@@ -96,9 +92,7 @@ void EmulatedDevices::ReloadInput() {
if (mouse_stick_device) {
mouse_stick_device->SetCallback({
.on_change =
[this](const Common::Input::CallbackStatus& callback) {
SetMousePosition(callback);
},
[this](const Common::Input::CallbackStatus& callback) { SetMouseStick(callback); },
});
}
@@ -131,7 +125,7 @@ void EmulatedDevices::UnloadInput() {
for (auto& button : mouse_button_devices) {
button.reset();
}
for (auto& analog : mouse_wheel_devices) {
for (auto& analog : mouse_analog_devices) {
analog.reset();
}
mouse_stick_device.reset();
@@ -365,18 +359,18 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba
TriggerOnChange(DeviceTriggerType::Mouse);
}
void EmulatedDevices::SetMouseWheel(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= device_status.mouse_wheel_values.size()) {
void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callback,
std::size_t index) {
if (index >= device_status.mouse_analog_values.size()) {
return;
}
std::unique_lock lock{mutex};
const auto analog_value = TransformToAnalog(callback);
device_status.mouse_wheel_values[index] = analog_value;
device_status.mouse_analog_values[index] = analog_value;
if (is_configuring) {
device_status.mouse_wheel_state = {};
device_status.mouse_position_state = {};
lock.unlock();
TriggerOnChange(DeviceTriggerType::Mouse);
return;
@@ -395,7 +389,7 @@ void EmulatedDevices::SetMouseWheel(const Common::Input::CallbackStatus& callbac
TriggerOnChange(DeviceTriggerType::Mouse);
}
void EmulatedDevices::SetMousePosition(const Common::Input::CallbackStatus& callback) {
void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callback) {
std::unique_lock lock{mutex};
const auto touch_value = TransformToTouch(callback);
+22 -7
View File
@@ -23,8 +23,8 @@ using KeyboardModifierDevices = std::array<std::unique_ptr<Common::Input::InputD
Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseButton::NumMouseButtons>;
using MouseWheelDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>;
using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
using MouseButtonParams =
@@ -36,7 +36,7 @@ using KeyboardModifierValues =
std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardMods>;
using MouseButtonValues =
std::array<Common::Input::ButtonStatus, Settings::NativeMouseButton::NumMouseButtons>;
using MouseWheelValues =
using MouseAnalogValues =
std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
using MouseStickValue = Common::Input::TouchStatus;
@@ -50,7 +50,7 @@ struct DeviceStatus {
KeyboardValues keyboard_values{};
KeyboardModifierValues keyboard_moddifier_values{};
MouseButtonValues mouse_button_values{};
MouseWheelValues mouse_wheel_values{};
MouseAnalogValues mouse_analog_values{};
MouseStickValue mouse_stick_value{};
// Data for HID serices
@@ -111,6 +111,15 @@ public:
/// Reverts any mapped changes made that weren't saved
void RestoreConfig();
// Returns the current mapped ring device
Common::ParamPackage GetRingParam() const;
/**
* Updates the current mapped ring device
* @param param ParamPackage with ring sensor data to be mapped
*/
void SetRingParam(Common::ParamPackage param);
/// Returns the latest status of button input from the keyboard with parameters
KeyboardValues GetKeyboardValues() const;
@@ -178,13 +187,19 @@ private:
* @param callback A CallbackStatus containing the wheel status
* @param index wheel ID to be updated
*/
void SetMouseWheel(const Common::Input::CallbackStatus& callback, std::size_t index);
void SetMouseAnalog(const Common::Input::CallbackStatus& callback, std::size_t index);
/**
* Updates the mouse position status of the mouse device
* @param callback A CallbackStatus containing the position status
*/
void SetMousePosition(const Common::Input::CallbackStatus& callback);
void SetMouseStick(const Common::Input::CallbackStatus& callback);
/**
* Updates the ring analog sensor status of the ring controller
* @param callback A CallbackStatus containing the force status
*/
void SetRingAnalog(const Common::Input::CallbackStatus& callback);
/**
* Triggers a callback that something has changed on the device status
@@ -197,7 +212,7 @@ private:
KeyboardDevices keyboard_devices;
KeyboardModifierDevices keyboard_modifier_devices;
MouseButtonDevices mouse_button_devices;
MouseWheelDevices mouse_wheel_devices;
MouseAnalogDevices mouse_analog_devices;
MouseStickDevice mouse_stick_device;
mutable std::mutex mutex;
-7
View File
@@ -282,13 +282,6 @@ enum class VibrationGcErmCommand : u64 {
StopHard = 2,
};
// This is nn::hid::GyroscopeZeroDriftMode
enum class GyroscopeZeroDriftMode : u32 {
Loose = 0,
Standard = 1,
Tight = 2,
};
// This is nn::hid::NpadStyleTag
struct NpadStyleTag {
union {
+4 -22
View File
@@ -9,9 +9,7 @@ namespace Core::HID {
MotionInput::MotionInput() {
// Initialize PID constants with default values
SetPID(0.3f, 0.005f, 0.0f);
SetGyroThreshold(ThresholdStandard);
ResetQuaternion();
ResetRotations();
SetGyroThreshold(0.007f);
}
void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
@@ -22,25 +20,17 @@ void MotionInput::SetPID(f32 new_kp, f32 new_ki, f32 new_kd) {
void MotionInput::SetAcceleration(const Common::Vec3f& acceleration) {
accel = acceleration;
accel.x = std::clamp(accel.x, -AccelMaxValue, AccelMaxValue);
accel.y = std::clamp(accel.y, -AccelMaxValue, AccelMaxValue);
accel.z = std::clamp(accel.z, -AccelMaxValue, AccelMaxValue);
}
void MotionInput::SetGyroscope(const Common::Vec3f& gyroscope) {
gyro = gyroscope - gyro_bias;
gyro.x = std::clamp(gyro.x, -GyroMaxValue, GyroMaxValue);
gyro.y = std::clamp(gyro.y, -GyroMaxValue, GyroMaxValue);
gyro.z = std::clamp(gyro.z, -GyroMaxValue, GyroMaxValue);
// Auto adjust drift to minimize drift
if (!IsMoving(IsAtRestRelaxed)) {
if (!IsMoving(0.1f)) {
gyro_bias = (gyro_bias * 0.9999f) + (gyroscope * 0.0001f);
}
if (gyro.Length() < gyro_threshold * user_gyro_threshold) {
if (gyro.Length() < gyro_threshold) {
gyro = {};
} else {
only_accelerometer = false;
@@ -59,10 +49,6 @@ void MotionInput::SetGyroThreshold(f32 threshold) {
gyro_threshold = threshold;
}
void MotionInput::SetUserGyroThreshold(f32 threshold) {
user_gyro_threshold = threshold / ThresholdStandard;
}
void MotionInput::EnableReset(bool reset) {
reset_enabled = reset;
}
@@ -71,10 +57,6 @@ void MotionInput::ResetRotations() {
rotations = {};
}
void MotionInput::ResetQuaternion() {
quat = {{0.0f, 0.0f, -1.0f}, 0.0f};
}
bool MotionInput::IsMoving(f32 sensitivity) const {
return gyro.Length() >= sensitivity || accel.Length() <= 0.9f || accel.Length() >= 1.1f;
}
@@ -226,7 +208,7 @@ void MotionInput::ResetOrientation() {
if (!reset_enabled || only_accelerometer) {
return;
}
if (!IsMoving(IsAtRestRelaxed) && accel.z <= -0.9f) {
if (!IsMoving(0.5f) && accel.z <= -0.9f) {
++reset_counter;
if (reset_counter > 900) {
quat.w = 0;
+1 -20
View File
@@ -11,18 +11,6 @@ namespace Core::HID {
class MotionInput {
public:
static constexpr float ThresholdLoose = 0.01f;
static constexpr float ThresholdStandard = 0.007f;
static constexpr float ThresholdThight = 0.002f;
static constexpr float IsAtRestRelaxed = 0.05f;
static constexpr float IsAtRestLoose = 0.02f;
static constexpr float IsAtRestStandard = 0.01f;
static constexpr float IsAtRestThight = 0.005f;
static constexpr float GyroMaxValue = 5.0f;
static constexpr float AccelMaxValue = 7.0f;
explicit MotionInput();
MotionInput(const MotionInput&) = default;
@@ -38,12 +26,8 @@ public:
void SetGyroBias(const Common::Vec3f& bias);
void SetGyroThreshold(f32 threshold);
/// Applies a modifier on top of the normal gyro threshold
void SetUserGyroThreshold(f32 threshold);
void EnableReset(bool reset);
void ResetRotations();
void ResetQuaternion();
void UpdateRotation(u64 elapsed_time);
void UpdateOrientation(u64 elapsed_time);
@@ -73,7 +57,7 @@ private:
Common::Vec3f derivative_error;
// Quaternion containing the device orientation
Common::Quaternion<f32> quat;
Common::Quaternion<f32> quat{{0.0f, 0.0f, -1.0f}, 0.0f};
// Number of full rotations in each axis
Common::Vec3f rotations;
@@ -90,9 +74,6 @@ private:
// Minimum gyro amplitude to detect if the device is moving
f32 gyro_threshold = 0.0f;
// Multiplies gyro_threshold by this value
f32 user_gyro_threshold = 0.0f;
// Number of invalid sequential data
u32 reset_counter = 0;
+1 -1
View File
@@ -148,7 +148,7 @@ public:
if (context->GetManager()->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
kernel.ApplicationProcess()->GetResourceLimit()->Reserve(
kernel.CurrentProcess()->GetResourceLimit()->Reserve(
Kernel::LimitableResource::SessionCountMax, 1);
auto* session = Kernel::KSession::Create(kernel);
@@ -16,7 +16,6 @@
#include "core/hle/kernel/k_event_info.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_object_name.h"
#include "core/hle/kernel/k_page_buffer.h"
#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/k_process.h"
@@ -50,7 +49,6 @@ namespace Kernel::Init {
HANDLER(KThreadLocalPage, \
(SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), \
##__VA_ARGS__) \
HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ##__VA_ARGS__) \
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ##__VA_ARGS__) \
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ##__VA_ARGS__) \
+1 -2
View File
@@ -60,8 +60,7 @@ bool KClientPort::IsSignaled() const {
Result KClientPort::CreateSession(KClientSession** out) {
// Reserve a new session from the resource limit.
//! FIXME: we are reserving this from the wrong resource limit!
KScopedResourceReservation session_reservation(kernel.ApplicationProcess()->GetResourceLimit(),
KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
LimitableResource::SessionCountMax);
R_UNLESS(session_reservation.Succeeded(), ResultLimitReached);
+4 -4
View File
@@ -21,7 +21,7 @@ KCodeMemory::KCodeMemory(KernelCore& kernel_)
Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, size_t size) {
// Set members.
m_owner = GetCurrentProcessPointer(kernel);
m_owner = kernel.CurrentProcess();
// Get the owner page table.
auto& page_table = m_owner->PageTable();
@@ -74,7 +74,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) {
R_UNLESS(!m_is_mapped, ResultInvalidState);
// Map the memory.
R_TRY(GetCurrentProcess(kernel).PageTable().MapPageGroup(
R_TRY(kernel.CurrentProcess()->PageTable().MapPageGroup(
address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite));
// Mark ourselves as mapped.
@@ -91,8 +91,8 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) {
KScopedLightLock lk(m_lock);
// Unmap the memory.
R_TRY(GetCurrentProcess(kernel).PageTable().UnmapPageGroup(address, *m_page_group,
KMemoryState::CodeOut));
R_TRY(kernel.CurrentProcess()->PageTable().UnmapPageGroup(address, *m_page_group,
KMemoryState::CodeOut));
// Mark ourselves as unmapped.
m_is_mapped = false;
+4 -4
View File
@@ -164,8 +164,8 @@ Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value)
R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask));
// Get the lock owner thread.
owner_thread = GetCurrentProcess(kernel)
.GetHandleTable()
owner_thread = kernel.CurrentProcess()
->GetHandleTable()
.GetObjectWithoutPseudoHandle<KThread>(handle)
.ReleasePointerUnsafe();
R_UNLESS(owner_thread != nullptr, ResultInvalidHandle);
@@ -213,8 +213,8 @@ void KConditionVariable::SignalImpl(KThread* thread) {
thread->EndWait(ResultSuccess);
} else {
// Get the previous owner.
KThread* owner_thread = GetCurrentProcess(kernel)
.GetHandleTable()
KThread* owner_thread = kernel.CurrentProcess()
->GetHandleTable()
.GetObjectWithoutPseudoHandle<KThread>(
static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
.ReleasePointerUnsafe();
+1 -2
View File
@@ -90,8 +90,7 @@ public:
// Handle pseudo-handles.
if constexpr (std::derived_from<KProcess, T>) {
if (handle == Svc::PseudoHandle::CurrentProcess) {
//! FIXME: this is the wrong process!
auto* const cur_process = m_kernel.ApplicationProcess();
auto* const cur_process = m_kernel.CurrentProcess();
ASSERT(cur_process != nullptr);
return cur_process;
}
+1 -1
View File
@@ -16,7 +16,7 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) {
auto& current_thread = GetCurrentThread(kernel);
if (auto* process = GetCurrentProcessPointer(kernel); process) {
if (auto* process = kernel.CurrentProcess(); process) {
// If the user disable count is set, we may need to pin the current thread.
if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) {
KScopedSchedulerLock sl{kernel};
-102
View File
@@ -1,102 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/k_object_name.h"
namespace Kernel {
KObjectNameGlobalData::KObjectNameGlobalData(KernelCore& kernel) : m_object_list_lock{kernel} {}
KObjectNameGlobalData::~KObjectNameGlobalData() = default;
void KObjectName::Initialize(KAutoObject* obj, const char* name) {
// Set member variables.
m_object = obj;
std::strncpy(m_name.data(), name, sizeof(m_name) - 1);
m_name[sizeof(m_name) - 1] = '\x00';
// Open a reference to the object we hold.
m_object->Open();
}
bool KObjectName::MatchesName(const char* name) const {
return std::strncmp(m_name.data(), name, sizeof(m_name)) == 0;
}
Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name) {
// Create a new object name.
KObjectName* new_name = KObjectName::Allocate(kernel);
R_UNLESS(new_name != nullptr, ResultOutOfResource);
// Initialize the new name.
new_name->Initialize(obj, name);
// Check if there's an existing name.
{
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Ensure we have exclusive access to the global list.
KScopedLightLock lk{gd.GetObjectListLock()};
// If the object doesn't exist, put it into the list.
KScopedAutoObject existing_object = FindImpl(kernel, name);
if (existing_object.IsNull()) {
gd.GetObjectList().push_back(*new_name);
R_SUCCEED();
}
}
// The object already exists, which is an error condition. Perform cleanup.
obj->Close();
KObjectName::Free(kernel, new_name);
R_THROW(ResultInvalidState);
}
Result KObjectName::Delete(KernelCore& kernel, KAutoObject* obj, const char* compare_name) {
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Ensure we have exclusive access to the global list.
KScopedLightLock lk{gd.GetObjectListLock()};
// Find a matching entry in the list, and delete it.
for (auto& name : gd.GetObjectList()) {
if (name.MatchesName(compare_name) && obj == name.GetObject()) {
// We found a match, clean up its resources.
obj->Close();
gd.GetObjectList().erase(gd.GetObjectList().iterator_to(name));
KObjectName::Free(kernel, std::addressof(name));
R_SUCCEED();
}
}
// We didn't find the object in the list.
R_THROW(ResultNotFound);
}
KScopedAutoObject<KAutoObject> KObjectName::Find(KernelCore& kernel, const char* name) {
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Ensure we have exclusive access to the global list.
KScopedLightLock lk{gd.GetObjectListLock()};
return FindImpl(kernel, name);
}
KScopedAutoObject<KAutoObject> KObjectName::FindImpl(KernelCore& kernel, const char* compare_name) {
// Get the global data.
KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()};
// Try to find a matching object in the global list.
for (const auto& name : gd.GetObjectList()) {
if (name.MatchesName(compare_name)) {
return name.GetObject();
}
}
// There's no matching entry in the list.
return nullptr;
}
} // namespace Kernel
-86
View File
@@ -1,86 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <memory>
#include <boost/intrusive/list.hpp>
#include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel {
class KObjectNameGlobalData;
class KObjectName : public KSlabAllocated<KObjectName>, public boost::intrusive::list_base_hook<> {
public:
explicit KObjectName(KernelCore&) {}
virtual ~KObjectName() = default;
static constexpr size_t NameLengthMax = 12;
using List = boost::intrusive::list<KObjectName>;
static Result NewFromName(KernelCore& kernel, KAutoObject* obj, const char* name);
static Result Delete(KernelCore& kernel, KAutoObject* obj, const char* name);
static KScopedAutoObject<KAutoObject> Find(KernelCore& kernel, const char* name);
template <typename Derived>
static Result Delete(KernelCore& kernel, const char* name) {
// Find the object.
KScopedAutoObject obj = Find(kernel, name);
R_UNLESS(obj.IsNotNull(), ResultNotFound);
// Cast the object to the desired type.
Derived* derived = obj->DynamicCast<Derived*>();
R_UNLESS(derived != nullptr, ResultNotFound);
// Check that the object is closed.
R_UNLESS(derived->IsServerClosed(), ResultInvalidState);
return Delete(kernel, obj.GetPointerUnsafe(), name);
}
template <typename Derived>
requires(std::derived_from<Derived, KAutoObject>)
static KScopedAutoObject<Derived> Find(KernelCore& kernel, const char* name) {
return Find(kernel, name);
}
private:
static KScopedAutoObject<KAutoObject> FindImpl(KernelCore& kernel, const char* name);
void Initialize(KAutoObject* obj, const char* name);
bool MatchesName(const char* name) const;
KAutoObject* GetObject() const {
return m_object;
}
private:
std::array<char, NameLengthMax> m_name{};
KAutoObject* m_object{};
};
class KObjectNameGlobalData {
public:
explicit KObjectNameGlobalData(KernelCore& kernel);
~KObjectNameGlobalData();
KLightLock& GetObjectListLock() {
return m_object_list_lock;
}
KObjectName::List& GetObjectList() {
return m_object_list;
}
private:
KLightLock m_object_list_lock;
KObjectName::List m_object_list;
};
} // namespace Kernel
+1 -1
View File
@@ -370,7 +370,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
// Initialize proces address space
if (const Result result{page_table.InitializeForProcess(
metadata.GetAddressSpaceType(), false, false, false, KMemoryManager::Pool::Application,
0x8000000, code_size, &kernel.GetAppSystemResource(), resource_limit)};
0x8000000, code_size, &kernel.GetSystemSystemResource(), resource_limit)};
result.IsError()) {
R_RETURN(result);
}
+7 -7
View File
@@ -328,7 +328,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
}
void KScheduler::SwitchThread(KThread* next_thread) {
KProcess* const cur_process = GetCurrentProcessPointer(kernel);
KProcess* const cur_process = kernel.CurrentProcess();
KThread* const cur_thread = GetCurrentThreadPointer(kernel);
// We never want to schedule a null thread, so use the idle thread if we don't have a next.
@@ -689,11 +689,11 @@ void KScheduler::RotateScheduledQueue(KernelCore& kernel, s32 core_id, s32 prior
void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
// Validate preconditions.
ASSERT(CanSchedule(kernel));
ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
ASSERT(kernel.CurrentProcess() != nullptr);
// Get the current thread and process.
KThread& cur_thread = GetCurrentThread(kernel);
KProcess& cur_process = GetCurrentProcess(kernel);
KProcess& cur_process = *kernel.CurrentProcess();
// If the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@@ -728,11 +728,11 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) {
void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
// Validate preconditions.
ASSERT(CanSchedule(kernel));
ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
ASSERT(kernel.CurrentProcess() != nullptr);
// Get the current thread and process.
KThread& cur_thread = GetCurrentThread(kernel);
KProcess& cur_process = GetCurrentProcess(kernel);
KProcess& cur_process = *kernel.CurrentProcess();
// If the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@@ -816,11 +816,11 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
void KScheduler::YieldToAnyThread(KernelCore& kernel) {
// Validate preconditions.
ASSERT(CanSchedule(kernel));
ASSERT(GetCurrentProcessPointer(kernel) != nullptr);
ASSERT(kernel.CurrentProcess() != nullptr);
// Get the current thread and process.
KThread& cur_thread = GetCurrentThread(kernel);
KProcess& cur_process = GetCurrentProcess(kernel);
KProcess& cur_process = *kernel.CurrentProcess();
// If the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
+1 -2
View File
@@ -33,8 +33,7 @@ void KSession::Initialize(KClientPort* port_, const std::string& name_) {
name = name_;
// Set our owner process.
//! FIXME: this is the wrong process!
process = kernel.ApplicationProcess();
process = kernel.CurrentProcess();
process->Open();
// Set our port.
-8
View File
@@ -1266,14 +1266,6 @@ KThread& GetCurrentThread(KernelCore& kernel) {
return *GetCurrentThreadPointer(kernel);
}
KProcess* GetCurrentProcessPointer(KernelCore& kernel) {
return GetCurrentThread(kernel).GetOwnerProcess();
}
KProcess& GetCurrentProcess(KernelCore& kernel) {
return *GetCurrentProcessPointer(kernel);
}
s32 GetCurrentCoreId(KernelCore& kernel) {
return GetCurrentThread(kernel).GetCurrentCore();
}
-2
View File
@@ -110,8 +110,6 @@ enum class StepState : u32 {
void SetCurrentThread(KernelCore& kernel, KThread* thread);
[[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel);
[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
[[nodiscard]] KProcess* GetCurrentProcessPointer(KernelCore& kernel);
[[nodiscard]] KProcess& GetCurrentProcess(KernelCore& kernel);
[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>,
+1 -1
View File
@@ -16,7 +16,7 @@ KTransferMemory::~KTransferMemory() = default;
Result KTransferMemory::Initialize(VAddr address_, std::size_t size_,
Svc::MemoryPermission owner_perm_) {
// Set members.
owner = GetCurrentProcessPointer(kernel);
owner = kernel.CurrentProcess();
// TODO(bunnei): Lock for transfer memory
+49 -62
View File
@@ -29,7 +29,6 @@
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_object_name.h"
#include "core/hle/kernel/k_page_buffer.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
@@ -85,7 +84,6 @@ struct KernelCore::Impl {
InitializeShutdownThreads();
InitializePhysicalCores();
InitializePreemption(kernel);
InitializeGlobalData(kernel);
// Initialize the Dynamic Slab Heaps.
{
@@ -104,13 +102,13 @@ struct KernelCore::Impl {
void InitializeCores() {
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
cores[core_id]->Initialize((*application_process).Is64BitProcess());
system.Memory().SetCurrentPageTable(*application_process, core_id);
cores[core_id]->Initialize((*current_process).Is64BitProcess());
system.Memory().SetCurrentPageTable(*current_process, core_id);
}
}
void CloseApplicationProcess() {
KProcess* old_process = application_process.exchange(nullptr);
void CloseCurrentProcess() {
KProcess* old_process = current_process.exchange(nullptr);
if (old_process == nullptr) {
return;
}
@@ -184,7 +182,7 @@ struct KernelCore::Impl {
}
}
CloseApplicationProcess();
CloseCurrentProcess();
// Track kernel objects that were not freed on shutdown
{
@@ -196,8 +194,6 @@ struct KernelCore::Impl {
}
}
object_name_global_data.reset();
// Ensure that the object list container is finalized and properly shutdown.
global_object_list_container->Finalize();
global_object_list_container.reset();
@@ -367,29 +363,27 @@ struct KernelCore::Impl {
}
}
void InitializeGlobalData(KernelCore& kernel) {
object_name_global_data = std::make_unique<KObjectNameGlobalData>(kernel);
void MakeCurrentProcess(KProcess* process) {
current_process = process;
}
void MakeApplicationProcess(KProcess* process) {
application_process = process;
}
static inline thread_local u32 host_thread_id = UINT32_MAX;
static inline thread_local u8 host_thread_id = UINT8_MAX;
/// Sets the host thread ID for the caller.
u32 SetHostThreadId(std::size_t core_id) {
// This should only be called during core init.
ASSERT(host_thread_id == UINT8_MAX);
// The first four slots are reserved for CPU core threads
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u8>(core_id);
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
u32 GetHostThreadId(std::size_t core_id) {
if (host_thread_id == UINT32_MAX) {
// The first four slots are reserved for CPU core threads
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u32>(core_id);
}
return host_thread_id;
}
/// Gets the host thread ID for the caller
u32 GetHostThreadId() const {
/// Gets the host thread ID for the caller, allocating a new one if this is the first time
u32 GetHostThreadId() {
if (host_thread_id == UINT32_MAX) {
host_thread_id = next_host_thread_id++;
}
return host_thread_id;
}
@@ -397,19 +391,23 @@ struct KernelCore::Impl {
KThread* GetHostDummyThread(KThread* existing_thread) {
auto initialize = [this](KThread* thread) {
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
thread->SetName(fmt::format("DummyThread:{}", next_host_thread_id++));
thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId()));
return thread;
};
thread_local KThread raw_thread{system.Kernel()};
thread_local KThread* thread = existing_thread ? existing_thread : initialize(&raw_thread);
thread_local KThread* thread = nullptr;
if (thread == nullptr) {
thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread;
}
return thread;
}
/// Registers a CPU core thread by allocating a host thread ID for it
void RegisterCoreThread(std::size_t core_id) {
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
const auto this_id = SetHostThreadId(core_id);
const auto this_id = GetHostThreadId(core_id);
if (!is_multicore) {
single_core_thread_id = this_id;
}
@@ -417,6 +415,7 @@ struct KernelCore::Impl {
/// Registers a new host thread by allocating a host thread ID for it
void RegisterHostThread(KThread* existing_thread) {
[[maybe_unused]] const auto this_id = GetHostThreadId();
[[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread);
}
@@ -446,9 +445,11 @@ struct KernelCore::Impl {
static inline thread_local KThread* current_thread{nullptr};
KThread* GetCurrentEmuThread() {
if (!current_thread) {
current_thread = GetHostDummyThread(nullptr);
const auto thread_id = GetCurrentHostThreadID();
if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
return GetHostDummyThread(nullptr);
}
return current_thread;
}
@@ -820,7 +821,7 @@ struct KernelCore::Impl {
// Lists all processes that exist in the current session.
std::vector<KProcess*> process_list;
std::atomic<KProcess*> application_process{};
std::atomic<KProcess*> current_process{};
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
std::unique_ptr<Kernel::KHardwareTimer> hardware_timer;
@@ -837,8 +838,6 @@ struct KernelCore::Impl {
std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container;
std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
/// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC.
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
@@ -942,20 +941,20 @@ void KernelCore::AppendNewProcess(KProcess* process) {
impl->process_list.push_back(process);
}
void KernelCore::MakeApplicationProcess(KProcess* process) {
impl->MakeApplicationProcess(process);
void KernelCore::MakeCurrentProcess(KProcess* process) {
impl->MakeCurrentProcess(process);
}
KProcess* KernelCore::ApplicationProcess() {
return impl->application_process;
KProcess* KernelCore::CurrentProcess() {
return impl->current_process;
}
const KProcess* KernelCore::ApplicationProcess() const {
return impl->application_process;
const KProcess* KernelCore::CurrentProcess() const {
return impl->current_process;
}
void KernelCore::CloseApplicationProcess() {
impl->CloseApplicationProcess();
void KernelCore::CloseCurrentProcess() {
impl->CloseCurrentProcess();
}
const std::vector<KProcess*>& KernelCore::GetProcessList() const {
@@ -1003,7 +1002,7 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
}
Kernel::KScheduler* KernelCore::CurrentScheduler() {
const u32 core_id = impl->GetCurrentHostThreadID();
u32 core_id = impl->GetCurrentHostThreadID();
if (core_id >= Core::Hardware::NUM_CPU_CORES) {
// This is expected when called from not a guest thread
return {};
@@ -1139,10 +1138,6 @@ void KernelCore::SetCurrentEmuThread(KThread* thread) {
impl->SetCurrentEmuThread(thread);
}
KObjectNameGlobalData& KernelCore::ObjectNameGlobalData() {
return *impl->object_name_global_data;
}
KMemoryManager& KernelCore::MemoryManager() {
return *impl->memory_manager;
}
@@ -1151,14 +1146,6 @@ const KMemoryManager& KernelCore::MemoryManager() const {
return *impl->memory_manager;
}
KSystemResource& KernelCore::GetAppSystemResource() {
return *impl->app_system_resource;
}
const KSystemResource& KernelCore::GetAppSystemResource() const {
return *impl->app_system_resource;
}
KSystemResource& KernelCore::GetSystemSystemResource() {
return *impl->sys_system_resource;
}
@@ -1207,12 +1194,12 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const {
return *impl->hidbus_shared_mem;
}
void KernelCore::SuspendApplication(bool suspended) {
void KernelCore::Suspend(bool suspended) {
const bool should_suspend{exception_exited || suspended};
const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
// Get the application process.
KScopedAutoObject<KProcess> process = ApplicationProcess();
//! This refers to the application process, not the current process.
KScopedAutoObject<KProcess> process = CurrentProcess();
if (process.IsNull()) {
return;
}
@@ -1223,8 +1210,8 @@ void KernelCore::SuspendApplication(bool suspended) {
// Wait for process execution to stop.
bool must_wait{should_suspend};
// KernelCore::SuspendApplication must be called from locked context,
// or we could race another call to SetActivity, interfering with waiting.
// KernelCore::Suspend must be called from locked context, or we
// could race another call to SetActivity, interfering with waiting.
while (must_wait) {
KScopedSchedulerLock sl{*this};
@@ -1258,9 +1245,9 @@ bool KernelCore::IsShuttingDown() const {
return impl->IsShuttingDown();
}
void KernelCore::ExceptionalExitApplication() {
void KernelCore::ExceptionalExit() {
exception_exited = true;
SuspendApplication(true);
Suspend(true);
}
void KernelCore::EnterSVCProfile() {
+12 -26
View File
@@ -44,8 +44,6 @@ class KHardwareTimer;
class KLinkedListNode;
class KMemoryLayout;
class KMemoryManager;
class KObjectName;
class KObjectNameGlobalData;
class KPageBuffer;
class KPageBufferSlabHeap;
class KPort;
@@ -133,17 +131,17 @@ public:
/// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(KProcess* process);
/// Makes the given process the new application process.
void MakeApplicationProcess(KProcess* process);
/// Makes the given process the new current process.
void MakeCurrentProcess(KProcess* process);
/// Retrieves a pointer to the application process.
KProcess* ApplicationProcess();
/// Retrieves a pointer to the current process.
KProcess* CurrentProcess();
/// Retrieves a const pointer to the application process.
const KProcess* ApplicationProcess() const;
/// Retrieves a const pointer to the current process.
const KProcess* CurrentProcess() const;
/// Closes the application process.
void CloseApplicationProcess();
/// Closes the current process.
void CloseCurrentProcess();
/// Retrieves the list of processes.
const std::vector<KProcess*>& GetProcessList() const;
@@ -242,21 +240,12 @@ public:
/// Register the current thread as a non CPU core thread.
void RegisterHostThread(KThread* existing_thread = nullptr);
/// Gets global data for KObjectName.
KObjectNameGlobalData& ObjectNameGlobalData();
/// Gets the virtual memory manager for the kernel.
KMemoryManager& MemoryManager();
/// Gets the virtual memory manager for the kernel.
const KMemoryManager& MemoryManager() const;
/// Gets the application resource manager.
KSystemResource& GetAppSystemResource();
/// Gets the application resource manager.
const KSystemResource& GetAppSystemResource() const;
/// Gets the system resource manager.
KSystemResource& GetSystemSystemResource();
@@ -293,11 +282,11 @@ public:
/// Gets the shared memory object for HIDBus services.
const Kernel::KSharedMemory& GetHidBusSharedMem() const;
/// Suspend/unsuspend application process.
void SuspendApplication(bool suspend);
/// Suspend/unsuspend all processes.
void Suspend(bool suspend);
/// Exceptional exit application process.
void ExceptionalExitApplication();
/// Exceptional exit all processes.
void ExceptionalExit();
/// Notify emulated CPU cores to shut down.
void ShutdownCores();
@@ -377,8 +366,6 @@ public:
return slab_heap_container->page_buffer;
} else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
return slab_heap_container->thread_local_page;
} else if constexpr (std::is_same_v<T, KObjectName>) {
return slab_heap_container->object_name;
} else if constexpr (std::is_same_v<T, KSessionRequest>) {
return slab_heap_container->session_request;
} else if constexpr (std::is_same_v<T, KSecureSystemResource>) {
@@ -450,7 +437,6 @@ private:
KSlabHeap<KDeviceAddressSpace> device_address_space;
KSlabHeap<KPageBuffer> page_buffer;
KSlabHeap<KThreadLocalPage> thread_local_page;
KSlabHeap<KObjectName> object_name;
KSlabHeap<KSessionRequest> session_request;
KSlabHeap<KSecureSystemResource> secure_system_resource;
KSlabHeap<KEventInfo> event_info;
+423 -4409
View File
File diff suppressed because it is too large Load Diff
+148 -512
View File
@@ -1,536 +1,172 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// This file is automatically generated using svc_generator.py.
#pragma once
namespace Core {
class System;
}
#include "common/common_types.h"
#include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h"
namespace Core {
class System;
}
namespace Kernel::Svc {
// clang-format off
Result SetHeapSize(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
Result MapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapMemory(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result QueryMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
void Call(Core::System& system, u32 immediate);
Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size);
Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, MemoryPermission perm);
Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mask, u32 attr);
Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size);
Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size);
Result QueryMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address,
VAddr query_address);
void ExitProcess(Core::System& system);
Result CreateThread(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
Result CreateThread(Core::System& system, Handle* out_handle, VAddr entry_point, u64 arg,
VAddr stack_bottom, u32 priority, s32 core_id);
Result StartThread(Core::System& system, Handle thread_handle);
void ExitThread(Core::System& system);
void SleepThread(Core::System& system, int64_t ns);
Result GetThreadPriority(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber(Core::System& system);
void SleepThread(Core::System& system, s64 nanoseconds);
Result GetThreadPriority(Core::System& system, u32* out_priority, Handle handle);
Result SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority);
Result GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id,
u64* out_affinity_mask);
Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id,
u64 affinity_mask);
u32 GetCurrentProcessorNumber(Core::System& system);
Result SignalEvent(Core::System& system, Handle event_handle);
Result ClearEvent(Core::System& system, Handle event_handle);
Result MapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
Result CreateTransferMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size,
MemoryPermission map_perm);
Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, u64 size);
Result CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size,
MemoryPermission map_perm);
Result CloseHandle(Core::System& system, Handle handle);
Result ResetSignal(Core::System& system, Handle handle);
Result WaitSynchronization(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
Result WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, s32 num_handles,
s64 nano_seconds);
Result CancelSynchronization(Core::System& system, Handle handle);
Result ArbitrateLock(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
Result ArbitrateUnlock(Core::System& system, uint64_t address);
Result WaitProcessWideKeyAtomic(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey(Core::System& system, uint64_t cv_key, int32_t count);
int64_t GetSystemTick(Core::System& system);
Result ConnectToNamedPort(Core::System& system, Handle* out_handle, uint64_t name);
Result SendSyncRequest(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result GetProcessId(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
Result OutputDebugString(Core::System& system, uint64_t debug_str, uint64_t len);
void ReturnFromException(Core::System& system, Result result);
Result GetInfo(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache(Core::System& system);
Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size);
Result MapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemory(Core::System& system, uint64_t address, uint64_t size);
Result GetDebugFutureThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext3(Core::System& system, uint64_t out_context, Handle thread_handle);
Result WaitForAddress(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address, u32 tag);
Result ArbitrateUnlock(Core::System& system, VAddr address);
Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_key, u32 tag,
s64 timeout_ns);
void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count);
u64 GetSystemTick(Core::System& system);
Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address);
Result SendSyncRequest(Core::System& system, Handle handle);
Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle);
Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle);
void Break(Core::System& system, u32 reason, u64 info1, u64 info2);
void OutputDebugString(Core::System& system, VAddr address, u64 len);
Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u64 info_sub_id);
Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size);
Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size);
Result GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value,
Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value,
Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity);
Result GetThreadContext(Core::System& system, VAddr out_context, Handle thread_handle);
Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
s64 timeout_ns);
Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_type, s32 value,
s32 count);
void SynchronizePreemptionState(Core::System& system);
Result GetResourceLimitPeakValue(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
Result AcceptSession(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result CreateEvent(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
Result UnmapIoRegion(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size);
Result SetUnsafeLimit(Core::System& system, uint64_t limit);
Result CreateCodeMemory(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem(Core::System& system);
Result ReadWriteRegister(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
Result CreateInterruptEvent(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
Result CreateDeviceAddressSpace(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess(Core::System& system, Handle debug_handle);
Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle);
Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
Result GetProcessList(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
Result GetThreadList(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result UnmapProcessMemory(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess(Core::System& system, Handle process_handle);
Result GetProcessInfo(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
void KernelDebug(Core::System& system, u32 kernel_debug_type, u64 param1, u64 param2, u64 param3);
void ChangeKernelTraceState(Core::System& system, u32 trace_state);
Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u32 is_light,
u64 name);
Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s32 num_handles,
Handle reply_target, s64 timeout_ns);
Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read);
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size);
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation,
VAddr address, size_t size, MemoryPermission perm);
Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids,
u32 out_process_ids_size);
Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids,
u32 out_thread_ids_size, Handle debug_handle);
Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, VAddr address,
u64 size, MemoryPermission perm);
Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle,
VAddr src_address, u64 size);
Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle process_handle,
VAddr src_address, u64 size);
Result QueryProcessMemory(Core::System& system, VAddr memory_info_address, VAddr page_info_address,
Handle process_handle, VAddr address);
Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address,
u64 src_address, u64 size);
Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address,
u64 src_address, u64 size);
Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type);
Result CreateResourceLimit(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size);
Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle,
LimitableResource which, u64 limit_value);
Result SetHeapSize64From32(Core::System& system, uint64_t* out_address, uint32_t size);
Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size, MemoryPermission perm);
Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size, uint32_t mask, uint32_t attr);
Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address, uint32_t size);
Result QueryMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, uint32_t address);
void ExitProcess64From32(Core::System& system);
Result CreateThread64From32(Core::System& system, Handle* out_handle, uint32_t func, uint32_t arg, uint32_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread64From32(Core::System& system, Handle thread_handle);
void ExitThread64From32(Core::System& system);
void SleepThread64From32(Core::System& system, int64_t ns);
Result GetThreadPriority64From32(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority64From32(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask64From32(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask64From32(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber64From32(Core::System& system);
Result SignalEvent64From32(Core::System& system, Handle event_handle);
Result ClearEvent64From32(Core::System& system, Handle event_handle);
Result MapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
Result UnmapSharedMemory64From32(Core::System& system, Handle shmem_handle, uint32_t address, uint32_t size);
Result CreateTransferMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size, MemoryPermission map_perm);
Result CloseHandle64From32(Core::System& system, Handle handle);
Result ResetSignal64From32(Core::System& system, Handle handle);
Result WaitSynchronization64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization64From32(Core::System& system, Handle handle);
Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address, uint32_t tag);
Result ArbitrateUnlock64From32(Core::System& system, uint32_t address);
Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count);
int64_t GetSystemTick64From32(Core::System& system);
Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name);
Result SendSyncRequest64From32(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle, uint32_t message_buffer, uint32_t message_buffer_size, Handle session_handle);
Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId64From32(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size);
Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len);
void ReturnFromException64From32(Core::System& system, Result result);
Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache64From32(Core::System& system);
Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size);
Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result GetDebugFutureThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo64From32(Core::System& system, ilp32::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue64From32(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue64From32(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity64From32(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext364From32(Core::System& system, uint32_t out_context, Handle thread_handle);
Result WaitForAddress64From32(Core::System& system, uint32_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress64From32(Core::System& system, uint32_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState64From32(Core::System& system);
Result GetResourceLimitPeakValue64From32(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint32_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession64From32(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint32_t name);
Result AcceptSession64From32(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index, uint32_t message_buffer, uint32_t message_buffer_size, uint32_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result CreateEvent64From32(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size, MemoryPermission perm);
Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size);
Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size);
Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit);
Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address, uint32_t size);
Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem64From32(Core::System& system);
Result ReadWriteRegister64From32(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity64From32(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory64From32(Core::System& system, Handle* out_handle, uint32_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory64From32(Core::System& system, Handle trmem_handle, uint32_t address, uint32_t size);
Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info, uint32_t address);
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint32_t size);
Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint32_t size, uint64_t device_address);
Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle);
Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle);
Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags, uint32_t thread_ids, int32_t num_thread_ids);
Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes, uint32_t out_process_ids, int32_t max_out_count);
Result GetThreadList64From32(Core::System& system, int32_t* out_num_threads, uint32_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id, uint32_t context, uint32_t context_flags);
Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint32_t address);
Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle, uint32_t address, uint32_t size);
Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer, uint32_t address, uint32_t size);
Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort64From32(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint32_t name);
Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name, int32_t max_sessions);
Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle, uint64_t src_address, uint32_t size);
Result QueryProcessMemory64From32(Core::System& system, uint32_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters, uint32_t caps, int32_t num_caps);
Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess64From32(Core::System& system, Handle process_handle);
Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit64From32(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue64From32(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size);
//
Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size);
Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size, MemoryPermission perm);
Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask, uint32_t attr);
Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result QueryMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, uint64_t address);
void ExitProcess64(Core::System& system);
Result CreateThread64(Core::System& system, Handle* out_handle, uint64_t func, uint64_t arg, uint64_t stack_bottom, int32_t priority, int32_t core_id);
Result StartThread64(Core::System& system, Handle thread_handle);
void ExitThread64(Core::System& system);
void SleepThread64(Core::System& system, int64_t ns);
Result GetThreadPriority64(Core::System& system, int32_t* out_priority, Handle thread_handle);
Result SetThreadPriority64(Core::System& system, Handle thread_handle, int32_t priority);
Result GetThreadCoreMask64(Core::System& system, int32_t* out_core_id, uint64_t* out_affinity_mask, Handle thread_handle);
Result SetThreadCoreMask64(Core::System& system, Handle thread_handle, int32_t core_id, uint64_t affinity_mask);
int32_t GetCurrentProcessorNumber64(Core::System& system);
Result SignalEvent64(Core::System& system, Handle event_handle);
Result ClearEvent64(Core::System& system, Handle event_handle);
Result MapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result UnmapSharedMemory64(Core::System& system, Handle shmem_handle, uint64_t address, uint64_t size);
Result CreateTransferMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size, MemoryPermission map_perm);
Result CloseHandle64(Core::System& system, Handle handle);
Result ResetSignal64(Core::System& system, Handle handle);
Result WaitSynchronization64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, int64_t timeout_ns);
Result CancelSynchronization64(Core::System& system, Handle handle);
Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag);
Result ArbitrateUnlock64(Core::System& system, uint64_t address);
Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key, uint32_t tag, int64_t timeout_ns);
void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count);
int64_t GetSystemTick64(Core::System& system);
Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name);
Result SendSyncRequest64(Core::System& system, Handle session_handle);
Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle, uint64_t message_buffer, uint64_t message_buffer_size, Handle session_handle);
Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle);
Result GetThreadId64(Core::System& system, uint64_t* out_thread_id, Handle thread_handle);
void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size);
Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len);
void ReturnFromException64(Core::System& system, Result result);
Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle, uint64_t info_subtype);
void FlushEntireDataCache64(Core::System& system);
Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size);
Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size);
Result GetDebugFutureThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_thread_id, Handle debug_handle, int64_t ns);
Result GetLastThreadInfo64(Core::System& system, lp64::LastThreadContext* out_context, uint64_t* out_tls_address, uint32_t* out_flags);
Result GetResourceLimitLimitValue64(Core::System& system, int64_t* out_limit_value, Handle resource_limit_handle, LimitableResource which);
Result GetResourceLimitCurrentValue64(Core::System& system, int64_t* out_current_value, Handle resource_limit_handle, LimitableResource which);
Result SetThreadActivity64(Core::System& system, Handle thread_handle, ThreadActivity thread_activity);
Result GetThreadContext364(Core::System& system, uint64_t out_context, Handle thread_handle);
Result WaitForAddress64(Core::System& system, uint64_t address, ArbitrationType arb_type, int32_t value, int64_t timeout_ns);
Result SignalToAddress64(Core::System& system, uint64_t address, SignalType signal_type, int32_t value, int32_t count);
void SynchronizePreemptionState64(Core::System& system);
Result GetResourceLimitPeakValue64(Core::System& system, int64_t* out_peak_value, Handle resource_limit_handle, LimitableResource which);
Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType which);
Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool, uint64_t physical_address, uint64_t size, MemoryMapping mapping, MemoryPermission perm);
void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0, uint64_t arg1, uint64_t arg2);
void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state);
Result CreateSession64(Core::System& system, Handle* out_server_session_handle, Handle* out_client_session_handle, bool is_light, uint64_t name);
Result AcceptSession64(Core::System& system, Handle* out_handle, Handle port);
Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index, uint64_t message_buffer, uint64_t message_buffer_size, uint64_t handles, int32_t num_handles, Handle reply_target, int64_t timeout_ns);
Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle);
Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size, MemoryPermission perm);
Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size);
Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size);
Result SetUnsafeLimit64(Core::System& system, uint64_t limit);
Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address, uint64_t size);
Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle, CodeMemoryOperation operation, uint64_t address, uint64_t size, MemoryPermission perm);
void SleepSystem64(Core::System& system);
Result ReadWriteRegister64(Core::System& system, uint32_t* out_value, uint64_t address, uint32_t mask, uint32_t value);
Result SetProcessActivity64(Core::System& system, Handle process_handle, ProcessActivity process_activity);
Result CreateSharedMemory64(Core::System& system, Handle* out_handle, uint64_t size, MemoryPermission owner_perm, MemoryPermission remote_perm);
Result MapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size, MemoryPermission owner_perm);
Result UnmapTransferMemory64(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size);
Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id, InterruptType interrupt_type);
Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info, uint64_t address);
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size, uint64_t physical_address, uint64_t size);
Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address, uint64_t das_size);
Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle);
Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address, uint32_t option);
Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle, uint64_t process_address, uint64_t size, uint64_t device_address);
Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size);
Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id);
Result BreakDebugProcess64(Core::System& system, Handle debug_handle);
Result TerminateDebugProcess64(Core::System& system, Handle debug_handle);
Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle);
Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags, uint64_t thread_ids, int32_t num_thread_ids);
Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids, int32_t max_out_count);
Result GetThreadList64(Core::System& system, int32_t* out_num_threads, uint64_t out_thread_ids, int32_t max_out_count, Handle debug_handle);
Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle, uint64_t thread_id, uint32_t context_flags);
Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id, uint64_t context, uint32_t context_flags);
Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle, uint64_t address, uint64_t size);
Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer, uint64_t address, uint64_t size);
Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name, uint64_t flags, uint64_t value);
Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32, Handle debug_handle, uint64_t thread_id, DebugThreadParam param);
Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle, uint64_t info_subtype);
Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle, int32_t max_sessions, bool is_light, uint64_t name);
Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name, int32_t max_sessions);
Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port);
Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address, uint64_t size, MemoryPermission perm);
Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle, uint64_t src_address, uint64_t size);
Result QueryProcessMemory64(Core::System& system, uint64_t out_memory_info, PageInfo* out_page_info, Handle process_handle, uint64_t address);
Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address, uint64_t src_address, uint64_t size);
Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps, int32_t num_caps);
Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size);
Result TerminateProcess64(Core::System& system, Handle process_handle);
Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle, ProcessInfoType info_type);
Result CreateResourceLimit64(Core::System& system, Handle* out_handle);
Result SetResourceLimitLimitValue64(Core::System& system, Handle resource_limit_handle, LimitableResource which, int64_t limit_value);
Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size);
enum class SvcId : u32 {
SetHeapSize = 0x1,
SetMemoryPermission = 0x2,
SetMemoryAttribute = 0x3,
MapMemory = 0x4,
UnmapMemory = 0x5,
QueryMemory = 0x6,
ExitProcess = 0x7,
CreateThread = 0x8,
StartThread = 0x9,
ExitThread = 0xa,
SleepThread = 0xb,
GetThreadPriority = 0xc,
SetThreadPriority = 0xd,
GetThreadCoreMask = 0xe,
SetThreadCoreMask = 0xf,
GetCurrentProcessorNumber = 0x10,
SignalEvent = 0x11,
ClearEvent = 0x12,
MapSharedMemory = 0x13,
UnmapSharedMemory = 0x14,
CreateTransferMemory = 0x15,
CloseHandle = 0x16,
ResetSignal = 0x17,
WaitSynchronization = 0x18,
CancelSynchronization = 0x19,
ArbitrateLock = 0x1a,
ArbitrateUnlock = 0x1b,
WaitProcessWideKeyAtomic = 0x1c,
SignalProcessWideKey = 0x1d,
GetSystemTick = 0x1e,
ConnectToNamedPort = 0x1f,
SendSyncRequestLight = 0x20,
SendSyncRequest = 0x21,
SendSyncRequestWithUserBuffer = 0x22,
SendAsyncRequestWithUserBuffer = 0x23,
GetProcessId = 0x24,
GetThreadId = 0x25,
Break = 0x26,
OutputDebugString = 0x27,
ReturnFromException = 0x28,
GetInfo = 0x29,
FlushEntireDataCache = 0x2a,
FlushDataCache = 0x2b,
MapPhysicalMemory = 0x2c,
UnmapPhysicalMemory = 0x2d,
GetDebugFutureThreadInfo = 0x2e,
GetLastThreadInfo = 0x2f,
GetResourceLimitLimitValue = 0x30,
GetResourceLimitCurrentValue = 0x31,
SetThreadActivity = 0x32,
GetThreadContext3 = 0x33,
WaitForAddress = 0x34,
SignalToAddress = 0x35,
SynchronizePreemptionState = 0x36,
GetResourceLimitPeakValue = 0x37,
CreateIoPool = 0x39,
CreateIoRegion = 0x3a,
KernelDebug = 0x3c,
ChangeKernelTraceState = 0x3d,
CreateSession = 0x40,
AcceptSession = 0x41,
ReplyAndReceiveLight = 0x42,
ReplyAndReceive = 0x43,
ReplyAndReceiveWithUserBuffer = 0x44,
CreateEvent = 0x45,
MapIoRegion = 0x46,
UnmapIoRegion = 0x47,
MapPhysicalMemoryUnsafe = 0x48,
UnmapPhysicalMemoryUnsafe = 0x49,
SetUnsafeLimit = 0x4a,
CreateCodeMemory = 0x4b,
ControlCodeMemory = 0x4c,
SleepSystem = 0x4d,
ReadWriteRegister = 0x4e,
SetProcessActivity = 0x4f,
CreateSharedMemory = 0x50,
MapTransferMemory = 0x51,
UnmapTransferMemory = 0x52,
CreateInterruptEvent = 0x53,
QueryPhysicalAddress = 0x54,
QueryIoMapping = 0x55,
CreateDeviceAddressSpace = 0x56,
AttachDeviceAddressSpace = 0x57,
DetachDeviceAddressSpace = 0x58,
MapDeviceAddressSpaceByForce = 0x59,
MapDeviceAddressSpaceAligned = 0x5a,
UnmapDeviceAddressSpace = 0x5c,
InvalidateProcessDataCache = 0x5d,
StoreProcessDataCache = 0x5e,
FlushProcessDataCache = 0x5f,
DebugActiveProcess = 0x60,
BreakDebugProcess = 0x61,
TerminateDebugProcess = 0x62,
GetDebugEvent = 0x63,
ContinueDebugEvent = 0x64,
GetProcessList = 0x65,
GetThreadList = 0x66,
GetDebugThreadContext = 0x67,
SetDebugThreadContext = 0x68,
QueryDebugProcessMemory = 0x69,
ReadDebugProcessMemory = 0x6a,
WriteDebugProcessMemory = 0x6b,
SetHardwareBreakPoint = 0x6c,
GetDebugThreadParam = 0x6d,
GetSystemInfo = 0x6f,
CreatePort = 0x70,
ManageNamedPort = 0x71,
ConnectToPort = 0x72,
SetProcessMemoryPermission = 0x73,
MapProcessMemory = 0x74,
UnmapProcessMemory = 0x75,
QueryProcessMemory = 0x76,
MapProcessCodeMemory = 0x77,
UnmapProcessCodeMemory = 0x78,
CreateProcess = 0x79,
StartProcess = 0x7a,
TerminateProcess = 0x7b,
GetProcessInfo = 0x7c,
CreateResourceLimit = 0x7d,
SetResourceLimitLimitValue = 0x7e,
CallSecureMonitor = 0x7f,
MapInsecureMemory = 0x90,
UnmapInsecureMemory = 0x91,
};
// clang-format on
// Custom ABI.
Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args);
Result ReplyAndReceiveLight64(Core::System& system, Handle handle, uint32_t* args);
Result SendSyncRequestLight(Core::System& system, Handle session_handle, uint32_t* args);
Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, uint32_t* args);
Result SendSyncRequestLight64(Core::System& system, Handle session_handle, uint32_t* args);
void CallSecureMonitor(Core::System& system, lp64::SecureMonitorArguments* args);
void CallSecureMonitor64From32(Core::System& system, ilp32::SecureMonitorArguments* args);
void CallSecureMonitor64(Core::System& system, lp64::SecureMonitorArguments* args);
// Defined in svc_light_ipc.cpp.
void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system);
void SvcWrap_ReplyAndReceiveLight64(Core::System& system);
void SvcWrap_SendSyncRequestLight64From32(Core::System& system);
void SvcWrap_SendSyncRequestLight64(Core::System& system);
// Defined in svc_secure_monitor_call.cpp.
void SvcWrap_CallSecureMonitor64From32(Core::System& system);
void SvcWrap_CallSecureMonitor64(Core::System& system);
// Perform a supervisor call by index.
void Call(Core::System& system, u32 imm);
Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size);
Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, u32 attr);
Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size);
Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size);
Result QueryMemory32(Core::System& system, u32 memory_info_address, u32 page_info_address,
u32 query_address);
void ExitProcess32(Core::System& system);
Result CreateThread32(Core::System& system, Handle* out_handle, u32 priority, u32 entry_point,
u32 arg, u32 stack_top, s32 processor_id);
Result StartThread32(Core::System& system, Handle thread_handle);
void ExitThread32(Core::System& system);
void SleepThread32(Core::System& system, u32 nanoseconds_low, u32 nanoseconds_high);
Result GetThreadPriority32(Core::System& system, u32* out_priority, Handle handle);
Result SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority);
Result GetThreadCoreMask32(Core::System& system, Handle thread_handle, s32* out_core_id,
u32* out_affinity_mask_low, u32* out_affinity_mask_high);
Result SetThreadCoreMask32(Core::System& system, Handle thread_handle, s32 core_id,
u32 affinity_mask_low, u32 affinity_mask_high);
u32 GetCurrentProcessorNumber32(Core::System& system);
Result SignalEvent32(Core::System& system, Handle event_handle);
Result ClearEvent32(Core::System& system, Handle event_handle);
Result MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size,
MemoryPermission map_perm);
Result UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, u32 size);
Result CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size,
MemoryPermission map_perm);
Result CloseHandle32(Core::System& system, Handle handle);
Result ResetSignal32(Core::System& system, Handle handle);
Result WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address,
s32 num_handles, u32 timeout_high, s32* index);
Result CancelSynchronization32(Core::System& system, Handle handle);
Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag);
Result ArbitrateUnlock32(Core::System& system, u32 address);
Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag,
u32 timeout_ns_low, u32 timeout_ns_high);
void SignalProcessWideKey32(Core::System& system, u32 cv_key, s32 count);
void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high);
Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, u32 port_name_address);
Result SendSyncRequest32(Core::System& system, Handle handle);
Result GetProcessId32(Core::System& system, u32* out_process_id_low, u32* out_process_id_high,
Handle handle);
Result GetThreadId32(Core::System& system, u32* out_thread_id_low, u32* out_thread_id_high,
Handle thread_handle);
void Break32(Core::System& system, u32 reason, u32 info1, u32 info2);
void OutputDebugString32(Core::System& system, u32 address, u32 len);
Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low,
u32 info_id, u32 handle, u32 sub_id_high);
Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size);
Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size);
Result SetThreadActivity32(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity);
Result GetThreadContext32(Core::System& system, u32 out_context, Handle thread_handle);
Result WaitForAddress32(Core::System& system, u32 address, ArbitrationType arb_type, s32 value,
u32 timeout_ns_low, u32 timeout_ns_high);
Result SignalToAddress32(Core::System& system, u32 address, SignalType signal_type, s32 value,
s32 count);
Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read);
Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size);
Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation,
u64 address, u64 size, MemoryPermission perm);
Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, u64 size);
} // namespace Kernel::Svc
+4 -26
View File
@@ -16,19 +16,18 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle,
thread_activity);
// Validate the activity.
static constexpr auto IsValidThreadActivity = [](ThreadActivity activity) {
constexpr auto IsValidThreadActivity = [](ThreadActivity activity) {
return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused;
};
R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue);
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Check that the activity is being set on a non-current thread for the current process.
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()),
ResultInvalidHandle);
R_UNLESS(thread->GetOwnerProcess() == system.Kernel().CurrentProcess(), ResultInvalidHandle);
R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy);
// Set the activity.
@@ -37,30 +36,9 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle,
return ResultSuccess;
}
Result SetProcessActivity(Core::System& system, Handle process_handle,
ProcessActivity process_activity) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetThreadActivity64(Core::System& system, Handle thread_handle,
Result SetThreadActivity32(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity) {
return SetThreadActivity(system, thread_handle, thread_activity);
}
Result SetProcessActivity64(Core::System& system, Handle process_handle,
ProcessActivity process_activity) {
return SetProcessActivity(system, process_handle, process_activity);
}
Result SetThreadActivity64From32(Core::System& system, Handle thread_handle,
ThreadActivity thread_activity) {
return SetThreadActivity(system, thread_handle, thread_activity);
}
Result SetProcessActivity64From32(Core::System& system, Handle process_handle,
ProcessActivity process_activity) {
return SetProcessActivity(system, process_handle, process_activity);
}
} // namespace Kernel::Svc
+10 -19
View File
@@ -72,7 +72,13 @@ Result WaitForAddress(Core::System& system, VAddr address, ArbitrationType arb_t
timeout = timeout_ns;
}
return GetCurrentProcess(system.Kernel()).WaitAddressArbiter(address, arb_type, value, timeout);
return system.Kernel().CurrentProcess()->WaitAddressArbiter(address, arb_type, value, timeout);
}
Result WaitForAddress32(Core::System& system, u32 address, ArbitrationType arb_type, s32 value,
u32 timeout_ns_low, u32 timeout_ns_high) {
const auto timeout = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32));
return WaitForAddress(system, address, arb_type, value, timeout);
}
// Signals to an address (via Address Arbiter)
@@ -95,28 +101,13 @@ Result SignalToAddress(Core::System& system, VAddr address, SignalType signal_ty
return ResultInvalidEnumValue;
}
return GetCurrentProcess(system.Kernel())
.SignalAddressArbiter(address, signal_type, value, count);
return system.Kernel().CurrentProcess()->SignalAddressArbiter(address, signal_type, value,
count);
}
Result WaitForAddress64(Core::System& system, VAddr address, ArbitrationType arb_type, s32 value,
s64 timeout_ns) {
return WaitForAddress(system, address, arb_type, value, timeout_ns);
}
Result SignalToAddress64(Core::System& system, VAddr address, SignalType signal_type, s32 value,
Result SignalToAddress32(Core::System& system, u32 address, SignalType signal_type, s32 value,
s32 count) {
return SignalToAddress(system, address, signal_type, value, count);
}
Result WaitForAddress64From32(Core::System& system, u32 address, ArbitrationType arb_type,
s32 value, s64 timeout_ns) {
return WaitForAddress(system, address, arb_type, value, timeout_ns);
}
Result SignalToAddress64From32(Core::System& system, u32 address, SignalType signal_type, s32 value,
s32 count) {
return SignalToAddress(system, address, signal_type, value, count);
}
} // namespace Kernel::Svc
@@ -2,49 +2,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result QueryPhysicalAddress(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
uint64_t address) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result QueryIoMapping(Core::System& system, uint64_t* out_address, uint64_t* out_size,
uint64_t physical_address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result QueryPhysicalAddress64(Core::System& system, lp64::PhysicalMemoryInfo* out_info,
uint64_t address) {
R_RETURN(QueryPhysicalAddress(system, out_info, address));
}
Result QueryIoMapping64(Core::System& system, uint64_t* out_address, uint64_t* out_size,
uint64_t physical_address, uint64_t size) {
R_RETURN(QueryIoMapping(system, out_address, out_size, physical_address, size));
}
Result QueryPhysicalAddress64From32(Core::System& system, ilp32::PhysicalMemoryInfo* out_info,
uint32_t address) {
lp64::PhysicalMemoryInfo info{};
R_TRY(QueryPhysicalAddress(system, std::addressof(info), address));
*out_info = {
.physical_address = info.physical_address,
.virtual_address = static_cast<u32>(info.virtual_address),
.size = static_cast<u32>(info.size),
};
R_SUCCEED();
}
Result QueryIoMapping64From32(Core::System& system, uint64_t* out_address, uint64_t* out_size,
uint64_t physical_address, uint32_t size) {
R_RETURN(QueryIoMapping(system, reinterpret_cast<uint64_t*>(out_address),
reinterpret_cast<uint64_t*>(out_size), physical_address, size));
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+4 -71
View File
@@ -9,36 +9,15 @@
namespace Kernel::Svc {
void FlushEntireDataCache(Core::System& system) {
UNIMPLEMENTED();
}
Result FlushDataCache(Core::System& system, uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result InvalidateProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result StoreProcessDataCache(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 address, u64 size) {
Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, u64 size) {
// Validate address/size.
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS(address == static_cast<uint64_t>(address), ResultInvalidCurrentMemory);
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory);
R_UNLESS(size == static_cast<size_t>(size), ResultInvalidCurrentMemory);
// Get the process from its handle.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Verify the region is within range.
@@ -49,50 +28,4 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad
R_RETURN(system.Memory().FlushDataCache(*process, address, size));
}
void FlushEntireDataCache64(Core::System& system) {
FlushEntireDataCache(system);
}
Result FlushDataCache64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(FlushDataCache(system, address, size));
}
Result InvalidateProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
}
Result StoreProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
}
Result FlushProcessDataCache64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
}
void FlushEntireDataCache64From32(Core::System& system) {
return FlushEntireDataCache(system);
}
Result FlushDataCache64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(FlushDataCache(system, address, size));
}
Result InvalidateProcessDataCache64From32(Core::System& system, Handle process_handle,
uint64_t address, uint64_t size) {
R_RETURN(InvalidateProcessDataCache(system, process_handle, address, size));
}
Result StoreProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(StoreProcessDataCache(system, process_handle, address, size));
}
Result FlushProcessDataCache64From32(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size) {
R_RETURN(FlushProcessDataCache(system, process_handle, address, size));
}
} // namespace Kernel::Svc
+21 -38
View File
@@ -28,7 +28,7 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm)
} // namespace
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64_t size) {
Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, size_t size) {
LOG_TRACE(Kernel_SVC, "called, address=0x{:X}, size=0x{:X}", address, size);
// Get kernel instance.
@@ -46,7 +46,7 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64
R_UNLESS(code_mem != nullptr, ResultOutOfResource);
// Verify that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel()).PageTable().Contains(address, size),
R_UNLESS(system.CurrentProcess()->PageTable().Contains(address, size),
ResultInvalidCurrentMemory);
// Initialize the code memory.
@@ -56,16 +56,19 @@ Result CreateCodeMemory(Core::System& system, Handle* out, VAddr address, uint64
KCodeMemory::Register(kernel, code_mem);
// Add the code memory to the handle table.
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, code_mem));
R_TRY(system.CurrentProcess()->GetHandleTable().Add(out, code_mem));
code_mem->Close();
return ResultSuccess;
}
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
CodeMemoryOperation operation, VAddr address, uint64_t size,
MemoryPermission perm) {
Result CreateCodeMemory32(Core::System& system, Handle* out, u32 address, u32 size) {
return CreateCodeMemory(system, out, address, size);
}
Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, u32 operation,
VAddr address, size_t size, MemoryPermission perm) {
LOG_TRACE(Kernel_SVC,
"called, code_memory_handle=0x{:X}, operation=0x{:X}, address=0x{:X}, size=0x{:X}, "
@@ -79,22 +82,20 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
// Get the code memory from its handle.
KScopedAutoObject code_mem = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KCodeMemory>(code_memory_handle);
KScopedAutoObject code_mem =
system.CurrentProcess()->GetHandleTable().GetObject<KCodeMemory>(code_memory_handle);
R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle);
// NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process.
// This enables homebrew usage of these SVCs for JIT.
// Perform the operation.
switch (operation) {
switch (static_cast<CodeMemoryOperation>(operation)) {
case CodeMemoryOperation::Map: {
// Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel())
.PageTable()
.CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
R_UNLESS(
system.CurrentProcess()->PageTable().CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
// Check the memory permission.
R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
@@ -104,10 +105,9 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
} break;
case CodeMemoryOperation::Unmap: {
// Check that the region is in range.
R_UNLESS(GetCurrentProcess(system.Kernel())
.PageTable()
.CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
R_UNLESS(
system.CurrentProcess()->PageTable().CanContain(address, size, KMemoryState::CodeOut),
ResultInvalidMemoryRegion);
// Check the memory permission.
R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission);
@@ -146,26 +146,9 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
return ResultSuccess;
}
Result CreateCodeMemory64(Core::System& system, Handle* out_handle, uint64_t address,
uint64_t size) {
R_RETURN(CreateCodeMemory(system, out_handle, address, size));
}
Result ControlCodeMemory64(Core::System& system, Handle code_memory_handle,
CodeMemoryOperation operation, uint64_t address, uint64_t size,
MemoryPermission perm) {
R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
}
Result CreateCodeMemory64From32(Core::System& system, Handle* out_handle, uint32_t address,
uint32_t size) {
R_RETURN(CreateCodeMemory(system, out_handle, address, size));
}
Result ControlCodeMemory64From32(Core::System& system, Handle code_memory_handle,
CodeMemoryOperation operation, uint64_t address, uint64_t size,
MemoryPermission perm) {
R_RETURN(ControlCodeMemory(system, code_memory_handle, operation, address, size, perm));
Result ControlCodeMemory32(Core::System& system, Handle code_memory_handle, u32 operation,
u64 address, u64 size, MemoryPermission perm) {
return ControlCodeMemory(system, code_memory_handle, operation, address, size, perm);
}
} // namespace Kernel::Svc
@@ -43,8 +43,14 @@ Result WaitProcessWideKeyAtomic(Core::System& system, VAddr address, VAddr cv_ke
}
// Wait on the condition variable.
return GetCurrentProcess(system.Kernel())
.WaitConditionVariable(address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout);
return system.Kernel().CurrentProcess()->WaitConditionVariable(
address, Common::AlignDown(cv_key, sizeof(u32)), tag, timeout);
}
Result WaitProcessWideKeyAtomic32(Core::System& system, u32 address, u32 cv_key, u32 tag,
u32 timeout_ns_low, u32 timeout_ns_high) {
const auto timeout_ns = static_cast<s64>(timeout_ns_low | (u64{timeout_ns_high} << 32));
return WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns);
}
/// Signal process wide key
@@ -52,25 +58,11 @@ void SignalProcessWideKey(Core::System& system, VAddr cv_key, s32 count) {
LOG_TRACE(Kernel_SVC, "called, cv_key=0x{:X}, count=0x{:08X}", cv_key, count);
// Signal the condition variable.
return GetCurrentProcess(system.Kernel())
.SignalConditionVariable(Common::AlignDown(cv_key, sizeof(u32)), count);
return system.Kernel().CurrentProcess()->SignalConditionVariable(
Common::AlignDown(cv_key, sizeof(u32)), count);
}
Result WaitProcessWideKeyAtomic64(Core::System& system, uint64_t address, uint64_t cv_key,
uint32_t tag, int64_t timeout_ns) {
R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
}
void SignalProcessWideKey64(Core::System& system, uint64_t cv_key, int32_t count) {
SignalProcessWideKey(system, cv_key, count);
}
Result WaitProcessWideKeyAtomic64From32(Core::System& system, uint32_t address, uint32_t cv_key,
uint32_t tag, int64_t timeout_ns) {
R_RETURN(WaitProcessWideKeyAtomic(system, address, cv_key, tag, timeout_ns));
}
void SignalProcessWideKey64From32(Core::System& system, uint32_t cv_key, int32_t count) {
void SignalProcessWideKey32(Core::System& system, u32 cv_key, s32 count) {
SignalProcessWideKey(system, cv_key, count);
}
+1 -189
View File
@@ -2,193 +2,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result DebugActiveProcess(Core::System& system, Handle* out_handle, uint64_t process_id) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result BreakDebugProcess(Core::System& system, Handle debug_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result TerminateDebugProcess(Core::System& system, Handle debug_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetDebugEvent(Core::System& system, uint64_t out_info, Handle debug_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ContinueDebugEvent(Core::System& system, Handle debug_handle, uint32_t flags,
uint64_t user_thread_ids, int32_t num_thread_ids) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetDebugThreadContext(Core::System& system, uint64_t out_context, Handle debug_handle,
uint64_t thread_id, uint32_t context_flags) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetDebugThreadContext(Core::System& system, Handle debug_handle, uint64_t thread_id,
uint64_t user_context, uint32_t context_flags) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result QueryDebugProcessMemory(Core::System& system, uint64_t out_memory_info,
PageInfo* out_page_info, Handle process_handle, uint64_t address) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ReadDebugProcessMemory(Core::System& system, uint64_t buffer, Handle debug_handle,
uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result WriteDebugProcessMemory(Core::System& system, Handle debug_handle, uint64_t buffer,
uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetHardwareBreakPoint(Core::System& system, HardwareBreakPointRegisterName name,
uint64_t flags, uint64_t value) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetDebugThreadParam(Core::System& system, uint64_t* out_64, uint32_t* out_32,
Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result DebugActiveProcess64(Core::System& system, Handle* out_handle, uint64_t process_id) {
R_RETURN(DebugActiveProcess(system, out_handle, process_id));
}
Result BreakDebugProcess64(Core::System& system, Handle debug_handle) {
R_RETURN(BreakDebugProcess(system, debug_handle));
}
Result TerminateDebugProcess64(Core::System& system, Handle debug_handle) {
R_RETURN(TerminateDebugProcess(system, debug_handle));
}
Result GetDebugEvent64(Core::System& system, uint64_t out_info, Handle debug_handle) {
R_RETURN(GetDebugEvent(system, out_info, debug_handle));
}
Result ContinueDebugEvent64(Core::System& system, Handle debug_handle, uint32_t flags,
uint64_t thread_ids, int32_t num_thread_ids) {
R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
}
Result GetDebugThreadContext64(Core::System& system, uint64_t out_context, Handle debug_handle,
uint64_t thread_id, uint32_t context_flags) {
R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
}
Result SetDebugThreadContext64(Core::System& system, Handle debug_handle, uint64_t thread_id,
uint64_t context, uint32_t context_flags) {
R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
}
Result QueryDebugProcessMemory64(Core::System& system, uint64_t out_memory_info,
PageInfo* out_page_info, Handle debug_handle, uint64_t address) {
R_RETURN(
QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
}
Result ReadDebugProcessMemory64(Core::System& system, uint64_t buffer, Handle debug_handle,
uint64_t address, uint64_t size) {
R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
}
Result WriteDebugProcessMemory64(Core::System& system, Handle debug_handle, uint64_t buffer,
uint64_t address, uint64_t size) {
R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
}
Result SetHardwareBreakPoint64(Core::System& system, HardwareBreakPointRegisterName name,
uint64_t flags, uint64_t value) {
R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
}
Result GetDebugThreadParam64(Core::System& system, uint64_t* out_64, uint32_t* out_32,
Handle debug_handle, uint64_t thread_id, DebugThreadParam param) {
R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
}
Result DebugActiveProcess64From32(Core::System& system, Handle* out_handle, uint64_t process_id) {
R_RETURN(DebugActiveProcess(system, out_handle, process_id));
}
Result BreakDebugProcess64From32(Core::System& system, Handle debug_handle) {
R_RETURN(BreakDebugProcess(system, debug_handle));
}
Result TerminateDebugProcess64From32(Core::System& system, Handle debug_handle) {
R_RETURN(TerminateDebugProcess(system, debug_handle));
}
Result GetDebugEvent64From32(Core::System& system, uint32_t out_info, Handle debug_handle) {
R_RETURN(GetDebugEvent(system, out_info, debug_handle));
}
Result ContinueDebugEvent64From32(Core::System& system, Handle debug_handle, uint32_t flags,
uint32_t thread_ids, int32_t num_thread_ids) {
R_RETURN(ContinueDebugEvent(system, debug_handle, flags, thread_ids, num_thread_ids));
}
Result GetDebugThreadContext64From32(Core::System& system, uint32_t out_context,
Handle debug_handle, uint64_t thread_id,
uint32_t context_flags) {
R_RETURN(GetDebugThreadContext(system, out_context, debug_handle, thread_id, context_flags));
}
Result SetDebugThreadContext64From32(Core::System& system, Handle debug_handle, uint64_t thread_id,
uint32_t context, uint32_t context_flags) {
R_RETURN(SetDebugThreadContext(system, debug_handle, thread_id, context, context_flags));
}
Result QueryDebugProcessMemory64From32(Core::System& system, uint32_t out_memory_info,
PageInfo* out_page_info, Handle debug_handle,
uint32_t address) {
R_RETURN(
QueryDebugProcessMemory(system, out_memory_info, out_page_info, debug_handle, address));
}
Result ReadDebugProcessMemory64From32(Core::System& system, uint32_t buffer, Handle debug_handle,
uint32_t address, uint32_t size) {
R_RETURN(ReadDebugProcessMemory(system, buffer, debug_handle, address, size));
}
Result WriteDebugProcessMemory64From32(Core::System& system, Handle debug_handle, uint32_t buffer,
uint32_t address, uint32_t size) {
R_RETURN(WriteDebugProcessMemory(system, debug_handle, buffer, address, size));
}
Result SetHardwareBreakPoint64From32(Core::System& system, HardwareBreakPointRegisterName name,
uint64_t flags, uint64_t value) {
R_RETURN(SetHardwareBreakPoint(system, name, flags, value));
}
Result GetDebugThreadParam64From32(Core::System& system, uint64_t* out_64, uint32_t* out_32,
Handle debug_handle, uint64_t thread_id,
DebugThreadParam param) {
R_RETURN(GetDebugThreadParam(system, out_64, out_32, debug_handle, thread_id, param));
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+6 -10
View File
@@ -8,22 +8,18 @@
namespace Kernel::Svc {
/// Used to output a message on a debug hardware unit - does nothing on a retail unit
Result OutputDebugString(Core::System& system, VAddr address, u64 len) {
R_SUCCEED_IF(len == 0);
void OutputDebugString(Core::System& system, VAddr address, u64 len) {
if (len == 0) {
return;
}
std::string str(len, '\0');
system.Memory().ReadBlock(address, str.data(), str.size());
LOG_DEBUG(Debug_Emulated, "{}", str);
R_SUCCEED();
}
Result OutputDebugString64(Core::System& system, uint64_t debug_str, uint64_t len) {
R_RETURN(OutputDebugString(system, debug_str, len));
}
Result OutputDebugString64From32(Core::System& system, uint32_t debug_str, uint32_t len) {
R_RETURN(OutputDebugString(system, debug_str, len));
void OutputDebugString32(Core::System& system, u32 address, u32 len) {
OutputDebugString(system, address, len);
}
} // namespace Kernel::Svc
@@ -1,258 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/alignment.h"
#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/k_device_address_space.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/svc.h"
namespace Kernel::Svc {
constexpr inline u64 DeviceAddressSpaceAlignMask = (1ULL << 22) - 1;
constexpr bool IsProcessAndDeviceAligned(uint64_t process_address, uint64_t device_address) {
return (process_address & DeviceAddressSpaceAlignMask) ==
(device_address & DeviceAddressSpaceAlignMask);
}
Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_address,
uint64_t das_size) {
// Validate input.
R_UNLESS(Common::IsAligned(das_address, PageSize), ResultInvalidMemoryRegion);
R_UNLESS(Common::IsAligned(das_size, PageSize), ResultInvalidMemoryRegion);
R_UNLESS(das_size > 0, ResultInvalidMemoryRegion);
R_UNLESS((das_address < das_address + das_size), ResultInvalidMemoryRegion);
// Create the device address space.
KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel());
R_UNLESS(das != nullptr, ResultOutOfResource);
SCOPE_EXIT({ das->Close(); });
// Initialize the device address space.
R_TRY(das->Initialize(das_address, das_size));
// Register the device address space.
KDeviceAddressSpace::Register(system.Kernel(), das);
// Add to the handle table.
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, das));
R_SUCCEED();
}
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Attach.
R_RETURN(das->Attach(device_name));
}
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Detach.
R_RETURN(das->Detach(device_name));
}
constexpr bool IsValidDeviceMemoryPermission(MemoryPermission device_perm) {
switch (device_perm) {
case MemoryPermission::Read:
case MemoryPermission::Write:
case MemoryPermission::ReadWrite:
return true;
default:
return false;
}
}
Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Handle process_handle,
uint64_t process_address, uint64_t size,
uint64_t device_address, u32 option) {
// Decode the option.
const MapDeviceAddressSpaceOption option_pack{option};
const auto device_perm = option_pack.permission;
const auto reserved = option_pack.reserved;
// Validate input.
R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
ResultInvalidCurrentMemory);
R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
R_UNLESS(reserved == 0, ResultInvalidEnumValue);
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Get the process.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range.
auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
// Map.
R_RETURN(
das->MapByForce(std::addressof(page_table), process_address, size, device_address, option));
}
Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Handle process_handle,
uint64_t process_address, uint64_t size,
uint64_t device_address, u32 option) {
// Decode the option.
const MapDeviceAddressSpaceOption option_pack{option};
const auto device_perm = option_pack.permission;
const auto reserved = option_pack.reserved;
// Validate input.
R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
R_UNLESS(IsProcessAndDeviceAligned(process_address, device_address), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
ResultInvalidCurrentMemory);
R_UNLESS(IsValidDeviceMemoryPermission(device_perm), ResultInvalidNewMemoryPermission);
R_UNLESS(reserved == 0, ResultInvalidEnumValue);
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Get the process.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range.
auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
// Map.
R_RETURN(
das->MapAligned(std::addressof(page_table), process_address, size, device_address, option));
}
Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle process_handle,
uint64_t process_address, uint64_t size, uint64_t device_address) {
// Validate input.
R_UNLESS(Common::IsAligned(process_address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(device_address, PageSize), ResultInvalidAddress);
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS((process_address < process_address + size), ResultInvalidCurrentMemory);
R_UNLESS((device_address < device_address + size), ResultInvalidMemoryRegion);
R_UNLESS((process_address == static_cast<uint64_t>(process_address)),
ResultInvalidCurrentMemory);
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Get the process.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range.
auto& page_table = process->PageTable();
R_UNLESS(page_table.Contains(process_address, size), ResultInvalidCurrentMemory);
R_RETURN(das->Unmap(std::addressof(page_table), process_address, size, device_address));
}
Result CreateDeviceAddressSpace64(Core::System& system, Handle* out_handle, uint64_t das_address,
uint64_t das_size) {
R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size));
}
Result AttachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) {
R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle));
}
Result DetachDeviceAddressSpace64(Core::System& system, DeviceName device_name, Handle das_handle) {
R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle));
}
Result MapDeviceAddressSpaceByForce64(Core::System& system, Handle das_handle,
Handle process_handle, uint64_t process_address,
uint64_t size, uint64_t device_address, u32 option) {
R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size,
device_address, option));
}
Result MapDeviceAddressSpaceAligned64(Core::System& system, Handle das_handle,
Handle process_handle, uint64_t process_address,
uint64_t size, uint64_t device_address, u32 option) {
R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size,
device_address, option));
}
Result UnmapDeviceAddressSpace64(Core::System& system, Handle das_handle, Handle process_handle,
uint64_t process_address, uint64_t size, uint64_t device_address) {
R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size,
device_address));
}
Result CreateDeviceAddressSpace64From32(Core::System& system, Handle* out_handle,
uint64_t das_address, uint64_t das_size) {
R_RETURN(CreateDeviceAddressSpace(system, out_handle, das_address, das_size));
}
Result AttachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name,
Handle das_handle) {
R_RETURN(AttachDeviceAddressSpace(system, device_name, das_handle));
}
Result DetachDeviceAddressSpace64From32(Core::System& system, DeviceName device_name,
Handle das_handle) {
R_RETURN(DetachDeviceAddressSpace(system, device_name, das_handle));
}
Result MapDeviceAddressSpaceByForce64From32(Core::System& system, Handle das_handle,
Handle process_handle, uint64_t process_address,
uint32_t size, uint64_t device_address, u32 option) {
R_RETURN(MapDeviceAddressSpaceByForce(system, das_handle, process_handle, process_address, size,
device_address, option));
}
Result MapDeviceAddressSpaceAligned64From32(Core::System& system, Handle das_handle,
Handle process_handle, uint64_t process_address,
uint32_t size, uint64_t device_address, u32 option) {
R_RETURN(MapDeviceAddressSpaceAligned(system, das_handle, process_handle, process_address, size,
device_address, option));
}
Result UnmapDeviceAddressSpace64From32(Core::System& system, Handle das_handle,
Handle process_handle, uint64_t process_address,
uint32_t size, uint64_t device_address) {
R_RETURN(UnmapDeviceAddressSpace(system, das_handle, process_handle, process_address, size,
device_address));
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+15 -28
View File
@@ -15,7 +15,7 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
// Get the current handle table.
const KHandleTable& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
// Get the event.
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
@@ -24,11 +24,15 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
return event->Signal();
}
Result SignalEvent32(Core::System& system, Handle event_handle) {
return SignalEvent(system, event_handle);
}
Result ClearEvent(Core::System& system, Handle event_handle) {
LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle);
// Get the current handle table.
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
// Try to clear the writable event.
{
@@ -51,15 +55,19 @@ Result ClearEvent(Core::System& system, Handle event_handle) {
return ResultInvalidHandle;
}
Result ClearEvent32(Core::System& system, Handle event_handle) {
return ClearEvent(system, event_handle);
}
Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
LOG_DEBUG(Kernel_SVC, "called");
// Get the kernel reference and handle table.
auto& kernel = system.Kernel();
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
// Reserve a new event from the process resource limit
KScopedResourceReservation event_reservation(GetCurrentProcessPointer(kernel),
KScopedResourceReservation event_reservation(kernel.CurrentProcess(),
LimitableResource::EventCountMax);
R_UNLESS(event_reservation.Succeeded(), ResultLimitReached);
@@ -68,7 +76,7 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
R_UNLESS(event != nullptr, ResultOutOfResource);
// Initialize the event.
event->Initialize(GetCurrentProcessPointer(kernel));
event->Initialize(kernel.CurrentProcess());
// Commit the thread reservation.
event_reservation.Commit();
@@ -96,29 +104,8 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) {
return ResultSuccess;
}
Result SignalEvent64(Core::System& system, Handle event_handle) {
R_RETURN(SignalEvent(system, event_handle));
}
Result ClearEvent64(Core::System& system, Handle event_handle) {
R_RETURN(ClearEvent(system, event_handle));
}
Result CreateEvent64(Core::System& system, Handle* out_write_handle, Handle* out_read_handle) {
R_RETURN(CreateEvent(system, out_write_handle, out_read_handle));
}
Result SignalEvent64From32(Core::System& system, Handle event_handle) {
R_RETURN(SignalEvent(system, event_handle));
}
Result ClearEvent64From32(Core::System& system, Handle event_handle) {
R_RETURN(ClearEvent(system, event_handle));
}
Result CreateEvent64From32(Core::System& system, Handle* out_write_handle,
Handle* out_read_handle) {
R_RETURN(CreateEvent(system, out_write_handle, out_read_handle));
Result CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) {
return CreateEvent(system, out_write, out_read);
}
} // namespace Kernel::Svc
+8 -24
View File
@@ -12,10 +12,10 @@
namespace Kernel::Svc {
/// Break program execution
void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
BreakReason break_reason =
reason & static_cast<BreakReason>(~BreakReason::NotificationOnlyFlag);
bool notification_only = True(reason & BreakReason::NotificationOnlyFlag);
static_cast<BreakReason>(reason & ~static_cast<u32>(BreakReason::NotificationOnlyFlag));
bool notification_only = (reason & static_cast<u32>(BreakReason::NotificationOnlyFlag)) != 0;
bool has_dumped_buffer{};
std::vector<u8> debug_buffer;
@@ -90,9 +90,9 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
break;
}
system.GetReporter().SaveSvcBreakReport(
static_cast<u32>(reason), notification_only, info1, info2,
has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
system.GetReporter().SaveSvcBreakReport(reason, notification_only, info1, info2,
has_dumped_buffer ? std::make_optional(debug_buffer)
: std::nullopt);
if (!notification_only) {
LOG_CRITICAL(
@@ -114,24 +114,8 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
}
}
void ReturnFromException(Core::System& system, Result result) {
UNIMPLEMENTED();
}
void Break64(Core::System& system, BreakReason break_reason, uint64_t arg, uint64_t size) {
Break(system, break_reason, arg, size);
}
void Break64From32(Core::System& system, BreakReason break_reason, uint32_t arg, uint32_t size) {
Break(system, break_reason, arg, size);
}
void ReturnFromException64(Core::System& system, Result result) {
ReturnFromException(system, result);
}
void ReturnFromException64From32(Core::System& system, Result result) {
ReturnFromException(system, result);
void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) {
Break(system, reason, info1, info2);
}
} // namespace Kernel::Svc
+19 -34
View File
@@ -10,12 +10,11 @@
namespace Kernel::Svc {
/// Gets system/memory information for the current process
Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle handle,
u64 info_sub_id) {
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}",
info_id_type, info_sub_id, handle);
Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, u64 info_sub_id) {
LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id,
info_sub_id, handle);
u32 info_id = static_cast<u32>(info_id_type);
const auto info_id_type = static_cast<InfoType>(info_id);
switch (info_id_type) {
case InfoType::CoreMask:
@@ -44,7 +43,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
return ResultInvalidEnumValue;
}
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}",
@@ -154,7 +153,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
return ResultInvalidCombination;
}
KProcess* const current_process = GetCurrentProcessPointer(system.Kernel());
KProcess* const current_process = system.Kernel().CurrentProcess();
KHandleTable& handle_table = current_process->GetHandleTable();
const auto resource_limit = current_process->GetResourceLimit();
if (!resource_limit) {
@@ -183,7 +182,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
return ResultInvalidCombination;
}
*result = GetCurrentProcess(system.Kernel()).GetRandomEntropy(info_sub_id);
*result = system.Kernel().CurrentProcess()->GetRandomEntropy(info_sub_id);
return ResultSuccess;
case InfoType::InitialProcessIdRange:
@@ -200,9 +199,9 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
return ResultInvalidCombination;
}
KScopedAutoObject thread = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KThread>(static_cast<Handle>(handle));
KScopedAutoObject thread =
system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(
static_cast<Handle>(handle));
if (thread.IsNull()) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
static_cast<Handle>(handle));
@@ -249,7 +248,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
R_UNLESS(info_sub_id == 0, ResultInvalidCombination);
// Get the handle table.
KProcess* current_process = GetCurrentProcessPointer(system.Kernel());
KProcess* current_process = system.Kernel().CurrentProcess();
KHandleTable& handle_table = current_process->GetHandleTable();
// Get a new handle for the current process.
@@ -268,30 +267,16 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
}
}
Result GetSystemInfo(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle,
uint64_t info_subtype) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result GetInfo32(Core::System& system, u32* result_low, u32* result_high, u32 sub_id_low,
u32 info_id, u32 handle, u32 sub_id_high) {
const u64 sub_id{u64{sub_id_low} | (u64{sub_id_high} << 32)};
u64 res_value{};
Result GetInfo64(Core::System& system, uint64_t* out, InfoType info_type, Handle handle,
uint64_t info_subtype) {
R_RETURN(GetInfo(system, out, info_type, handle, info_subtype));
}
const Result result{GetInfo(system, &res_value, info_id, handle, sub_id)};
*result_high = static_cast<u32>(res_value >> 32);
*result_low = static_cast<u32>(res_value & std::numeric_limits<u32>::max());
Result GetSystemInfo64(Core::System& system, uint64_t* out, SystemInfoType info_type, Handle handle,
uint64_t info_subtype) {
R_RETURN(GetSystemInfo(system, out, info_type, handle, info_subtype));
}
Result GetInfo64From32(Core::System& system, uint64_t* out, InfoType info_type, Handle handle,
uint64_t info_subtype) {
R_RETURN(GetInfo(system, out, info_type, handle, info_subtype));
}
Result GetSystemInfo64From32(Core::System& system, uint64_t* out, SystemInfoType info_type,
Handle handle, uint64_t info_subtype) {
R_RETURN(GetSystemInfo(system, out, info_type, handle, info_subtype));
return result;
}
} // namespace Kernel::Svc
@@ -1,35 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result MapInsecureMemory(Core::System& system, uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result UnmapInsecureMemory(Core::System& system, uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result MapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(MapInsecureMemory(system, address, size));
}
Result UnmapInsecureMemory64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(UnmapInsecureMemory(system, address, size));
}
Result MapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(MapInsecureMemory(system, address, size));
}
Result UnmapInsecureMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(UnmapInsecureMemory(system, address, size));
}
} // namespace Kernel::Svc
@@ -2,24 +2,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result CreateInterruptEvent(Core::System& system, Handle* out, int32_t interrupt_id,
InterruptType type) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result CreateInterruptEvent64(Core::System& system, Handle* out_read_handle, int32_t interrupt_id,
InterruptType interrupt_type) {
R_RETURN(CreateInterruptEvent(system, out_read_handle, interrupt_id, interrupt_type));
}
Result CreateInterruptEvent64From32(Core::System& system, Handle* out_read_handle,
int32_t interrupt_id, InterruptType interrupt_type) {
R_RETURN(CreateInterruptEvent(system, out_read_handle, interrupt_id, interrupt_type));
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+1 -66
View File
@@ -2,70 +2,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result CreateIoPool(Core::System& system, Handle* out, IoPoolType pool_type) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result CreateIoRegion(Core::System& system, Handle* out, Handle io_pool_handle, uint64_t phys_addr,
uint64_t size, MemoryMapping mapping, MemoryPermission perm) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result MapIoRegion(Core::System& system, Handle io_region_handle, uint64_t address, uint64_t size,
MemoryPermission map_perm) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result UnmapIoRegion(Core::System& system, Handle io_region_handle, uint64_t address,
uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result CreateIoPool64(Core::System& system, Handle* out_handle, IoPoolType pool_type) {
R_RETURN(CreateIoPool(system, out_handle, pool_type));
}
Result CreateIoRegion64(Core::System& system, Handle* out_handle, Handle io_pool,
uint64_t physical_address, uint64_t size, MemoryMapping mapping,
MemoryPermission perm) {
R_RETURN(CreateIoRegion(system, out_handle, io_pool, physical_address, size, mapping, perm));
}
Result MapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size,
MemoryPermission perm) {
R_RETURN(MapIoRegion(system, io_region, address, size, perm));
}
Result UnmapIoRegion64(Core::System& system, Handle io_region, uint64_t address, uint64_t size) {
R_RETURN(UnmapIoRegion(system, io_region, address, size));
}
Result CreateIoPool64From32(Core::System& system, Handle* out_handle, IoPoolType pool_type) {
R_RETURN(CreateIoPool(system, out_handle, pool_type));
}
Result CreateIoRegion64From32(Core::System& system, Handle* out_handle, Handle io_pool,
uint64_t physical_address, uint32_t size, MemoryMapping mapping,
MemoryPermission perm) {
R_RETURN(CreateIoRegion(system, out_handle, io_pool, physical_address, size, mapping, perm));
}
Result MapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address, uint32_t size,
MemoryPermission perm) {
R_RETURN(MapIoRegion(system, io_region, address, size, perm));
}
Result UnmapIoRegion64From32(Core::System& system, Handle io_region, uint32_t address,
uint32_t size) {
R_RETURN(UnmapIoRegion(system, io_region, address, size));
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+10 -93
View File
@@ -12,9 +12,11 @@ namespace Kernel::Svc {
/// Makes a blocking IPC call to a service.
Result SendSyncRequest(Core::System& system, Handle handle) {
auto& kernel = system.Kernel();
// Get the client session from its handle.
KScopedAutoObject session =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KClientSession>(handle);
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
@@ -22,37 +24,20 @@ Result SendSyncRequest(Core::System& system, Handle handle) {
return session->SendSyncRequest();
}
Result SendSyncRequestWithUserBuffer(Core::System& system, uint64_t message_buffer,
uint64_t message_buffer_size, Handle session_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
Result SendSyncRequest32(Core::System& system, Handle handle) {
return SendSyncRequest(system, handle);
}
Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_handle,
uint64_t message_buffer, uint64_t message_buffer_size,
Handle session_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_addr, s32 num_handles,
Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles, s32 num_handles,
Handle reply_target, s64 timeout_ns) {
auto& kernel = system.Kernel();
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange);
R_UNLESS(system.Memory().IsValidVirtualAddressRange(
handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
ResultInvalidPointer);
std::vector<Handle> handles(num_handles);
system.Memory().ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable();
// Convert handle list to object table.
std::vector<KSynchronizationObject*> objs(num_handles);
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(),
num_handles),
ResultInvalidHandle);
R_UNLESS(
handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles),
ResultInvalidHandle);
// Ensure handles are closed when we're done.
SCOPE_EXIT({
@@ -101,72 +86,4 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
}
}
Result ReplyAndReceiveWithUserBuffer(Core::System& system, int32_t* out_index,
uint64_t message_buffer, uint64_t message_buffer_size,
uint64_t handles, int32_t num_handles, Handle reply_target,
int64_t timeout_ns) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SendSyncRequest64(Core::System& system, Handle session_handle) {
R_RETURN(SendSyncRequest(system, session_handle));
}
Result SendSyncRequestWithUserBuffer64(Core::System& system, uint64_t message_buffer,
uint64_t message_buffer_size, Handle session_handle) {
R_RETURN(
SendSyncRequestWithUserBuffer(system, message_buffer, message_buffer_size, session_handle));
}
Result SendAsyncRequestWithUserBuffer64(Core::System& system, Handle* out_event_handle,
uint64_t message_buffer, uint64_t message_buffer_size,
Handle session_handle) {
R_RETURN(SendAsyncRequestWithUserBuffer(system, out_event_handle, message_buffer,
message_buffer_size, session_handle));
}
Result ReplyAndReceive64(Core::System& system, int32_t* out_index, uint64_t handles,
int32_t num_handles, Handle reply_target, int64_t timeout_ns) {
R_RETURN(ReplyAndReceive(system, out_index, handles, num_handles, reply_target, timeout_ns));
}
Result ReplyAndReceiveWithUserBuffer64(Core::System& system, int32_t* out_index,
uint64_t message_buffer, uint64_t message_buffer_size,
uint64_t handles, int32_t num_handles, Handle reply_target,
int64_t timeout_ns) {
R_RETURN(ReplyAndReceiveWithUserBuffer(system, out_index, message_buffer, message_buffer_size,
handles, num_handles, reply_target, timeout_ns));
}
Result SendSyncRequest64From32(Core::System& system, Handle session_handle) {
R_RETURN(SendSyncRequest(system, session_handle));
}
Result SendSyncRequestWithUserBuffer64From32(Core::System& system, uint32_t message_buffer,
uint32_t message_buffer_size, Handle session_handle) {
R_RETURN(
SendSyncRequestWithUserBuffer(system, message_buffer, message_buffer_size, session_handle));
}
Result SendAsyncRequestWithUserBuffer64From32(Core::System& system, Handle* out_event_handle,
uint32_t message_buffer, uint32_t message_buffer_size,
Handle session_handle) {
R_RETURN(SendAsyncRequestWithUserBuffer(system, out_event_handle, message_buffer,
message_buffer_size, session_handle));
}
Result ReplyAndReceive64From32(Core::System& system, int32_t* out_index, uint32_t handles,
int32_t num_handles, Handle reply_target, int64_t timeout_ns) {
R_RETURN(ReplyAndReceive(system, out_index, handles, num_handles, reply_target, timeout_ns));
}
Result ReplyAndReceiveWithUserBuffer64From32(Core::System& system, int32_t* out_index,
uint32_t message_buffer, uint32_t message_buffer_size,
uint32_t handles, int32_t num_handles,
Handle reply_target, int64_t timeout_ns) {
R_RETURN(ReplyAndReceiveWithUserBuffer(system, out_index, message_buffer, message_buffer_size,
handles, num_handles, reply_target, timeout_ns));
}
} // namespace Kernel::Svc
+5 -21
View File
@@ -5,31 +5,15 @@
namespace Kernel::Svc {
void KernelDebug(Core::System& system, KernelDebugType kernel_debug_type, u64 arg0, u64 arg1,
u64 arg2) {
void KernelDebug([[maybe_unused]] Core::System& system, [[maybe_unused]] u32 kernel_debug_type,
[[maybe_unused]] u64 param1, [[maybe_unused]] u64 param2,
[[maybe_unused]] u64 param3) {
// Intentionally do nothing, as this does nothing in released kernel binaries.
}
void ChangeKernelTraceState(Core::System& system, KernelTraceState trace_state) {
void ChangeKernelTraceState([[maybe_unused]] Core::System& system,
[[maybe_unused]] u32 trace_state) {
// Intentionally do nothing, as this does nothing in released kernel binaries.
}
void KernelDebug64(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0,
uint64_t arg1, uint64_t arg2) {
KernelDebug(system, kern_debug_type, arg0, arg1, arg2);
}
void ChangeKernelTraceState64(Core::System& system, KernelTraceState kern_trace_state) {
ChangeKernelTraceState(system, kern_trace_state);
}
void KernelDebug64From32(Core::System& system, KernelDebugType kern_debug_type, uint64_t arg0,
uint64_t arg1, uint64_t arg2) {
KernelDebug(system, kern_debug_type, arg0, arg1, arg2);
}
void ChangeKernelTraceState64From32(Core::System& system, KernelTraceState kern_trace_state) {
ChangeKernelTraceState(system, kern_trace_state);
}
} // namespace Kernel::Svc
+1 -68
View File
@@ -1,73 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SendSyncRequestLight64(Core::System& system, Handle session_handle, u32* args) {
R_RETURN(SendSyncRequestLight(system, session_handle, args));
}
Result ReplyAndReceiveLight64(Core::System& system, Handle session_handle, u32* args) {
R_RETURN(ReplyAndReceiveLight(system, session_handle, args));
}
Result SendSyncRequestLight64From32(Core::System& system, Handle session_handle, u32* args) {
R_RETURN(SendSyncRequestLight(system, session_handle, args));
}
Result ReplyAndReceiveLight64From32(Core::System& system, Handle session_handle, u32* args) {
R_RETURN(ReplyAndReceiveLight(system, session_handle, args));
}
// Custom ABI implementation for light IPC.
template <typename F>
static void SvcWrap_LightIpc(Core::System& system, F&& cb) {
auto& core = system.CurrentArmInterface();
std::array<u32, 7> arguments{};
Handle session_handle = static_cast<Handle>(core.GetReg(0));
for (int i = 0; i < 7; i++) {
arguments[i] = static_cast<u32>(core.GetReg(i + 1));
}
Result ret = cb(system, session_handle, arguments.data());
core.SetReg(0, ret.raw);
for (int i = 0; i < 7; i++) {
core.SetReg(i + 1, arguments[i]);
}
}
void SvcWrap_SendSyncRequestLight64(Core::System& system) {
SvcWrap_LightIpc(system, SendSyncRequestLight64);
}
void SvcWrap_ReplyAndReceiveLight64(Core::System& system) {
SvcWrap_LightIpc(system, ReplyAndReceiveLight64);
}
void SvcWrap_SendSyncRequestLight64From32(Core::System& system) {
SvcWrap_LightIpc(system, SendSyncRequestLight64From32);
}
void SvcWrap_ReplyAndReceiveLight64From32(Core::System& system) {
SvcWrap_LightIpc(system, ReplyAndReceiveLight64From32);
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+8 -17
View File
@@ -24,7 +24,11 @@ Result ArbitrateLock(Core::System& system, Handle thread_handle, VAddr address,
return ResultInvalidAddress;
}
return GetCurrentProcess(system.Kernel()).WaitForAddress(thread_handle, address, tag);
return system.Kernel().CurrentProcess()->WaitForAddress(thread_handle, address, tag);
}
Result ArbitrateLock32(Core::System& system, Handle thread_handle, u32 address, u32 tag) {
return ArbitrateLock(system, thread_handle, address, tag);
}
/// Unlock a mutex
@@ -43,24 +47,11 @@ Result ArbitrateUnlock(Core::System& system, VAddr address) {
return ResultInvalidAddress;
}
return GetCurrentProcess(system.Kernel()).SignalToAddress(address);
return system.Kernel().CurrentProcess()->SignalToAddress(address);
}
Result ArbitrateLock64(Core::System& system, Handle thread_handle, uint64_t address, uint32_t tag) {
R_RETURN(ArbitrateLock(system, thread_handle, address, tag));
}
Result ArbitrateUnlock64(Core::System& system, uint64_t address) {
R_RETURN(ArbitrateUnlock(system, address));
}
Result ArbitrateLock64From32(Core::System& system, Handle thread_handle, uint32_t address,
uint32_t tag) {
R_RETURN(ArbitrateLock(system, thread_handle, address, tag));
}
Result ArbitrateUnlock64From32(Core::System& system, uint32_t address) {
R_RETURN(ArbitrateUnlock(system, address));
Result ArbitrateUnlock32(Core::System& system, u32 address) {
return ArbitrateUnlock(system, address);
}
} // namespace Kernel::Svc
+14 -42
View File
@@ -113,7 +113,7 @@ Result SetMemoryPermission(Core::System& system, VAddr address, u64 size, Memory
R_UNLESS(IsValidSetMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Validate that the region is in range for the current process.
auto& page_table = GetCurrentProcess(system.Kernel()).PageTable();
auto& page_table = system.Kernel().CurrentProcess()->PageTable();
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Set the memory attribute.
@@ -137,19 +137,23 @@ Result SetMemoryAttribute(Core::System& system, VAddr address, u64 size, u32 mas
R_UNLESS((mask | attr | SupportedMask) == SupportedMask, ResultInvalidCombination);
// Validate that the region is in range for the current process.
auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
auto& page_table{system.Kernel().CurrentProcess()->PageTable()};
R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory);
// Set the memory attribute.
return page_table.SetMemoryAttribute(address, size, mask, attr);
}
Result SetMemoryAttribute32(Core::System& system, u32 address, u32 size, u32 mask, u32 attr) {
return SetMemoryAttribute(system, address, size, mask, attr);
}
/// Maps a memory range into a different range.
Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size);
auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
auto& page_table{system.Kernel().CurrentProcess()->PageTable()};
if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
result.IsError()) {
@@ -159,12 +163,16 @@ Result MapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size)
return page_table.MapMemory(dst_addr, src_addr, size);
}
Result MapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) {
return MapMemory(system, dst_addr, src_addr, size);
}
/// Unmaps a region that was previously mapped with svcMapMemory
Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 size) {
LOG_TRACE(Kernel_SVC, "called, dst_addr=0x{:X}, src_addr=0x{:X}, size=0x{:X}", dst_addr,
src_addr, size);
auto& page_table{GetCurrentProcess(system.Kernel()).PageTable()};
auto& page_table{system.Kernel().CurrentProcess()->PageTable()};
if (const Result result{MapUnmapMemorySanityChecks(page_table, dst_addr, src_addr, size)};
result.IsError()) {
@@ -174,44 +182,8 @@ Result UnmapMemory(Core::System& system, VAddr dst_addr, VAddr src_addr, u64 siz
return page_table.UnmapMemory(dst_addr, src_addr, size);
}
Result SetMemoryPermission64(Core::System& system, uint64_t address, uint64_t size,
MemoryPermission perm) {
R_RETURN(SetMemoryPermission(system, address, size, perm));
}
Result SetMemoryAttribute64(Core::System& system, uint64_t address, uint64_t size, uint32_t mask,
uint32_t attr) {
R_RETURN(SetMemoryAttribute(system, address, size, mask, attr));
}
Result MapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address,
uint64_t size) {
R_RETURN(MapMemory(system, dst_address, src_address, size));
}
Result UnmapMemory64(Core::System& system, uint64_t dst_address, uint64_t src_address,
uint64_t size) {
R_RETURN(UnmapMemory(system, dst_address, src_address, size));
}
Result SetMemoryPermission64From32(Core::System& system, uint32_t address, uint32_t size,
MemoryPermission perm) {
R_RETURN(SetMemoryPermission(system, address, size, perm));
}
Result SetMemoryAttribute64From32(Core::System& system, uint32_t address, uint32_t size,
uint32_t mask, uint32_t attr) {
R_RETURN(SetMemoryAttribute(system, address, size, mask, attr));
}
Result MapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address,
uint32_t size) {
R_RETURN(MapMemory(system, dst_address, src_address, size));
}
Result UnmapMemory64From32(Core::System& system, uint32_t dst_address, uint32_t src_address,
uint32_t size) {
R_RETURN(UnmapMemory(system, dst_address, src_address, size));
Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u32 size) {
return UnmapMemory(system, dst_addr, src_addr, size);
}
} // namespace Kernel::Svc
+16 -64
View File
@@ -16,11 +16,18 @@ Result SetHeapSize(Core::System& system, VAddr* out_address, u64 size) {
R_UNLESS(size < MainMemorySizeMax, ResultInvalidSize);
// Set the heap size.
R_TRY(GetCurrentProcess(system.Kernel()).PageTable().SetHeapSize(out_address, size));
R_TRY(system.Kernel().CurrentProcess()->PageTable().SetHeapSize(out_address, size));
return ResultSuccess;
}
Result SetHeapSize32(Core::System& system, u32* heap_addr, u32 heap_size) {
VAddr temp_heap_addr{};
const Result result{SetHeapSize(system, &temp_heap_addr, heap_size)};
*heap_addr = static_cast<u32>(temp_heap_addr);
return result;
}
/// Maps memory at a desired address
Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
@@ -45,7 +52,7 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
return ResultInvalidMemoryRegion;
}
KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
KProcess* const current_process{system.Kernel().CurrentProcess()};
auto& page_table{current_process->PageTable()};
if (current_process->GetSystemResourceSize() == 0) {
@@ -70,6 +77,10 @@ Result MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
return page_table.MapPhysicalMemory(addr, size);
}
Result MapPhysicalMemory32(Core::System& system, u32 addr, u32 size) {
return MapPhysicalMemory(system, addr, size);
}
/// Unmaps memory previously mapped via MapPhysicalMemory
Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
LOG_DEBUG(Kernel_SVC, "called, addr=0x{:016X}, size=0x{:X}", addr, size);
@@ -94,7 +105,7 @@ Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
return ResultInvalidMemoryRegion;
}
KProcess* const current_process{GetCurrentProcessPointer(system.Kernel())};
KProcess* const current_process{system.Kernel().CurrentProcess()};
auto& page_table{current_process->PageTable()};
if (current_process->GetSystemResourceSize() == 0) {
@@ -119,67 +130,8 @@ Result UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size) {
return page_table.UnmapPhysicalMemory(addr, size);
}
Result MapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result UnmapPhysicalMemoryUnsafe(Core::System& system, uint64_t address, uint64_t size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetUnsafeLimit(Core::System& system, uint64_t limit) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result SetHeapSize64(Core::System& system, uint64_t* out_address, uint64_t size) {
R_RETURN(SetHeapSize(system, out_address, size));
}
Result MapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(MapPhysicalMemory(system, address, size));
}
Result UnmapPhysicalMemory64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(UnmapPhysicalMemory(system, address, size));
}
Result MapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(MapPhysicalMemoryUnsafe(system, address, size));
}
Result UnmapPhysicalMemoryUnsafe64(Core::System& system, uint64_t address, uint64_t size) {
R_RETURN(UnmapPhysicalMemoryUnsafe(system, address, size));
}
Result SetUnsafeLimit64(Core::System& system, uint64_t limit) {
R_RETURN(SetUnsafeLimit(system, limit));
}
Result SetHeapSize64From32(Core::System& system, uint64_t* out_address, uint32_t size) {
R_RETURN(SetHeapSize(system, out_address, size));
}
Result MapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(MapPhysicalMemory(system, address, size));
}
Result UnmapPhysicalMemory64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(UnmapPhysicalMemory(system, address, size));
}
Result MapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(MapPhysicalMemoryUnsafe(system, address, size));
}
Result UnmapPhysicalMemoryUnsafe64From32(Core::System& system, uint32_t address, uint32_t size) {
R_RETURN(UnmapPhysicalMemoryUnsafe(system, address, size));
}
Result SetUnsafeLimit64From32(Core::System& system, uint32_t limit) {
R_RETURN(SetUnsafeLimit(system, limit));
Result UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size) {
return UnmapPhysicalMemory(system, addr, size);
}
} // namespace Kernel::Svc
+3 -102
View File
@@ -5,7 +5,6 @@
#include "core/core.h"
#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_client_session.h"
#include "core/hle/kernel/k_object_name.h"
#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/svc.h"
@@ -35,7 +34,7 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_add
// Get the current handle table.
auto& kernel = system.Kernel();
auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
// Find the client port.
auto port = kernel.CreateNamedServicePort(port_name);
@@ -64,107 +63,9 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_add
return ResultSuccess;
}
Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
int32_t max_sessions, bool is_light, uint64_t name) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ConnectToNamedPort32(Core::System& system, Handle* out_handle, u32 port_name_address) {
Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
int32_t max_sessions) {
// Copy the provided name from user memory to kernel memory.
std::array<char, KObjectName::NameLengthMax> name{};
system.Memory().ReadBlock(user_name, name.data(), sizeof(name));
// Validate that sessions and name are valid.
R_UNLESS(max_sessions >= 0, ResultOutOfRange);
R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
if (max_sessions > 0) {
// Get the current handle table.
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
// Create a new port.
KPort* port = KPort::Create(system.Kernel());
R_UNLESS(port != nullptr, ResultOutOfResource);
// Initialize the new port.
port->Initialize(max_sessions, false, "");
// Register the port.
KPort::Register(system.Kernel(), port);
// Ensure that our only reference to the port is in the handle table when we're done.
SCOPE_EXIT({
port->GetClientPort().Close();
port->GetServerPort().Close();
});
// Register the handle in the table.
R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort())));
ON_RESULT_FAILURE {
handle_table.Remove(*out_server_handle);
};
// Create a new object name.
R_TRY(KObjectName::NewFromName(system.Kernel(), std::addressof(port->GetClientPort()),
name.data()));
} else /* if (max_sessions == 0) */ {
// Ensure that this else case is correct.
ASSERT(max_sessions == 0);
// If we're closing, there's no server handle.
*out_server_handle = InvalidHandle;
// Delete the object.
R_TRY(KObjectName::Delete<KClientPort>(system.Kernel(), name.data()));
}
R_SUCCEED();
}
Result ConnectToNamedPort64(Core::System& system, Handle* out_handle, uint64_t name) {
R_RETURN(ConnectToNamedPort(system, out_handle, name));
}
Result CreatePort64(Core::System& system, Handle* out_server_handle, Handle* out_client_handle,
int32_t max_sessions, bool is_light, uint64_t name) {
R_RETURN(
CreatePort(system, out_server_handle, out_client_handle, max_sessions, is_light, name));
}
Result ManageNamedPort64(Core::System& system, Handle* out_server_handle, uint64_t name,
int32_t max_sessions) {
R_RETURN(ManageNamedPort(system, out_server_handle, name, max_sessions));
}
Result ConnectToPort64(Core::System& system, Handle* out_handle, Handle port) {
R_RETURN(ConnectToPort(system, out_handle, port));
}
Result ConnectToNamedPort64From32(Core::System& system, Handle* out_handle, uint32_t name) {
R_RETURN(ConnectToNamedPort(system, out_handle, name));
}
Result CreatePort64From32(Core::System& system, Handle* out_server_handle,
Handle* out_client_handle, int32_t max_sessions, bool is_light,
uint32_t name) {
R_RETURN(
CreatePort(system, out_server_handle, out_client_handle, max_sessions, is_light, name));
}
Result ManageNamedPort64From32(Core::System& system, Handle* out_server_handle, uint32_t name,
int32_t max_sessions) {
R_RETURN(ManageNamedPort(system, out_server_handle, name, max_sessions));
}
Result ConnectToPort64From32(Core::System& system, Handle* out_handle, Handle port) {
R_RETURN(ConnectToPort(system, out_handle, port));
return ConnectToNamedPort(system, out_handle, port_name_address);
}
} // namespace Kernel::Svc
@@ -2,20 +2,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/svc.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel::Svc {
void SleepSystem(Core::System& system) {
UNIMPLEMENTED();
}
void SleepSystem64(Core::System& system) {
return SleepSystem(system);
}
void SleepSystem64From32(Core::System& system) {
return SleepSystem(system);
}
} // namespace Kernel::Svc
namespace Kernel::Svc {} // namespace Kernel::Svc
+28 -98
View File
@@ -9,7 +9,7 @@ namespace Kernel::Svc {
/// Exits the current process
void ExitProcess(Core::System& system) {
auto* current_process = GetCurrentProcessPointer(system.Kernel());
auto* current_process = system.Kernel().CurrentProcess();
LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
ASSERT_MSG(current_process->GetState() == KProcess::State::Running,
@@ -18,14 +18,18 @@ void ExitProcess(Core::System& system) {
system.Exit();
}
void ExitProcess32(Core::System& system) {
ExitProcess(system);
}
/// Gets the ID of the specified process or a specified thread's owning process.
Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
// Get the object from the handle table.
KScopedAutoObject obj = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KAutoObject>(static_cast<Handle>(handle));
KScopedAutoObject obj =
system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KAutoObject>(
static_cast<Handle>(handle));
R_UNLESS(obj.IsNotNull(), ResultInvalidHandle);
// Get the process from the object.
@@ -50,8 +54,17 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
return ResultSuccess;
}
Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_process_ids,
int32_t out_process_ids_size) {
Result GetProcessId32(Core::System& system, u32* out_process_id_low, u32* out_process_id_high,
Handle handle) {
u64 out_process_id{};
const auto result = GetProcessId(system, &out_process_id, handle);
*out_process_id_low = static_cast<u32>(out_process_id);
*out_process_id_high = static_cast<u32>(out_process_id >> 32);
return result;
}
Result GetProcessList(Core::System& system, u32* out_num_processes, VAddr out_process_ids,
u32 out_process_ids_size) {
LOG_DEBUG(Kernel_SVC, "called. out_process_ids=0x{:016X}, out_process_ids_size={}",
out_process_ids, out_process_ids_size);
@@ -63,10 +76,10 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_pr
return ResultOutOfRange;
}
auto& kernel = system.Kernel();
const auto& kernel = system.Kernel();
const auto total_copy_size = out_process_ids_size * sizeof(u64);
if (out_process_ids_size > 0 && !GetCurrentProcess(kernel).PageTable().IsInsideAddressSpace(
if (out_process_ids_size > 0 && !kernel.CurrentProcess()->PageTable().IsInsideAddressSpace(
out_process_ids, total_copy_size)) {
LOG_ERROR(Kernel_SVC, "Address range outside address space. begin=0x{:016X}, end=0x{:016X}",
out_process_ids, out_process_ids + total_copy_size);
@@ -76,8 +89,7 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_pr
auto& memory = system.Memory();
const auto& process_list = kernel.GetProcessList();
const auto num_processes = process_list.size();
const auto copy_amount =
std::min(static_cast<std::size_t>(out_process_ids_size), num_processes);
const auto copy_amount = std::min(std::size_t{out_process_ids_size}, num_processes);
for (std::size_t i = 0; i < copy_amount; ++i) {
memory.Write64(out_process_ids, process_list[i]->GetProcessID());
@@ -88,11 +100,10 @@ Result GetProcessList(Core::System& system, s32* out_num_processes, VAddr out_pr
return ResultSuccess;
}
Result GetProcessInfo(Core::System& system, s64* out, Handle process_handle,
ProcessInfoType info_type) {
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, info_type);
Result GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) {
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type);
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
@@ -100,95 +111,14 @@ Result GetProcessInfo(Core::System& system, s64* out, Handle process_handle,
return ResultInvalidHandle;
}
const auto info_type = static_cast<ProcessInfoType>(type);
if (info_type != ProcessInfoType::ProcessState) {
LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead",
info_type);
LOG_ERROR(Kernel_SVC, "Expected info_type to be ProcessState but got {} instead", type);
return ResultInvalidEnumValue;
}
*out = static_cast<s64>(process->GetState());
*out = static_cast<u64>(process->GetState());
return ResultSuccess;
}
Result CreateProcess(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps,
int32_t num_caps) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result StartProcess(Core::System& system, Handle process_handle, int32_t priority, int32_t core_id,
uint64_t main_thread_stack_size) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
Result TerminateProcess(Core::System& system, Handle process_handle) {
UNIMPLEMENTED();
R_THROW(ResultNotImplemented);
}
void ExitProcess64(Core::System& system) {
ExitProcess(system);
}
Result GetProcessId64(Core::System& system, uint64_t* out_process_id, Handle process_handle) {
R_RETURN(GetProcessId(system, out_process_id, process_handle));
}
Result GetProcessList64(Core::System& system, int32_t* out_num_processes, uint64_t out_process_ids,
int32_t max_out_count) {
R_RETURN(GetProcessList(system, out_num_processes, out_process_ids, max_out_count));
}
Result CreateProcess64(Core::System& system, Handle* out_handle, uint64_t parameters, uint64_t caps,
int32_t num_caps) {
R_RETURN(CreateProcess(system, out_handle, parameters, caps, num_caps));
}
Result StartProcess64(Core::System& system, Handle process_handle, int32_t priority,
int32_t core_id, uint64_t main_thread_stack_size) {
R_RETURN(StartProcess(system, process_handle, priority, core_id, main_thread_stack_size));
}
Result TerminateProcess64(Core::System& system, Handle process_handle) {
R_RETURN(TerminateProcess(system, process_handle));
}
Result GetProcessInfo64(Core::System& system, int64_t* out_info, Handle process_handle,
ProcessInfoType info_type) {
R_RETURN(GetProcessInfo(system, out_info, process_handle, info_type));
}
void ExitProcess64From32(Core::System& system) {
ExitProcess(system);
}
Result GetProcessId64From32(Core::System& system, uint64_t* out_process_id, Handle process_handle) {
R_RETURN(GetProcessId(system, out_process_id, process_handle));
}
Result GetProcessList64From32(Core::System& system, int32_t* out_num_processes,
uint32_t out_process_ids, int32_t max_out_count) {
R_RETURN(GetProcessList(system, out_num_processes, out_process_ids, max_out_count));
}
Result CreateProcess64From32(Core::System& system, Handle* out_handle, uint32_t parameters,
uint32_t caps, int32_t num_caps) {
R_RETURN(CreateProcess(system, out_handle, parameters, caps, num_caps));
}
Result StartProcess64From32(Core::System& system, Handle process_handle, int32_t priority,
int32_t core_id, uint64_t main_thread_stack_size) {
R_RETURN(StartProcess(system, process_handle, priority, core_id, main_thread_stack_size));
}
Result TerminateProcess64From32(Core::System& system, Handle process_handle) {
R_RETURN(TerminateProcess(system, process_handle));
}
Result GetProcessInfo64From32(Core::System& system, int64_t* out_info, Handle process_handle,
ProcessInfoType info_type) {
R_RETURN(GetProcessInfo(system, out_info, process_handle, info_type));
}
} // namespace Kernel::Svc
+7 -57
View File
@@ -37,15 +37,15 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, V
R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize);
R_UNLESS(size > 0, ResultInvalidSize);
R_UNLESS((address < address + size), ResultInvalidCurrentMemory);
R_UNLESS(address == static_cast<uint64_t>(address), ResultInvalidCurrentMemory);
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
R_UNLESS(address == static_cast<uintptr_t>(address), ResultInvalidCurrentMemory);
R_UNLESS(size == static_cast<size_t>(size), ResultInvalidCurrentMemory);
// Validate the memory permission.
R_UNLESS(IsValidProcessMemoryPermission(perm), ResultInvalidNewMemoryPermission);
// Get the process from its handle.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
system.CurrentProcess()->GetHandleTable().GetObject<KProcess>(process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the address is in range.
@@ -71,7 +71,7 @@ Result MapProcessMemory(Core::System& system, VAddr dst_address, Handle process_
R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory);
// Get the processes.
KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
KProcess* dst_process = system.CurrentProcess();
KScopedAutoObject src_process =
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
@@ -114,7 +114,7 @@ Result UnmapProcessMemory(Core::System& system, VAddr dst_address, Handle proces
R_UNLESS((src_address < src_address + size), ResultInvalidCurrentMemory);
// Get the processes.
KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
KProcess* dst_process = system.CurrentProcess();
KScopedAutoObject src_process =
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
@@ -174,7 +174,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
return ResultInvalidCurrentMemory;
}
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
@@ -242,7 +242,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
return ResultInvalidCurrentMemory;
}
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
@@ -271,54 +271,4 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
KPageTable::ICacheInvalidationStrategy::InvalidateAll);
}
Result SetProcessMemoryPermission64(Core::System& system, Handle process_handle, uint64_t address,
uint64_t size, MemoryPermission perm) {
R_RETURN(SetProcessMemoryPermission(system, process_handle, address, size, perm));
}
Result MapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle,
uint64_t src_address, uint64_t size) {
R_RETURN(MapProcessMemory(system, dst_address, process_handle, src_address, size));
}
Result UnmapProcessMemory64(Core::System& system, uint64_t dst_address, Handle process_handle,
uint64_t src_address, uint64_t size) {
R_RETURN(UnmapProcessMemory(system, dst_address, process_handle, src_address, size));
}
Result MapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address,
uint64_t src_address, uint64_t size) {
R_RETURN(MapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
}
Result UnmapProcessCodeMemory64(Core::System& system, Handle process_handle, uint64_t dst_address,
uint64_t src_address, uint64_t size) {
R_RETURN(UnmapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
}
Result SetProcessMemoryPermission64From32(Core::System& system, Handle process_handle,
uint64_t address, uint64_t size, MemoryPermission perm) {
R_RETURN(SetProcessMemoryPermission(system, process_handle, address, size, perm));
}
Result MapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle,
uint64_t src_address, uint32_t size) {
R_RETURN(MapProcessMemory(system, dst_address, process_handle, src_address, size));
}
Result UnmapProcessMemory64From32(Core::System& system, uint32_t dst_address, Handle process_handle,
uint64_t src_address, uint32_t size) {
R_RETURN(UnmapProcessMemory(system, dst_address, process_handle, src_address, size));
}
Result MapProcessCodeMemory64From32(Core::System& system, Handle process_handle,
uint64_t dst_address, uint64_t src_address, uint64_t size) {
R_RETURN(MapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
}
Result UnmapProcessCodeMemory64From32(Core::System& system, Handle process_handle,
uint64_t dst_address, uint64_t src_address, uint64_t size) {
R_RETURN(UnmapProcessCodeMemory(system, process_handle, dst_address, src_address, size));
}
} // namespace Kernel::Svc
+3 -7
View File
@@ -9,16 +9,12 @@
namespace Kernel::Svc {
/// Get which CPU core is executing the current thread
int32_t GetCurrentProcessorNumber(Core::System& system) {
u32 GetCurrentProcessorNumber(Core::System& system) {
LOG_TRACE(Kernel_SVC, "called");
return static_cast<int32_t>(system.CurrentPhysicalCore().CoreIndex());
return static_cast<u32>(system.CurrentPhysicalCore().CoreIndex());
}
int32_t GetCurrentProcessorNumber64(Core::System& system) {
return GetCurrentProcessorNumber(system);
}
int32_t GetCurrentProcessorNumber64From32(Core::System& system) {
u32 GetCurrentProcessorNumber32(Core::System& system) {
return GetCurrentProcessorNumber(system);
}

Some files were not shown because too many files have changed in this diff Show More