Merge master

This commit is contained in:
PabloMK7
2023-08-23 19:54:37 +02:00
131 changed files with 1617 additions and 1509 deletions
+24 -16
View File
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <exception>
#include <memory>
#include <stdexcept>
#include <utility>
#include <boost/serialization/array.hpp>
@@ -16,6 +14,8 @@
#include "core/arm/arm_interface.h"
#include "core/arm/exclusive_monitor.h"
#include "core/hle/service/cam/cam.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/ir/ir_user.h"
#if CITRA_ARCH(x86_64) || CITRA_ARCH(arm64)
#include "core/arm/dynarmic/arm_dynarmic.h"
#endif
@@ -35,9 +35,7 @@
#include "core/hle/service/cam/cam.h"
#include "core/hle/service/fs/archive.h"
#include "core/hle/service/gsp/gsp.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/ir/ir_rst.h"
#include "core/hle/service/ir/ir_user.h"
#include "core/hle/service/mic/mic_u.h"
#include "core/hle/service/plgldr/plgldr.h"
#include "core/hle/service/service.h"
@@ -48,6 +46,7 @@
#include "core/loader/loader.h"
#include "core/movie.h"
#include "core/rpc/server.h"
#include "core/telemetry_session.h"
#include "network/network.h"
#include "video_core/custom_textures/custom_tex_manager.h"
#include "video_core/renderer_base.h"
@@ -72,6 +71,8 @@ Core::Timing& Global() {
return System::GetInstance().CoreTiming();
}
System::System() : movie{*this} {}
System::~System() = default;
System::ResultStatus System::RunLoop(bool tight_loop) {
@@ -85,7 +86,7 @@ System::ResultStatus System::RunLoop(bool tight_loop) {
if (thread && running_core) {
running_core->SaveContext(thread->context);
}
GDBStub::HandlePacket();
GDBStub::HandlePacket(*this);
// If the loop is halted and we want to step, use a tiny (1) number of instructions to
// execute. Otherwise, get out of the loop function.
@@ -320,12 +321,12 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
cheat_engine = std::make_unique<Cheats::CheatEngine>(title_id, *this);
perf_stats = std::make_unique<PerfStats>(title_id);
if (Settings::values.dump_textures) {
custom_tex_manager->PrepareDumping(title_id);
}
if (Settings::values.custom_textures) {
custom_tex_manager->FindCustomTextures();
}
if (Settings::values.dump_textures) {
custom_tex_manager->WriteConfig();
}
status = ResultStatus::Success;
m_emu_window = &emu_window;
@@ -367,12 +368,13 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
const Kernel::New3dsHwCapabilities& n3ds_hw_caps, u32 num_cores) {
LOG_DEBUG(HW_Memory, "initialized OK");
memory = std::make_unique<Memory::MemorySystem>();
memory = std::make_unique<Memory::MemorySystem>(*this);
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue());
kernel = std::make_unique<Kernel::KernelSystem>(
*memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps);
*memory, *timing, [this] { PrepareReschedule(); }, memory_mode, num_cores, n3ds_hw_caps,
movie.GetOverrideInitTime());
exclusive_monitor = MakeExclusiveMonitor(*memory, num_cores);
cpu_cores.reserve(num_cores);
@@ -508,6 +510,14 @@ const VideoCore::CustomTexManager& System::CustomTexManager() const {
return *custom_tex_manager;
}
Core::Movie& System::Movie() {
return movie;
}
const Core::Movie& System::Movie() const {
return movie;
}
void System::RegisterMiiSelector(std::shared_ptr<Frontend::MiiSelector> mii_selector) {
registered_mii_selector = std::move(mii_selector);
}
@@ -617,16 +627,14 @@ void System::ApplySettings() {
if (VideoCore::g_renderer) {
auto& settings = VideoCore::g_renderer->Settings();
settings.bg_color_update_requested = true;
settings.sampler_update_requested = true;
settings.shader_update_requested = true;
settings.texture_filter_update_requested = true;
}
if (IsPoweredOn()) {
CoreTiming().UpdateClockSpeed(Settings::values.cpu_clock_percentage.GetValue());
Core::DSP().SetSink(Settings::values.output_type.GetValue(),
Settings::values.output_device.GetValue());
Core::DSP().EnableStretching(Settings::values.enable_audio_stretching.GetValue());
dsp_core->SetSink(Settings::values.output_type.GetValue(),
Settings::values.output_device.GetValue());
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
auto hid = Service::HID::GetModule(*this);
if (hid) {
@@ -704,7 +712,7 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
ar&* kernel.get();
VideoCore::serialize(ar, file_version);
if (file_version >= 1) {
ar& Movie::GetInstance();
ar& movie;
}
// This needs to be set from somewhere - might as well be here!
+26 -10
View File
@@ -10,18 +10,17 @@
#include <string>
#include <boost/serialization/version.hpp>
#include "common/common_types.h"
#include "core/frontend/applets/mii_selector.h"
#include "core/frontend/applets/swkbd.h"
#include "core/loader/loader.h"
#include "core/memory.h"
#include "core/arm/arm_interface.h"
#include "core/movie.h"
#include "core/perf_stats.h"
#include "core/telemetry_session.h"
class ARM_Interface;
namespace Frontend {
class EmuWindow;
class ImageInterface;
class MiiSelector;
class SoftwareKeyboard;
} // namespace Frontend
namespace Memory {
@@ -47,7 +46,9 @@ class ArchiveManager;
namespace Kernel {
class KernelSystem;
}
struct New3dsHwCapabilities;
enum class MemoryMode : u8;
} // namespace Kernel
namespace Cheats {
class CheatEngine;
@@ -62,8 +63,13 @@ class CustomTexManager;
class RendererBase;
} // namespace VideoCore
namespace Loader {
class AppLoader;
}
namespace Core {
class TelemetrySession;
class ExclusiveMonitor;
class Timing;
@@ -95,6 +101,7 @@ public:
ErrorUnknown ///< Any other error
};
explicit System();
~System();
/**
@@ -187,6 +194,10 @@ public:
return *cpu_cores[core_id];
};
[[nodiscard]] const ARM_Interface& GetCore(u32 core_id) const {
return *cpu_cores[core_id];
};
[[nodiscard]] u32 GetNumCores() const {
return static_cast<u32>(cpu_cores.size());
}
@@ -258,6 +269,12 @@ public:
/// Gets a const reference to the custom texture cache system
[[nodiscard]] const VideoCore::CustomTexManager& CustomTexManager() const;
/// Gets a reference to the movie recorder
[[nodiscard]] Core::Movie& Movie();
/// Gets a const reference to the movie recorder
[[nodiscard]] const Core::Movie& Movie() const;
/// Video Dumper interface
void RegisterVideoDumper(std::shared_ptr<VideoDumper::Backend> video_dumper);
@@ -373,6 +390,9 @@ private:
std::shared_ptr<Frontend::MiiSelector> registered_mii_selector;
std::shared_ptr<Frontend::SoftwareKeyboard> registered_swkbd;
/// Movie recorder
Core::Movie movie;
/// Cheats manager
std::unique_ptr<Cheats::CheatEngine> cheat_engine;
@@ -435,10 +455,6 @@ private:
return System::GetInstance().GetNumCores();
}
[[nodiscard]] inline AudioCore::DspInterface& DSP() {
return System::GetInstance().DSP();
}
} // namespace Core
BOOST_CLASS_VERSION(Core::System, 1)
+1 -1
View File
@@ -12,8 +12,8 @@
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/file_sys/romfs_reader.h"
#include "core/loader/loader.h"
enum NCSDContentIndex { Main = 0, Manual = 1, DLP = 2, New3DSUpdate = 6, Update = 7 };
+2 -3
View File
@@ -36,7 +36,6 @@
#include "core/gdbstub/gdbstub.h"
#include "core/gdbstub/hio.h"
#include "core/hle/kernel/process.h"
#include "core/loader/loader.h"
#include "core/memory.h"
namespace GDBStub {
@@ -1035,7 +1034,7 @@ static void RemoveBreakpoint() {
SendReply("OK");
}
void HandlePacket() {
void HandlePacket(Core::System& system) {
if (!IsConnected()) {
if (defer_start) {
ToggleServer(true);
@@ -1076,7 +1075,7 @@ void HandlePacket() {
Continue();
return;
case 'F':
HandleHioReply(command_buffer, command_length);
HandleHioReply(system, command_buffer, command_length);
break;
case 'g':
ReadRegisters();
+5 -1
View File
@@ -10,6 +10,10 @@
#include "common/common_types.h"
#include "core/hle/kernel/thread.h"
namespace Core {
class System;
}
namespace GDBStub {
/// Breakpoint Method
@@ -70,7 +74,7 @@ void Break(bool is_memory_break = false);
bool IsMemoryBreak();
/// Read and handle packet from gdb client.
void HandlePacket();
void HandlePacket(Core::System& system);
/**
* Get the nearest breakpoint of the specified type at the given address.
+11 -11
View File
@@ -54,7 +54,7 @@ static void SendErrorReply(int error_code, int retval = -1) {
SendReply(packet.data());
}
void SetHioRequest(const VAddr addr) {
void SetHioRequest(Core::System& system, const VAddr addr) {
if (!IsServerEnabled()) {
LOG_WARNING(Debug_GDBStub, "HIO requested but GDB stub is not running");
return;
@@ -69,15 +69,15 @@ void SetHioRequest(const VAddr addr) {
LOG_INFO(Debug_GDBStub, "overwriting existing HIO request that was not sent yet");
}
auto& memory = Core::System::GetInstance().Memory();
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
auto& memory = system.Memory();
const auto process = system.Kernel().GetCurrentProcess();
if (!memory.IsValidVirtualAddress(*process, addr)) {
LOG_WARNING(Debug_GDBStub, "Invalid address for HIO request");
return;
}
memory.ReadBlock(*process, addr, &current_hio_request, sizeof(PackedGdbHioRequest));
memory.ReadBlock(addr, &current_hio_request, sizeof(PackedGdbHioRequest));
if (current_hio_request.magic != std::array{'G', 'D', 'B', '\0'}) {
std::string_view bad_magic{
@@ -105,10 +105,11 @@ void SetHioRequest(const VAddr addr) {
Break();
SetCpuHaltFlag(true);
SetCpuStepFlag(false);
Core::GetRunningCore().ClearInstructionCache();
system.GetRunningCore().ClearInstructionCache();
}
void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
void HandleHioReply(Core::System& system, const u8* const command_buffer,
const u32 command_length) {
if (!IsWaitingForHioReply()) {
LOG_WARNING(Debug_GDBStub, "Got HIO reply but never sent a request");
return;
@@ -176,8 +177,8 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
current_hio_request.retval, current_hio_request.gdb_errno,
current_hio_request.ctrl_c);
const auto process = Core::System::GetInstance().Kernel().GetCurrentProcess();
auto& memory = Core::System::GetInstance().Memory();
const auto process = system.Kernel().GetCurrentProcess();
auto& memory = system.Memory();
// should have been checked when we first initialized the request,
// but just double check again before we write to memory
@@ -187,8 +188,7 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
return;
}
memory.WriteBlock(*process, current_hio_request_addr, &current_hio_request,
sizeof(PackedGdbHioRequest));
memory.WriteBlock(current_hio_request_addr, &current_hio_request, sizeof(PackedGdbHioRequest));
current_hio_request = {};
current_hio_request_addr = 0;
@@ -197,7 +197,7 @@ void HandleHioReply(const u8* const command_buffer, const u32 command_length) {
// Restore state from before the request came in
SetCpuStepFlag(was_stepping);
SetCpuHaltFlag(was_halted);
Core::GetRunningCore().ClearInstructionCache();
system.GetRunningCore().ClearInstructionCache();
}
bool HandlePendingHioRequestPacket() {
+6 -2
View File
@@ -6,6 +6,10 @@
#include "common/common_types.h"
namespace Core {
class System;
}
namespace GDBStub {
/**
@@ -47,7 +51,7 @@ static_assert(sizeof(PackedGdbHioRequest) == 152,
*
* @param address The memory address of the \ref PackedGdbHioRequest.
*/
void SetHioRequest(const VAddr address);
void SetHioRequest(Core::System& system, const VAddr address);
/**
* If there is a pending HIO request, send it to the client.
@@ -59,6 +63,6 @@ bool HandlePendingHioRequestPacket();
/**
* Process an HIO reply from the client.
*/
void HandleHioReply(const u8* const command_buffer, const u32 command_length);
void HandleHioReply(Core::System& system, const u8* const command_buffer, const u32 command_length);
} // namespace GDBStub
+1
View File
@@ -4,6 +4,7 @@
#include <algorithm>
#include <vector>
#include "common/archives.h"
#include "common/assert.h"
#include "common/common_types.h"
#include "core/core.h"
+2 -2
View File
@@ -25,13 +25,13 @@ namespace Kernel {
KernelSystem::KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
std::function<void()> prepare_reschedule_callback,
MemoryMode memory_mode, u32 num_cores,
const New3dsHwCapabilities& n3ds_hw_caps)
const New3dsHwCapabilities& n3ds_hw_caps, u64 override_init_time)
: memory(memory), timing(timing),
prepare_reschedule_callback(std::move(prepare_reschedule_callback)), memory_mode(memory_mode),
n3ds_hw_caps(n3ds_hw_caps) {
std::generate(memory_regions.begin(), memory_regions.end(),
[] { return std::make_shared<MemoryRegionInfo>(); });
MemoryInit(memory_mode, n3ds_hw_caps.memory_mode);
MemoryInit(memory_mode, n3ds_hw_caps.memory_mode, override_init_time);
resource_limits = std::make_unique<ResourceLimitList>(*this);
for (u32 core_id = 0; core_id < num_cores; ++core_id) {
+3 -2
View File
@@ -134,7 +134,8 @@ class KernelSystem {
public:
explicit KernelSystem(Memory::MemorySystem& memory, Core::Timing& timing,
std::function<void()> prepare_reschedule_callback, MemoryMode memory_mode,
u32 num_cores, const New3dsHwCapabilities& n3ds_hw_caps);
u32 num_cores, const New3dsHwCapabilities& n3ds_hw_caps,
u64 override_init_time = 0);
~KernelSystem();
using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>;
@@ -330,7 +331,7 @@ public:
Core::Timing& timing;
private:
void MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode);
void MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode, u64 override_init_time);
std::function<void()> prepare_reschedule_callback;
+3 -2
View File
@@ -37,7 +37,8 @@ static const u32 memory_region_sizes[8][3] = {
{0x0B200000, 0x02E00000, 0x02000000}, // 7
};
void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode) {
void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode,
u64 override_init_time) {
const bool is_new_3ds = Settings::values.is_new_3ds.GetValue();
u32 mem_type_index = static_cast<u32>(memory_mode);
u32 reported_mem_type = static_cast<u32>(memory_mode);
@@ -73,7 +74,7 @@ void KernelSystem::MemoryInit(MemoryMode memory_mode, New3dsMemoryMode n3ds_mode
config_mem.sys_mem_alloc = memory_regions[1]->size;
config_mem.base_mem_alloc = memory_regions[2]->size;
shared_page_handler = std::make_shared<SharedPage::Handler>(timing);
shared_page_handler = std::make_shared<SharedPage::Handler>(timing, override_init_time);
}
std::shared_ptr<MemoryRegionInfo> KernelSystem::GetMemoryRegion(MemoryRegion region) {
+5 -5
View File
@@ -19,7 +19,8 @@ namespace boost::serialization {
template <class Archive>
void load_construct_data(Archive& ar, SharedPage::Handler* t, const unsigned int) {
::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming());
::new (t) SharedPage::Handler(Core::System::GetInstance().CoreTiming(),
Core::System::GetInstance().Movie().GetOverrideInitTime());
}
template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t,
const unsigned int);
@@ -28,8 +29,7 @@ template void load_construct_data<iarchive>(iarchive& ar, SharedPage::Handler* t
namespace SharedPage {
static std::chrono::seconds GetInitTime() {
const u64 override_init_time = Core::Movie::GetInstance().GetOverrideInitTime();
static std::chrono::seconds GetInitTime(u64 override_init_time) {
if (override_init_time != 0) {
// Override the clock init time with the one in the movie
return std::chrono::seconds(override_init_time);
@@ -62,7 +62,7 @@ static std::chrono::seconds GetInitTime() {
}
}
Handler::Handler(Core::Timing& timing) : timing(timing) {
Handler::Handler(Core::Timing& timing, u64 override_init_time) : timing(timing) {
std::memset(&shared_page, 0, sizeof(shared_page));
shared_page.running_hw = 0x1; // product
@@ -76,7 +76,7 @@ Handler::Handler(Core::Timing& timing) : timing(timing) {
shared_page.battery_state.is_adapter_connected.Assign(1);
shared_page.battery_state.is_charging.Assign(1);
init_time = GetInitTime();
init_time = GetInitTime(override_init_time);
using namespace std::placeholders;
update_time_event = timing.RegisterEvent("SharedPage::UpdateTimeCallback",
+1 -1
View File
@@ -86,7 +86,7 @@ static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE,
class Handler : public BackingMem {
public:
Handler(Core::Timing& timing);
Handler(Core::Timing& timing, u64 override_init_time);
void SetMacAddress(const MacAddress&);
+4 -4
View File
@@ -5,6 +5,7 @@
#include <algorithm>
#include <array>
#include <fmt/format.h>
#include "common/archives.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/scm_rev.h"
@@ -38,7 +39,6 @@
#include "core/hle/lock.h"
#include "core/hle/result.h"
#include "core/hle/service/plgldr/plgldr.h"
#include "core/hle/service/service.h"
namespace Kernel {
@@ -1128,7 +1128,7 @@ void SVC::OutputDebugString(VAddr address, s32 len) {
}
if (len == 0) {
GDBStub::SetHioRequest(address);
GDBStub::SetHioRequest(system, address);
return;
}
@@ -1953,12 +1953,12 @@ ResultCode SVC::GetProcessList(s32* process_count, VAddr out_process_array,
}
ResultCode SVC::InvalidateInstructionCacheRange(u32 addr, u32 size) {
Core::GetRunningCore().InvalidateCacheRange(addr, size);
system.GetRunningCore().InvalidateCacheRange(addr, size);
return RESULT_SUCCESS;
}
ResultCode SVC::InvalidateEntireInstructionCache() {
Core::GetRunningCore().ClearInstructionCache();
system.GetRunningCore().ClearInstructionCache();
return RESULT_SUCCESS;
}
+1
View File
@@ -13,6 +13,7 @@
#include <boost/serialization/split_member.hpp>
#include "common/common_types.h"
#include "common/memory_ref.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/result.h"
#include "core/memory.h"
#include "core/mmio.h"
+1
View File
@@ -4,6 +4,7 @@
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/act/act.h"
#include "core/hle/service/act/act_a.h"
#include "core/hle/service/act/act_u.h"
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/archives.h"
#include "common/file_util.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/frontend/input.h"
+2
View File
@@ -33,6 +33,8 @@
#include "core/hle/service/service.h"
#include "core/hw/aes/ccm.h"
#include "core/hw/aes/key.h"
#include "core/loader/loader.h"
#include "core/telemetry_session.h"
SERVICE_CONSTRUCT_IMPL(Service::APT::Module)
+1 -1
View File
@@ -6,9 +6,9 @@
#include <cstring>
#include <ctime>
#include <vector>
#include "common/archives.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/result.h"
+4 -4
View File
@@ -150,7 +150,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
circle_pad_old_y.erase(circle_pad_old_y.begin());
circle_pad_old_y.push_back(circle_pad_new_y);
Core::Movie::GetInstance().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y);
system.Movie().HandlePadAndCircleStatus(state, circle_pad_x, circle_pad_y);
const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y);
state.circle_up.Assign(direction.up);
@@ -200,7 +200,7 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight);
touch_entry.valid.Assign(pressed ? 1 : 0);
Core::Movie::GetInstance().HandleTouchStatus(touch_entry);
system.Movie().HandleTouchStatus(touch_entry);
// TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which
// supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being
@@ -246,7 +246,7 @@ void Module::UpdateAccelerometerCallback(std::uintptr_t user_data, s64 cycles_la
accelerometer_entry.y = static_cast<s16>(accel.y);
accelerometer_entry.z = static_cast<s16>(accel.z);
Core::Movie::GetInstance().HandleAccelerometerStatus(accelerometer_entry);
system.Movie().HandleAccelerometerStatus(accelerometer_entry);
// Make up "raw" entry
// TODO(wwylele):
@@ -287,7 +287,7 @@ void Module::UpdateGyroscopeCallback(std::uintptr_t user_data, s64 cycles_late)
gyroscope_entry.y = static_cast<s16>(gyro.y);
gyroscope_entry.z = static_cast<s16>(gyro.z);
Core::Movie::GetInstance().HandleGyroscopeStatus(gyroscope_entry);
system.Movie().HandleGyroscopeStatus(gyroscope_entry);
// Make up "raw" entry
mem->gyroscope.raw_entry.x = gyroscope_entry.x;
+35
View File
@@ -31,6 +31,10 @@ namespace Core {
class System;
}
namespace IPC {
class RequestParser;
}
namespace Service::HTTP {
enum class RequestMethod : u8 {
@@ -362,6 +366,37 @@ private:
void SetProxyDefault(Kernel::HLERequestContext& ctx);
/**
* HTTP_C::ReceiveData service function
* Inputs:
* 1 : Context handle
* 2 : Buffer size
* 3 : (OutSize<<4) | 12
* 4 : Output data pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void ReceiveData(Kernel::HLERequestContext& ctx);
/**
* HTTP_C::ReceiveDataTimeout service function
* Inputs:
* 1 : Context handle
* 2 : Buffer size
* 3-4 : u64 nanoseconds delay
* 5 : (OutSize<<4) | 12
* 6 : Output data pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void ReceiveDataTimeout(Kernel::HLERequestContext& ctx);
/**
* ReceiveDataImpl:
* Implements ReceiveData and ReceiveDataTimeout service functions
*/
void ReceiveDataImpl(Kernel::HLERequestContext& ctx, bool timeout);
/**
* HTTP_C::AddRequestHeader service function
* Inputs:
+3 -4
View File
@@ -5,8 +5,6 @@
#include <fmt/format.h>
#include "common/alignment.h"
#include "common/settings.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/service/ir/extra_hid.h"
#include "core/movie.h"
@@ -65,7 +63,8 @@ enum class ResponseID : u8 {
ReadCalibrationData = 0x11,
};
ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing) : IRDevice(send_func), timing(timing) {
ExtraHID::ExtraHID(SendFunc send_func, Core::Timing& timing_, Core::Movie& movie_)
: IRDevice(send_func), timing{timing_}, movie{movie_} {
LoadInputDevices();
// The data below was retrieved from a New 3DS
@@ -249,7 +248,7 @@ void ExtraHID::SendHIDStatus() {
response.buttons.r_not_held.Assign(1);
response.unknown = 0;
Core::Movie::GetInstance().HandleExtraHidResponse(response);
movie.HandleExtraHidResponse(response);
std::vector<u8> response_buffer(sizeof(response));
memcpy(response_buffer.data(), &response, sizeof(response));
+3 -1
View File
@@ -16,6 +16,7 @@
namespace Core {
struct TimingEventType;
class Timing;
class Movie;
} // namespace Core
namespace Service::IR {
@@ -43,7 +44,7 @@ static_assert(sizeof(ExtraHIDResponse) == 6, "HID status response has wrong size
*/
class ExtraHID final : public IRDevice {
public:
explicit ExtraHID(SendFunc send_func, Core::Timing& timing);
explicit ExtraHID(SendFunc send_func, Core::Timing& timing, Core::Movie& movie);
~ExtraHID();
void OnConnect() override;
@@ -60,6 +61,7 @@ private:
void LoadInputDevices();
Core::Timing& timing;
Core::Movie& movie;
u8 hid_period;
Core::TimingEventType* hid_polling_callback_id;
std::array<u8, 0x40> calibration_data;
+1 -1
View File
@@ -83,7 +83,7 @@ void IR_RST::UpdateCallback(std::uintptr_t user_data, s64 cycles_late) {
s16 c_stick_x = static_cast<s16>(c_stick_x_f * MAX_CSTICK_RADIUS);
s16 c_stick_y = static_cast<s16>(c_stick_y_f * MAX_CSTICK_RADIUS);
Core::Movie::GetInstance().HandleIrRst(state, c_stick_x, c_stick_y);
system.Movie().HandleIrRst(state, c_stick_x, c_stick_y);
if (!raw_c_stick) {
const HID::DirectionState direction = HID::GetStickDirectionState(c_stick_x, c_stick_y);
+2 -2
View File
@@ -9,7 +9,7 @@
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/unique_ptr.hpp>
#include <fmt/format.h>
#include "common/string_util.h"
#include "common/archives.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
@@ -467,7 +467,7 @@ IR_USER::IR_USER(Core::System& system) : ServiceFramework("ir:USER", 1) {
receive_event = system.Kernel().CreateEvent(ResetType::OneShot, "IR:ReceiveEvent");
extra_hid = std::make_unique<ExtraHID>([this](std::span<const u8> data) { PutToReceive(data); },
system.CoreTiming());
system.CoreTiming(), system.Movie());
}
IR_USER::~IR_USER() {
+2 -1
View File
@@ -7,13 +7,14 @@
#include <boost/crc.hpp>
#include <cryptopp/osrng.h>
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/kernel/shared_page.h"
#include "core/hle/service/nfc/amiibo_crypto.h"
#include "core/hle/service/nfc/nfc_device.h"
#include "core/hw/aes/key.h"
#include "core/loader/loader.h"
SERVICE_CONSTRUCT_IMPL(Service::NFC::NfcDevice)
+1
View File
@@ -6,6 +6,7 @@
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/nim/nim_u.h"
SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U)
+1
View File
@@ -53,6 +53,7 @@
#include "core/hle/service/sm/srv.h"
#include "core/hle/service/soc/soc_u.h"
#include "core/hle/service/ssl/ssl_c.h"
#include "core/loader/loader.h"
namespace Service {
-1
View File
@@ -14,7 +14,6 @@
#include "common/file_util.h"
#include "core/file_sys/romfs_reader.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/object.h"
namespace Kernel {
struct AddressMapping;
+1
View File
@@ -27,6 +27,7 @@
#include "core/loader/smdh.h"
#include "core/memory.h"
#include "core/system_titles.h"
#include "core/telemetry_session.h"
#include "network/network.h"
namespace Loader {
+25 -24
View File
@@ -17,9 +17,7 @@
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/global.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/process.h"
#include "core/hle/lock.h"
#include "core/hle/service/plgldr/plgldr.h"
#include "core/hw/hw.h"
#include "core/memory.h"
@@ -89,12 +87,13 @@ private:
class MemorySystem::Impl {
public:
// Visual Studio would try to allocate these on compile time if they are std::array, which would
// exceed the memory limit.
// Visual Studio would try to allocate these on compile time
// if they are std::array which would exceed the memory limit.
std::unique_ptr<u8[]> fcram = std::make_unique<u8[]>(Memory::FCRAM_N3DS_SIZE);
std::unique_ptr<u8[]> vram = std::make_unique<u8[]>(Memory::VRAM_SIZE);
std::unique_ptr<u8[]> n3ds_extra_ram = std::make_unique<u8[]>(Memory::N3DS_EXTRA_RAM_SIZE);
Core::System& system;
std::shared_ptr<PageTable> current_page_table = nullptr;
RasterizerCacheMarker cache_marker;
std::vector<std::shared_ptr<PageTable>> page_table_list;
@@ -106,7 +105,7 @@ public:
std::shared_ptr<BackingMem> n3ds_extra_ram_mem;
std::shared_ptr<BackingMem> dsp_mem;
Impl();
Impl(Core::System& system_);
const u8* GetPtr(Region r) const {
switch (r) {
@@ -153,6 +152,10 @@ public:
}
}
u32 GetPC() const noexcept {
return system.GetRunningCore().GetPC();
}
/**
* This function should only be called for virtual addreses with attribute `PageType::Special`.
*/
@@ -187,7 +190,7 @@ public:
HW_Memory,
"unmapped ReadBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
"0x{:08X}",
current_vaddr, src_addr, size, Core::GetRunningCore().GetPC());
current_vaddr, src_addr, size, GetPC());
std::memset(dest_buffer, 0, copy_amount);
break;
}
@@ -242,7 +245,7 @@ public:
HW_Memory,
"unmapped WriteBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
"0x{:08X}",
current_vaddr, dest_addr, size, Core::GetRunningCore().GetPC());
current_vaddr, dest_addr, size, GetPC());
break;
}
case PageType::Memory: {
@@ -345,13 +348,13 @@ private:
friend class boost::serialization::access;
};
MemorySystem::Impl::Impl()
: fcram_mem(std::make_shared<BackingMemImpl<Region::FCRAM>>(*this)),
MemorySystem::Impl::Impl(Core::System& system_)
: system{system_}, fcram_mem(std::make_shared<BackingMemImpl<Region::FCRAM>>(*this)),
vram_mem(std::make_shared<BackingMemImpl<Region::VRAM>>(*this)),
n3ds_extra_ram_mem(std::make_shared<BackingMemImpl<Region::N3DS>>(*this)),
dsp_mem(std::make_shared<BackingMemImpl<Region::DSP>>(*this)) {}
MemorySystem::MemorySystem() : impl(std::make_unique<Impl>()) {}
MemorySystem::MemorySystem(Core::System& system) : impl(std::make_unique<Impl>(system)) {}
MemorySystem::~MemorySystem() = default;
template <class Archive>
@@ -467,7 +470,7 @@ T MemorySystem::Read(const VAddr vaddr) {
switch (type) {
case PageType::Unmapped:
LOG_ERROR(HW_Memory, "unmapped Read{} @ 0x{:08X} at PC 0x{:08X}", sizeof(T) * 8, vaddr,
Core::GetRunningCore().GetPC());
impl->GetPC());
return 0;
case PageType::Memory:
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
@@ -518,7 +521,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) {
switch (type) {
case PageType::Unmapped:
LOG_ERROR(HW_Memory, "unmapped Write{} 0x{:08X} @ 0x{:08X} at PC 0x{:08X}",
sizeof(data) * 8, (u32)data, vaddr, Core::GetRunningCore().GetPC());
sizeof(data) * 8, (u32)data, vaddr, impl->GetPC());
return;
case PageType::Memory:
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
@@ -550,7 +553,7 @@ bool MemorySystem::WriteExclusive(const VAddr vaddr, const T data, const T expec
switch (type) {
case PageType::Unmapped:
LOG_ERROR(HW_Memory, "unmapped Write{} 0x{:08X} @ 0x{:08X} at PC 0x{:08X}",
sizeof(data) * 8, (u32)data, vaddr, Core::GetRunningCore().GetPC());
sizeof(data) * 8, static_cast<u32>(data), vaddr, impl->GetPC());
return true;
case PageType::Memory:
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:08X}", vaddr);
@@ -606,8 +609,7 @@ u8* MemorySystem::GetPointer(const VAddr vaddr) {
return GetPointerForRasterizerCache(vaddr);
}
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x{:08x} at PC 0x{:08X}", vaddr,
Core::GetRunningCore().GetPC());
LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x{:08x} at PC 0x{:08X}", vaddr, impl->GetPC());
return nullptr;
}
@@ -663,7 +665,7 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const {
if (area == memory_areas.end()) {
LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#08X} at PC {:#08X}", address,
Core::GetRunningCore().GetPC());
impl->GetPC());
return nullptr;
}
@@ -693,8 +695,7 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const {
return {target_mem, offset_into_region};
}
/// For a rasterizer-accessible PAddr, gets a list of all possible VAddr
static std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr) {
std::vector<VAddr> MemorySystem::PhysicalToVirtualAddressForRasterizer(PAddr addr) {
if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) {
return {addr - VRAM_PADDR + VRAM_VADDR};
}
@@ -714,7 +715,7 @@ static std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr) {
// parts of the texture.
LOG_ERROR(HW_Memory,
"Trying to use invalid physical address for rasterizer: {:08X} at PC 0x{:08X}", addr,
Core::GetRunningCore().GetPC());
impl->GetPC());
return {};
}
@@ -729,7 +730,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached
for (unsigned i = 0; i < num_pages; ++i, paddr += CITRA_PAGE_SIZE) {
for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) {
impl->cache_marker.Mark(vaddr, cached);
for (auto page_table : impl->page_table_list) {
for (auto& page_table : impl->page_table_list) {
PageType& page_type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
if (cached) {
@@ -868,7 +869,7 @@ void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_add
}
void MemorySystem::ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) {
const auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
const auto& process = *impl->system.Kernel().GetCurrentProcess();
return impl->ReadBlockImpl<false>(process, src_addr, dest_buffer, size);
}
@@ -911,7 +912,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a
void MemorySystem::WriteBlock(const VAddr dest_addr, const void* src_buffer,
const std::size_t size) {
auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess();
auto& process = *impl->system.Kernel().GetCurrentProcess();
return impl->WriteBlockImpl<false>(process, dest_addr, src_buffer, size);
}
@@ -934,7 +935,7 @@ void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_ad
LOG_ERROR(HW_Memory,
"unmapped ZeroBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
"0x{:08X}",
current_vaddr, dest_addr, size, Core::GetRunningCore().GetPC());
current_vaddr, dest_addr, size, impl->GetPC());
break;
}
case PageType::Memory: {
@@ -989,7 +990,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& dest_process,
LOG_ERROR(HW_Memory,
"unmapped CopyBlock @ 0x{:08X} (start address = 0x{:08X}, size = {}) at PC "
"0x{:08X}",
current_vaddr, src_addr, size, Core::GetRunningCore().GetPC());
current_vaddr, src_addr, size, impl->GetPC());
ZeroBlock(dest_process, dest_addr, copy_amount);
break;
}
+9 -1
View File
@@ -18,6 +18,10 @@ namespace Kernel {
class Process;
}
namespace Core {
class System;
}
namespace AudioCore {
class DspInterface;
}
@@ -287,7 +291,7 @@ void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode);
class MemorySystem {
public:
MemorySystem();
explicit MemorySystem(Core::System& system);
~MemorySystem();
/**
@@ -575,6 +579,9 @@ public:
*/
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached);
/// For a rasterizer-accessible PAddr, gets a list of all possible VAddr
std::vector<VAddr> PhysicalToVirtualAddressForRasterizer(PAddr addr);
/// Gets a pointer to the memory region beginning at the specified physical address.
u8* GetPhysicalPointer(PAddr address) const;
@@ -627,6 +634,7 @@ private:
void MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, PageType type);
private:
class Impl;
std::unique_ptr<Impl> impl;
+7 -6
View File
@@ -10,13 +10,11 @@
#include <boost/optional.hpp>
#include <cryptopp/hex.h>
#include <cryptopp/osrng.h>
#include <fmt/format.h>
#include "common/archives.h"
#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/scm_rev.h"
#include "common/string_util.h"
#include "common/swap.h"
#include "common/timer.h"
#include "core/core.h"
@@ -24,12 +22,11 @@
#include "core/hle/service/ir/extra_hid.h"
#include "core/hle/service/ir/ir_rst.h"
#include "core/hw/gpu.h"
#include "core/loader/loader.h"
#include "core/movie.h"
namespace Core {
/*static*/ Movie Movie::s_instance;
enum class ControllerStateType : u8 {
PadAndCircle,
Touch,
@@ -146,6 +143,10 @@ static u64 GetInputCount(std::span<const u8> input) {
return input_count;
}
Movie::Movie(const Core::System& system_) : system{system_} {}
Movie::~Movie() = default;
template <class Archive>
void Movie::serialize(Archive& ar, const unsigned int file_version) {
// Only serialize what's needed to make savestates useful for TAS:
@@ -565,7 +566,7 @@ void Movie::StartRecording(const std::string& movie_file, const std::string& aut
// Get program ID
program_id = 0;
Core::System::GetInstance().GetAppLoader().ReadProgramId(program_id);
system.GetAppLoader().ReadProgramId(program_id);
LOG_INFO(Movie, "Enabling Movie recording, ID: {:016X}", id);
}
+15 -11
View File
@@ -23,25 +23,29 @@ union PadState;
} // namespace Service
namespace Core {
class System;
struct CTMHeader;
struct ControllerState;
class Movie {
public:
enum class PlayMode { None, Recording, Playing, MovieFinished };
enum class ValidationResult {
enum class PlayMode : u32 {
None,
Recording,
Playing,
MovieFinished,
};
enum class ValidationResult : u32 {
OK,
RevisionDismatch,
InputCountDismatch,
Invalid,
};
/**
* Gets the instance of the Movie singleton class.
* @returns Reference to the instance of the Movie singleton class.
*/
static Movie& GetInstance() {
return s_instance;
}
explicit Movie(const Core::System& system);
~Movie();
void SetPlaybackCompletionCallback(std::function<void()> completion_callback);
void StartPlayback(const std::string& movie_file);
@@ -133,8 +137,6 @@ public:
void SaveMovie();
private:
static Movie s_instance;
void CheckInputEnd();
template <typename... Targs>
@@ -159,6 +161,8 @@ private:
ValidationResult ValidateHeader(const CTMHeader& header) const;
ValidationResult ValidateInput(std::span<const u8> input, u64 expected_count) const;
private:
const Core::System& system;
PlayMode play_mode;
std::string record_movie_file;
+14 -10
View File
@@ -3,11 +3,14 @@
// Refer to the license.txt file included.
#include <chrono>
#include <sstream>
#include <cryptopp/hex.h>
#include <fmt/format.h>
#include "common/archives.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/scm_rev.h"
#include "common/swap.h"
#include "common/zstd_compression.h"
#include "core/core.h"
#include "core/movie.h"
@@ -30,8 +33,7 @@ static_assert(sizeof(CSTHeader) == 256, "CSTHeader should be 256 bytes");
constexpr std::array<u8, 4> header_magic_bytes{{'C', 'S', 'T', 0x1B}};
static std::string GetSaveStatePath(u64 program_id, u32 slot) {
const u64 movie_id = Movie::GetInstance().GetCurrentMovieID();
static std::string GetSaveStatePath(u64 program_id, u64 movie_id, u32 slot) {
if (movie_id) {
return fmt::format("{}{:016X}.movie{:016X}.{:02d}.cst",
FileUtil::GetUserPath(FileUtil::UserPath::StatesDir), program_id,
@@ -43,8 +45,8 @@ static std::string GetSaveStatePath(u64 program_id, u32 slot) {
}
static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64 program_id,
u32 slot) {
const auto path = GetSaveStatePath(program_id, slot);
u64 movie_id, u32 slot) {
const auto path = GetSaveStatePath(program_id, movie_id, slot);
if (header.filetype != header_magic_bytes) {
LOG_WARNING(Core, "Invalid save state file {}", path);
return false;
@@ -66,11 +68,11 @@ static bool ValidateSaveState(const CSTHeader& header, SaveStateInfo& info, u64
return true;
}
std::vector<SaveStateInfo> ListSaveStates(u64 program_id) {
std::vector<SaveStateInfo> ListSaveStates(u64 program_id, u64 movie_id) {
std::vector<SaveStateInfo> result;
result.reserve(SaveStateSlotCount);
for (u32 slot = 1; slot <= SaveStateSlotCount; ++slot) {
const auto path = GetSaveStatePath(program_id, slot);
const auto path = GetSaveStatePath(program_id, movie_id, slot);
if (!FileUtil::Exists(path)) {
continue;
}
@@ -92,7 +94,7 @@ std::vector<SaveStateInfo> ListSaveStates(u64 program_id) {
LOG_ERROR(Core, "Could not read from file {}", path);
continue;
}
if (!ValidateSaveState(header, info, program_id, slot)) {
if (!ValidateSaveState(header, info, program_id, movie_id, slot)) {
continue;
}
@@ -111,7 +113,8 @@ void System::SaveState(u32 slot) const {
const auto data = std::span<const u8>{reinterpret_cast<const u8*>(str.data()), str.size()};
auto buffer = Common::Compression::CompressDataZSTDDefault(data);
const auto path = GetSaveStatePath(title_id, slot);
const u64 movie_id = movie.GetCurrentMovieID();
const auto path = GetSaveStatePath(title_id, movie_id, slot);
if (!FileUtil::CreateFullPath(path)) {
throw std::runtime_error("Could not create path " + path);
}
@@ -143,7 +146,8 @@ void System::LoadState(u32 slot) {
throw std::runtime_error("Unable to load while connected to multiplayer");
}
const auto path = GetSaveStatePath(title_id, slot);
const u64 movie_id = movie.GetCurrentMovieID();
const auto path = GetSaveStatePath(title_id, movie_id, slot);
std::vector<u8> decompressed;
{
@@ -159,7 +163,7 @@ void System::LoadState(u32 slot) {
// validate header
SaveStateInfo info;
if (!ValidateSaveState(header, info, title_id, slot)) {
if (!ValidateSaveState(header, info, title_id, movie_id, slot)) {
throw std::runtime_error("Invalid savestate");
}
+1 -1
View File
@@ -20,6 +20,6 @@ struct SaveStateInfo {
constexpr u32 SaveStateSlotCount = 10; // Maximum count of savestate slots
std::vector<SaveStateInfo> ListSaveStates(u64 program_id);
std::vector<SaveStateInfo> ListSaveStates(u64 program_id, u64 movie_id);
} // namespace Core
+1
View File
@@ -11,6 +11,7 @@
#include "common/scm_rev.h"
#include "common/settings.h"
#include "core/core.h"
#include "core/loader/loader.h"
#include "core/telemetry_session.h"
#include "network/network_settings.h"