IOS: Move more emulation-only stuff from Kernel to EmulationKernel.

This commit is contained in:
Admiral H. Curtiss 2023-05-13 17:48:05 +02:00
parent 3d767edd8a
commit b8f3a47fba
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
4 changed files with 46 additions and 52 deletions

View File

@ -28,7 +28,7 @@ OpenRequest::OpenRequest(Core::System& system, const u32 address_) : Request(sys
auto& memory = system.GetMemory();
path = memory.GetString(memory.Read_U32(address + 0xc));
flags = static_cast<OpenMode>(memory.Read_U32(address + 0x10));
const Kernel* ios = GetIOS();
const EmulationKernel* ios = GetIOS();
if (ios)
{
uid = ios->GetUidForPPC();

View File

@ -252,7 +252,7 @@ IPCReply ESDevice::GetTitleId(const IOCtlVRequest& request)
return IPCReply(IPC_SUCCESS);
}
static bool UpdateUIDAndGID(Kernel& kernel, const ES::TMDReader& tmd)
static bool UpdateUIDAndGID(EmulationKernel& kernel, const ES::TMDReader& tmd)
{
ES::UIDSys uid_sys{kernel.GetFSCore()};
const u64 title_id = tmd.GetTitleId();
@ -267,7 +267,7 @@ static bool UpdateUIDAndGID(Kernel& kernel, const ES::TMDReader& tmd)
return true;
}
static ReturnCode CheckIsAllowedToSetUID(Kernel& kernel, const u32 caller_uid,
static ReturnCode CheckIsAllowedToSetUID(EmulationKernel& kernel, const u32 caller_uid,
const ES::TMDReader& active_tmd)
{
ES::UIDSys uid_map{kernel.GetFSCore()};

View File

@ -309,12 +309,6 @@ Kernel::Kernel(IOSC::ConsoleType console_type) : m_iosc(console_type)
Kernel::~Kernel()
{
{
std::lock_guard lock(m_device_map_mutex);
m_device_map.clear();
m_socket_manager.reset();
}
if (m_is_responsible_for_nand_root)
Core::ShutdownWiiRoot();
}
@ -351,6 +345,10 @@ EmulationKernel::EmulationKernel(Core::System& system, u64 title_id)
EmulationKernel::~EmulationKernel()
{
Core::System::GetInstance().GetCoreTiming().RemoveAllEvents(s_event_enqueue);
std::lock_guard lock(m_device_map_mutex);
m_device_map.clear();
m_socket_manager.reset();
}
// The title ID is a u64 where the first 32 bits are used for the title type.
@ -393,22 +391,22 @@ std::shared_ptr<WiiSockMan> EmulationKernel::GetSocketManager()
// Since we don't have actual processes, we keep track of only the PPC's UID/GID.
// These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC).
void Kernel::SetUidForPPC(u32 uid)
void EmulationKernel::SetUidForPPC(u32 uid)
{
m_ppc_uid = uid;
}
u32 Kernel::GetUidForPPC() const
u32 EmulationKernel::GetUidForPPC() const
{
return m_ppc_uid;
}
void Kernel::SetGidForPPC(u16 gid)
void EmulationKernel::SetGidForPPC(u16 gid)
{
m_ppc_gid = gid;
}
u16 Kernel::GetGidForPPC() const
u16 EmulationKernel::GetGidForPPC() const
{
return m_ppc_gid;
}
@ -432,7 +430,7 @@ static std::vector<u8> ReadBootContent(FSCore& fs, const std::string& path, size
// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC.
// Unlike 0x42, IOS will set up some constants in memory before booting the PPC.
bool Kernel::BootstrapPPC(Core::System& system, const std::string& boot_content_path)
bool EmulationKernel::BootstrapPPC(Core::System& system, const std::string& boot_content_path)
{
// Seeking and processing overhead is ignored as most time is spent reading from the NAND.
u64 ticks = 0;
@ -506,8 +504,8 @@ static constexpr SystemTimers::TimeBaseTick GetIOSBootTicks(u32 version)
// Passing a boot content path is optional because we do not require IOSes
// to be installed at the moment. If one is passed, the boot binary must exist
// on the NAND, or the call will fail like on a Wii.
bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ppc,
const std::string& boot_content_path)
bool EmulationKernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ppc,
const std::string& boot_content_path)
{
// IOS suspends regular PPC<->ARM IPC before loading a new IOS.
// IPC is not resumed if the boot fails for any reason.
@ -543,7 +541,7 @@ bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_
return true;
}
void Kernel::InitIPC()
void EmulationKernel::InitIPC()
{
if (!Core::IsRunning())
return;
@ -552,7 +550,7 @@ void Kernel::InitIPC()
GenerateAck(0);
}
void Kernel::AddDevice(std::unique_ptr<Device> device)
void EmulationKernel::AddDevice(std::unique_ptr<Device> device)
{
ASSERT(device->GetDeviceType() == Device::DeviceType::Static);
m_device_map.insert_or_assign(device->GetDeviceName(), std::move(device));
@ -648,18 +646,13 @@ s32 EmulationKernel::GetFreeDeviceID()
return -1;
}
std::shared_ptr<Device> Kernel::GetDeviceByName(std::string_view device_name)
std::shared_ptr<Device> EmulationKernel::GetDeviceByName(std::string_view device_name)
{
std::lock_guard lock(m_device_map_mutex);
const auto iterator = m_device_map.find(device_name);
return iterator != m_device_map.end() ? iterator->second : nullptr;
}
std::shared_ptr<Device> EmulationKernel::GetDeviceByName(std::string_view device_name)
{
return Kernel::GetDeviceByName(device_name);
}
// Returns the FD for the newly opened device (on success) or an error code.
std::optional<IPCReply> EmulationKernel::OpenDevice(OpenRequest& request)
{

View File

@ -127,15 +127,6 @@ public:
FSCore& GetFSCore();
ESCore& GetESCore();
void SetUidForPPC(u32 uid);
u32 GetUidForPPC() const;
void SetGidForPPC(u16 gid);
u16 GetGidForPPC() const;
bool BootstrapPPC(Core::System& system, const std::string& boot_content_path);
bool BootIOS(Core::System& system, u64 ios_title_id, HangPPC hang_ppc = HangPPC::No,
const std::string& boot_content_path = {});
void InitIPC();
u32 GetVersion() const;
IOSC& GetIOSC();
@ -143,28 +134,11 @@ public:
protected:
explicit Kernel(u64 title_id);
void AddDevice(std::unique_ptr<Device> device);
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
std::unique_ptr<FSCore> m_fs_core;
std::unique_ptr<ESCore> m_es_core;
bool m_is_responsible_for_nand_root = false;
u64 m_title_id = 0;
static constexpr u8 IPC_MAX_FDS = 0x18;
std::map<std::string, std::shared_ptr<Device>, std::less<>> m_device_map;
std::mutex m_device_map_mutex;
// TODO: make this fdmap per process.
std::array<std::shared_ptr<Device>, IPC_MAX_FDS> m_fdmap;
u32 m_ppc_uid = 0;
u16 m_ppc_gid = 0;
using IPCMsgQueue = std::deque<u32>;
IPCMsgQueue m_request_queue; // ppc -> arm
IPCMsgQueue m_reply_queue; // arm -> ppc
u64 m_last_reply_time = 0;
bool m_ipc_paused = false;
IOSC m_iosc;
std::shared_ptr<FS::FileSystem> m_fs;
@ -198,17 +172,44 @@ public:
void EnqueueIPCReply(const Request& request, s32 return_value, s64 cycles_in_future = 0,
CoreTiming::FromThread from = CoreTiming::FromThread::CPU);
void SetUidForPPC(u32 uid);
u32 GetUidForPPC() const;
void SetGidForPPC(u16 gid);
u16 GetGidForPPC() const;
bool BootstrapPPC(Core::System& system, const std::string& boot_content_path);
bool BootIOS(Core::System& system, u64 ios_title_id, HangPPC hang_ppc = HangPPC::No,
const std::string& boot_content_path = {});
void InitIPC();
Core::System& GetSystem() const { return m_system; }
private:
Core::System& m_system;
void ExecuteIPCCommand(u32 address);
std::optional<IPCReply> HandleIPCCommand(const Request& request);
void AddDevice(std::unique_ptr<Device> device);
void AddStaticDevices();
s32 GetFreeDeviceID();
std::optional<IPCReply> OpenDevice(OpenRequest& request);
Core::System& m_system;
static constexpr u8 IPC_MAX_FDS = 0x18;
std::map<std::string, std::shared_ptr<Device>, std::less<>> m_device_map;
std::mutex m_device_map_mutex;
// TODO: make this fdmap per process.
std::array<std::shared_ptr<Device>, IPC_MAX_FDS> m_fdmap;
u32 m_ppc_uid = 0;
u16 m_ppc_gid = 0;
using IPCMsgQueue = std::deque<u32>;
IPCMsgQueue m_request_queue; // ppc -> arm
IPCMsgQueue m_reply_queue; // arm -> ppc
u64 m_last_reply_time = 0;
bool m_ipc_paused = false;
};
// Used for controlling and accessing an IOS instance that is tied to emulation.