aboutsummaryrefslogtreecommitdiff
path: root/src/core/core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/core.cpp')
-rwxr-xr-xsrc/core/core.cpp109
1 files changed, 82 insertions, 27 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index a51d3447b..56f5dd67d 100755
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -3,6 +3,7 @@
3 3
4#include <array> 4#include <array>
5#include <atomic> 5#include <atomic>
6#include <exception>
6#include <memory> 7#include <memory>
7#include <utility> 8#include <utility>
8 9
@@ -19,6 +20,7 @@
19#include "core/cpu_manager.h" 20#include "core/cpu_manager.h"
20#include "core/debugger/debugger.h" 21#include "core/debugger/debugger.h"
21#include "core/device_memory.h" 22#include "core/device_memory.h"
23#include "core/file_sys/bis_factory.h"
22#include "core/file_sys/fs_filesystem.h" 24#include "core/file_sys/fs_filesystem.h"
23#include "core/file_sys/patch_manager.h" 25#include "core/file_sys/patch_manager.h"
24#include "core/file_sys/registered_cache.h" 26#include "core/file_sys/registered_cache.h"
@@ -36,7 +38,6 @@
36#include "core/hle/service/acc/profile_manager.h" 38#include "core/hle/service/acc/profile_manager.h"
37#include "core/hle/service/am/applet_manager.h" 39#include "core/hle/service/am/applet_manager.h"
38#include "core/hle/service/am/frontend/applets.h" 40#include "core/hle/service/am/frontend/applets.h"
39#include "core/hle/service/am/process_creation.h"
40#include "core/hle/service/apm/apm_controller.h" 41#include "core/hle/service/apm/apm_controller.h"
41#include "core/hle/service/filesystem/filesystem.h" 42#include "core/hle/service/filesystem/filesystem.h"
42#include "core/hle/service/glue/glue_manager.h" 43#include "core/hle/service/glue/glue_manager.h"
@@ -71,6 +72,30 @@ MICROPROFILE_DEFINE(ARM_CPU3, "ARM", "CPU 3", MP_RGB(255, 64, 64));
71 72
72namespace Core { 73namespace Core {
73 74
75namespace {
76
77FileSys::StorageId GetStorageIdForFrontendSlot(
78 std::optional<FileSys::ContentProviderUnionSlot> slot) {
79 if (!slot.has_value()) {
80 return FileSys::StorageId::None;
81 }
82
83 switch (*slot) {
84 case FileSys::ContentProviderUnionSlot::UserNAND:
85 return FileSys::StorageId::NandUser;
86 case FileSys::ContentProviderUnionSlot::SysNAND:
87 return FileSys::StorageId::NandSystem;
88 case FileSys::ContentProviderUnionSlot::SDMC:
89 return FileSys::StorageId::SdCard;
90 case FileSys::ContentProviderUnionSlot::FrontendManual:
91 return FileSys::StorageId::Host;
92 default:
93 return FileSys::StorageId::None;
94 }
95}
96
97} // Anonymous namespace
98
74FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, 99FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
75 const std::string& path) { 100 const std::string& path) {
76 // To account for split 00+01+etc files. 101 // To account for split 00+01+etc files.
@@ -272,6 +297,9 @@ struct System::Impl {
272 } 297 }
273 298
274 SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { 299 SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
300 /// Reset all glue registrations
301 arp_manager.ResetAll();
302
275 telemetry_session = std::make_unique<Core::TelemetrySession>(); 303 telemetry_session = std::make_unique<Core::TelemetrySession>();
276 304
277 host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system); 305 host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
@@ -307,24 +335,8 @@ struct System::Impl {
307 SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, 335 SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
308 const std::string& filepath, 336 const std::string& filepath,
309 Service::AM::FrontendAppletParameters& params) { 337 Service::AM::FrontendAppletParameters& params) {
310 InitializeKernel(system); 338 app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
311 339 params.program_id, params.program_index);
312 const auto file = GetGameFileFromPath(virtual_filesystem, filepath);
313
314 // Create the application process
315 Loader::ResultStatus load_result{};
316 std::vector<u8> control;
317 auto process =
318 Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file,
319 params.program_id, params.program_index);
320
321 if (load_result != Loader::ResultStatus::Success) {
322 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
323 ShutdownMainProcess();
324
325 return static_cast<SystemResultStatus>(
326 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
327 }
328 340
329 if (!app_loader) { 341 if (!app_loader) {
330 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); 342 LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
@@ -332,7 +344,7 @@ struct System::Impl {
332 } 344 }
333 345
334 if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) { 346 if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) {
335 LOG_ERROR(Core, "Failed to find program id for ROM!"); 347 LOG_ERROR(Core, "Failed to find title id for ROM!");
336 } 348 }
337 349
338 std::string name = "Unknown program"; 350 std::string name = "Unknown program";
@@ -340,10 +352,23 @@ struct System::Impl {
340 LOG_ERROR(Core, "Failed to read title for ROM!"); 352 LOG_ERROR(Core, "Failed to read title for ROM!");
341 } 353 }
342 354
343 LOG_INFO(Core, "Loading {} ({:016X}) ...", name, params.program_id); 355 LOG_INFO(Core, "Loading {} ({})", name, params.program_id);
344 356
345 // Make the process created be the application 357 InitializeKernel(system);
346 kernel.MakeApplicationProcess(process->GetHandle()); 358
359 // Create the application process.
360 auto main_process = Kernel::KProcess::Create(system.Kernel());
361 Kernel::KProcess::Register(system.Kernel(), main_process);
362 kernel.AppendNewProcess(main_process);
363 kernel.MakeApplicationProcess(main_process);
364 const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
365 if (load_result != Loader::ResultStatus::Success) {
366 LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
367 ShutdownMainProcess();
368
369 return static_cast<SystemResultStatus>(
370 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
371 }
347 372
348 // Set up the rest of the system. 373 // Set up the rest of the system.
349 SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; 374 SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
@@ -354,6 +379,7 @@ struct System::Impl {
354 return init_result; 379 return init_result;
355 } 380 }
356 381
382 AddGlueRegistrationForProcess(*app_loader, *main_process);
357 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); 383 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
358 384
359 // Initialize cheat engine 385 // Initialize cheat engine
@@ -362,7 +388,13 @@ struct System::Impl {
362 } 388 }
363 389
364 // Register with applet manager. 390 // Register with applet manager.
365 applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params); 391 applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(),
392 params);
393
394 // All threads are started, begin main process execution, now that we're in the clear.
395 main_process->Run(load_parameters->main_thread_priority,
396 load_parameters->main_thread_stack_size);
397 main_process->Close();
366 398
367 if (Settings::values.gamecard_inserted) { 399 if (Settings::values.gamecard_inserted) {
368 if (Settings::values.gamecard_current_game) { 400 if (Settings::values.gamecard_current_game) {
@@ -434,6 +466,7 @@ struct System::Impl {
434 kernel.SuspendEmulation(true); 466 kernel.SuspendEmulation(true);
435 kernel.CloseServices(); 467 kernel.CloseServices();
436 kernel.ShutdownCores(); 468 kernel.ShutdownCores();
469 applet_manager.Reset();
437 services.reset(); 470 services.reset();
438 service_manager.reset(); 471 service_manager.reset();
439 fs_controller.Reset(); 472 fs_controller.Reset();
@@ -459,9 +492,6 @@ struct System::Impl {
459 // Workarounds 492 // Workarounds
460 Settings::values.renderer_amdvlk_depth_bias_workaround = false; 493 Settings::values.renderer_amdvlk_depth_bias_workaround = false;
461 494
462 // Reset all glue registrations
463 arp_manager.ResetAll();
464
465 LOG_DEBUG(Core, "Shutdown OK"); 495 LOG_DEBUG(Core, "Shutdown OK");
466 } 496 }
467 497
@@ -479,6 +509,31 @@ struct System::Impl {
479 return app_loader->ReadTitle(out); 509 return app_loader->ReadTitle(out);
480 } 510 }
481 511
512 void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) {
513 std::vector<u8> nacp_data;
514 FileSys::NACP nacp;
515 if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) {
516 nacp_data = nacp.GetRawBytes();
517 } else {
518 nacp_data.resize(sizeof(FileSys::RawNACP));
519 }
520
521 Service::Glue::ApplicationLaunchProperty launch{};
522 launch.title_id = process.GetProgramId();
523
524 FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider};
525 launch.version = pm.GetGameVersion().value_or(0);
526
527 // TODO(DarkLordZach): When FSController/Game Card Support is added, if
528 // current_process_game_card use correct StorageId
529 launch.base_game_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry(
530 launch.title_id, FileSys::ContentRecordType::Program));
531 launch.update_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry(
532 FileSys::GetUpdateTitleID(launch.title_id), FileSys::ContentRecordType::Program));
533
534 arp_manager.Register(launch.title_id, launch, std::move(nacp_data));
535 }
536
482 void SetStatus(SystemResultStatus new_status, const char* details = nullptr) { 537 void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
483 status = new_status; 538 status = new_status;
484 if (details) { 539 if (details) {