diff options
Diffstat (limited to 'src/core/core.cpp')
-rwxr-xr-x | src/core/core.cpp | 109 |
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 | ||
72 | namespace Core { | 73 | namespace Core { |
73 | 74 | ||
75 | namespace { | ||
76 | |||
77 | FileSys::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 | |||
74 | FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | 99 | FileSys::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) { |