mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-11-26 22:05:44 +01:00
core: move main applet initialization to am
This commit is contained in:
parent
89e00dff57
commit
23ac21dc6e
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <exception>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -20,7 +19,6 @@
|
|||||||
#include "core/cpu_manager.h"
|
#include "core/cpu_manager.h"
|
||||||
#include "core/debugger/debugger.h"
|
#include "core/debugger/debugger.h"
|
||||||
#include "core/device_memory.h"
|
#include "core/device_memory.h"
|
||||||
#include "core/file_sys/bis_factory.h"
|
|
||||||
#include "core/file_sys/fs_filesystem.h"
|
#include "core/file_sys/fs_filesystem.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
@ -38,6 +36,7 @@
|
|||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
|
#include "core/hle/service/am/process_creation.h"
|
||||||
#include "core/hle/service/apm/apm_controller.h"
|
#include "core/hle/service/apm/apm_controller.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
@ -72,30 +71,6 @@ MICROPROFILE_DEFINE(ARM_CPU3, "ARM", "CPU 3", MP_RGB(255, 64, 64));
|
|||||||
|
|
||||||
namespace Core {
|
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
|
|
||||||
|
|
||||||
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
||||||
const std::string& path) {
|
const std::string& path) {
|
||||||
// To account for split 00+01+etc files.
|
// To account for split 00+01+etc files.
|
||||||
@ -297,9 +272,6 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
|
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
|
||||||
/// Reset all glue registrations
|
|
||||||
arp_manager.ResetAll();
|
|
||||||
|
|
||||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||||
|
|
||||||
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
|
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
|
||||||
@ -335,33 +307,17 @@ struct System::Impl {
|
|||||||
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
||||||
const std::string& filepath,
|
const std::string& filepath,
|
||||||
Service::AM::FrontendAppletParameters& params) {
|
Service::AM::FrontendAppletParameters& params) {
|
||||||
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
|
|
||||||
params.program_id, params.program_index);
|
|
||||||
|
|
||||||
if (!app_loader) {
|
|
||||||
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
|
||||||
return SystemResultStatus::ErrorGetLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) {
|
|
||||||
LOG_ERROR(Core, "Failed to find title id for ROM!");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name = "Unknown program";
|
|
||||||
if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) {
|
|
||||||
LOG_ERROR(Core, "Failed to read title for ROM!");
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO(Core, "Loading {} ({})", name, params.program_id);
|
|
||||||
|
|
||||||
InitializeKernel(system);
|
InitializeKernel(system);
|
||||||
|
|
||||||
// Create the application process.
|
const auto file = GetGameFileFromPath(virtual_filesystem, filepath);
|
||||||
auto main_process = Kernel::KProcess::Create(system.Kernel());
|
|
||||||
Kernel::KProcess::Register(system.Kernel(), main_process);
|
// Create the application process
|
||||||
kernel.AppendNewProcess(main_process);
|
Loader::ResultStatus load_result{};
|
||||||
kernel.MakeApplicationProcess(main_process);
|
std::vector<u8> control;
|
||||||
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
auto process =
|
||||||
|
Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file,
|
||||||
|
params.program_id, params.program_index);
|
||||||
|
|
||||||
if (load_result != Loader::ResultStatus::Success) {
|
if (load_result != Loader::ResultStatus::Success) {
|
||||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
||||||
ShutdownMainProcess();
|
ShutdownMainProcess();
|
||||||
@ -370,6 +326,25 @@ struct System::Impl {
|
|||||||
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
|
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!app_loader) {
|
||||||
|
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||||
|
return SystemResultStatus::ErrorGetLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) {
|
||||||
|
LOG_ERROR(Core, "Failed to find program id for ROM!");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = "Unknown program";
|
||||||
|
if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) {
|
||||||
|
LOG_ERROR(Core, "Failed to read title for ROM!");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(Core, "Loading {} ({:016X}) ...", name, params.program_id);
|
||||||
|
|
||||||
|
// Make the process created be the application
|
||||||
|
kernel.MakeApplicationProcess(process->GetHandle());
|
||||||
|
|
||||||
// Set up the rest of the system.
|
// Set up the rest of the system.
|
||||||
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
|
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
|
||||||
if (init_result != SystemResultStatus::Success) {
|
if (init_result != SystemResultStatus::Success) {
|
||||||
@ -379,7 +354,6 @@ struct System::Impl {
|
|||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddGlueRegistrationForProcess(*app_loader, *main_process);
|
|
||||||
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
||||||
|
|
||||||
// Initialize cheat engine
|
// Initialize cheat engine
|
||||||
@ -387,14 +361,9 @@ struct System::Impl {
|
|||||||
cheat_engine->Initialize();
|
cheat_engine->Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register with applet manager.
|
// Register with applet manager
|
||||||
applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(),
|
// All threads are started, begin main process execution, now that we're in the clear
|
||||||
params);
|
applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params);
|
||||||
|
|
||||||
// All threads are started, begin main process execution, now that we're in the clear.
|
|
||||||
main_process->Run(load_parameters->main_thread_priority,
|
|
||||||
load_parameters->main_thread_stack_size);
|
|
||||||
main_process->Close();
|
|
||||||
|
|
||||||
if (Settings::values.gamecard_inserted) {
|
if (Settings::values.gamecard_inserted) {
|
||||||
if (Settings::values.gamecard_current_game) {
|
if (Settings::values.gamecard_current_game) {
|
||||||
@ -461,7 +430,6 @@ struct System::Impl {
|
|||||||
kernel.SuspendEmulation(true);
|
kernel.SuspendEmulation(true);
|
||||||
kernel.CloseServices();
|
kernel.CloseServices();
|
||||||
kernel.ShutdownCores();
|
kernel.ShutdownCores();
|
||||||
applet_manager.Reset();
|
|
||||||
services.reset();
|
services.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
@ -484,6 +452,9 @@ struct System::Impl {
|
|||||||
room_member->SendGameInfo(game_info);
|
room_member->SendGameInfo(game_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset all glue registrations
|
||||||
|
arp_manager.ResetAll();
|
||||||
|
|
||||||
LOG_DEBUG(Core, "Shutdown OK");
|
LOG_DEBUG(Core, "Shutdown OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,31 +472,6 @@ struct System::Impl {
|
|||||||
return app_loader->ReadTitle(out);
|
return app_loader->ReadTitle(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& 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.GetProgramId();
|
|
||||||
|
|
||||||
FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider};
|
|
||||||
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(SystemResultStatus new_status, const char* details = nullptr) {
|
void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
|
||||||
status = new_status;
|
status = new_status;
|
||||||
if (details) {
|
if (details) {
|
||||||
|
@ -1170,6 +1170,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
|
|||||||
// Determine if we are an application.
|
// Determine if we are an application.
|
||||||
if (pool == KMemoryManager::Pool::Application) {
|
if (pool == KMemoryManager::Pool::Application) {
|
||||||
flag |= Svc::CreateProcessFlag::IsApplication;
|
flag |= Svc::CreateProcessFlag::IsApplication;
|
||||||
|
m_is_application = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are 64-bit, create as such.
|
// If we are 64-bit, create as such.
|
||||||
|
@ -267,13 +267,12 @@ void AppletManager::TerminateAndRemoveApplet(u64 aruid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AppletManager::CreateAndInsertByFrontendAppletParameters(
|
void AppletManager::CreateAndInsertByFrontendAppletParameters(
|
||||||
u64 aruid, const FrontendAppletParameters& params) {
|
std::unique_ptr<Process> process, const FrontendAppletParameters& params) {
|
||||||
// TODO: this should be run inside AM so that the events will have a parent process
|
// TODO: this should be run inside AM so that the events will have a parent process
|
||||||
// TODO: have am create the guest process
|
// TODO: have am create the guest process
|
||||||
auto applet = std::make_shared<Applet>(m_system, std::make_unique<Process>(m_system),
|
auto applet = std::make_shared<Applet>(m_system, std::move(process),
|
||||||
params.applet_id == AppletId::Application);
|
params.applet_id == AppletId::Application);
|
||||||
|
|
||||||
applet->aruid.pid = aruid;
|
|
||||||
applet->program_id = params.program_id;
|
applet->program_id = params.program_id;
|
||||||
applet->applet_id = params.applet_id;
|
applet->applet_id = params.applet_id;
|
||||||
applet->type = params.applet_type;
|
applet->type = params.applet_type;
|
||||||
@ -329,6 +328,7 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters(
|
|||||||
|
|
||||||
// Applet was started by frontend, so it is foreground.
|
// Applet was started by frontend, so it is foreground.
|
||||||
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
||||||
|
applet->process->Run();
|
||||||
|
|
||||||
this->InsertApplet(std::move(applet));
|
this->InsertApplet(std::move(applet));
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,10 @@ namespace Core {
|
|||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Service {
|
||||||
|
class Process;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
enum class LaunchType {
|
enum class LaunchType {
|
||||||
@ -36,7 +40,7 @@ public:
|
|||||||
void InsertApplet(std::shared_ptr<Applet> applet);
|
void InsertApplet(std::shared_ptr<Applet> applet);
|
||||||
void TerminateAndRemoveApplet(u64 aruid);
|
void TerminateAndRemoveApplet(u64 aruid);
|
||||||
|
|
||||||
void CreateAndInsertByFrontendAppletParameters(u64 aruid,
|
void CreateAndInsertByFrontendAppletParameters(std::unique_ptr<Process> process,
|
||||||
const FrontendAppletParameters& params);
|
const FrontendAppletParameters& params);
|
||||||
std::shared_ptr<Applet> GetByAppletResourceUserId(u64 aruid) const;
|
std::shared_ptr<Applet> GetByAppletResourceUserId(u64 aruid) const;
|
||||||
|
|
||||||
|
@ -13,21 +13,21 @@ namespace Service::AM {
|
|||||||
HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) {
|
HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) {
|
||||||
m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid");
|
m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid");
|
||||||
|
|
||||||
if (m_process.IsInitialized()) {
|
if (m_hid_server && m_process.IsInitialized()) {
|
||||||
m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(),
|
m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HidRegistration::~HidRegistration() {
|
HidRegistration::~HidRegistration() {
|
||||||
if (m_process.IsInitialized()) {
|
if (m_hid_server && m_process.IsInitialized()) {
|
||||||
m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId(
|
m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId(
|
||||||
m_process.GetProcessId());
|
m_process.GetProcessId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HidRegistration::EnableAppletToGetInput(bool enable) {
|
void HidRegistration::EnableAppletToGetInput(bool enable) {
|
||||||
if (m_process.IsInitialized()) {
|
if (m_hid_server && m_process.IsInitialized()) {
|
||||||
m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable);
|
m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,7 @@ struct Memory::Impl {
|
|||||||
void SetCurrentPageTable(Kernel::KProcess& process) {
|
void SetCurrentPageTable(Kernel::KProcess& process) {
|
||||||
current_page_table = &process.GetPageTable().GetImpl();
|
current_page_table = &process.GetPageTable().GetImpl();
|
||||||
|
|
||||||
if (std::addressof(process) == system.ApplicationProcess() &&
|
if (process.IsApplication() && Settings::IsFastmemEnabled()) {
|
||||||
Settings::IsFastmemEnabled()) {
|
|
||||||
current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
|
current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
|
||||||
} else {
|
} else {
|
||||||
current_page_table->fastmem_arena = nullptr;
|
current_page_table->fastmem_arena = nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user