diff options
Diffstat (limited to 'src/core/core.cpp')
-rw-r--r-- | src/core/core.cpp | 107 |
1 files changed, 103 insertions, 4 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index ff0721079..3d0978cbf 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -19,25 +19,55 @@ #include "core/file_sys/vfs_concat.h" #include "core/file_sys/vfs_real.h" #include "core/gdbstub/gdbstub.h" +#include "core/hardware_interrupt_manager.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/thread.h" #include "core/hle/service/am/applets/applets.h" +#include "core/hle/service/apm/controller.h" +#include "core/hle/service/glue/manager.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/loader/loader.h" #include "core/perf_stats.h" +#include "core/reporter.h" #include "core/settings.h" #include "core/telemetry_session.h" +#include "core/tools/freezer.h" #include "file_sys/cheat_engine.h" +#include "file_sys/patch_manager.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" namespace Core { +namespace { + +FileSys::StorageId GetStorageIdForFrontendSlot( + std::optional<FileSys::ContentProviderUnionSlot> slot) { + if (!slot.has_value()) { + return FileSys::StorageId::None; + } + + switch (*slot) { + case FileSys::ContentProviderUnionSlot::UserNAND: + return FileSys::StorageId::NandUser; + case FileSys::ContentProviderUnionSlot::SysNAND: + return FileSys::StorageId::NandSystem; + case FileSys::ContentProviderUnionSlot::SDMC: + return FileSys::StorageId::SdCard; + case FileSys::ContentProviderUnionSlot::FrontendManual: + return FileSys::StorageId::Host; + default: + return FileSys::StorageId::None; + } +} + +} // Anonymous namespace + /*static*/ System System::s_instance; FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, @@ -74,7 +104,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, return vfs->OpenFile(path, FileSys::Mode::Read); } struct System::Impl { - explicit Impl(System& system) : kernel{system}, cpu_core_manager{system} {} + explicit Impl(System& system) + : kernel{system}, cpu_core_manager{system}, applet_manager{system}, reporter{system} {} Cpu& CurrentCpuCore() { return cpu_core_manager.GetCurrentCore(); @@ -109,17 +140,20 @@ struct System::Impl { /// Create default implementations of applets if one is not provided. applet_manager.SetDefaultAppletsIfMissing(); + /// Reset all glue registrations + arp_manager.ResetAll(); + telemetry_session = std::make_unique<Core::TelemetrySession>(); service_manager = std::make_shared<Service::SM::ServiceManager>(); - Service::Init(service_manager, system, *virtual_filesystem); + Service::Init(service_manager, system); GDBStub::Init(); renderer = VideoCore::CreateRenderer(emu_window, system); if (!renderer->Init()) { return ResultStatus::ErrorVideoCore; } - + interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system); gpu_core = VideoCore::CreateGPU(system); is_powered_on = true; @@ -150,7 +184,8 @@ struct System::Impl { } telemetry_session->AddInitialInfo(*app_loader); - auto main_process = Kernel::Process::Create(system, "main"); + auto main_process = + Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland); const auto [load_result, load_parameters] = app_loader->Load(*main_process); if (load_result != Loader::ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); @@ -159,6 +194,7 @@ struct System::Impl { return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + static_cast<u32>(load_result)); } + AddGlueRegistrationForProcess(*app_loader, *main_process); kernel.MakeCurrentProcess(main_process.get()); // Main process has been loaded and been made current. @@ -217,6 +253,31 @@ struct System::Impl { return app_loader->ReadTitle(out); } + void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::Process& process) { + std::vector<u8> nacp_data; + FileSys::NACP nacp; + if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) { + nacp_data = nacp.GetRawBytes(); + } else { + nacp_data.resize(sizeof(FileSys::RawNACP)); + } + + Service::Glue::ApplicationLaunchProperty launch{}; + launch.title_id = process.GetTitleID(); + + FileSys::PatchManager pm{launch.title_id}; + launch.version = pm.GetGameVersion().value_or(0); + + // TODO(DarkLordZach): When FSController/Game Card Support is added, if + // current_process_game_card use correct StorageId + launch.base_game_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry( + launch.title_id, FileSys::ContentRecordType::Program)); + launch.update_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry( + FileSys::GetUpdateTitleID(launch.title_id), FileSys::ContentRecordType::Program)); + + arp_manager.Register(launch.title_id, launch, std::move(nacp_data)); + } + void SetStatus(ResultStatus new_status, const char* details = nullptr) { status = new_status; if (details) { @@ -239,20 +300,30 @@ struct System::Impl { std::unique_ptr<VideoCore::RendererBase> renderer; std::unique_ptr<Tegra::GPU> gpu_core; std::shared_ptr<Tegra::DebugContext> debug_context; + std::unique_ptr<Core::Hardware::InterruptManager> interrupt_manager; CpuCoreManager cpu_core_manager; bool is_powered_on = false; std::unique_ptr<FileSys::CheatEngine> cheat_engine; + std::unique_ptr<Tools::Freezer> memory_freezer; /// Frontend applets Service::AM::Applets::AppletManager applet_manager; + /// APM (Performance) services + Service::APM::Controller apm_controller{core_timing}; + + /// Glue services + Service::Glue::ARPManager arp_manager; + /// Service manager std::shared_ptr<Service::SM::ServiceManager> service_manager; /// Telemetry session for this emulation session std::unique_ptr<Core::TelemetrySession> telemetry_session; + Reporter reporter; + ResultStatus status = ResultStatus::Success; std::string status_details = ""; @@ -376,6 +447,14 @@ const Tegra::GPU& System::GPU() const { return *impl->gpu_core; } +Core::Hardware::InterruptManager& System::InterruptManager() { + return *impl->interrupt_manager; +} + +const Core::Hardware::InterruptManager& System::InterruptManager() const { + return *impl->interrupt_manager; +} + VideoCore::RendererBase& System::Renderer() { return *impl->renderer; } @@ -492,6 +571,26 @@ void System::ClearContentProvider(FileSys::ContentProviderUnionSlot slot) { impl->content_provider->ClearSlot(slot); } +const Reporter& System::GetReporter() const { + return impl->reporter; +} + +Service::Glue::ARPManager& System::GetARPManager() { + return impl->arp_manager; +} + +const Service::Glue::ARPManager& System::GetARPManager() const { + return impl->arp_manager; +} + +Service::APM::Controller& System::GetAPMController() { + return impl->apm_controller; +} + +const Service::APM::Controller& System::GetAPMController() const { + return impl->apm_controller; +} + System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { return impl->Init(*this, emu_window); } |