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(); auto& memory = system.GetMemory();
path = memory.GetString(memory.Read_U32(address + 0xc)); path = memory.GetString(memory.Read_U32(address + 0xc));
flags = static_cast<OpenMode>(memory.Read_U32(address + 0x10)); flags = static_cast<OpenMode>(memory.Read_U32(address + 0x10));
const Kernel* ios = GetIOS(); const EmulationKernel* ios = GetIOS();
if (ios) if (ios)
{ {
uid = ios->GetUidForPPC(); uid = ios->GetUidForPPC();

View File

@ -252,7 +252,7 @@ IPCReply ESDevice::GetTitleId(const IOCtlVRequest& request)
return IPCReply(IPC_SUCCESS); 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()}; ES::UIDSys uid_sys{kernel.GetFSCore()};
const u64 title_id = tmd.GetTitleId(); const u64 title_id = tmd.GetTitleId();
@ -267,7 +267,7 @@ static bool UpdateUIDAndGID(Kernel& kernel, const ES::TMDReader& tmd)
return true; 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) const ES::TMDReader& active_tmd)
{ {
ES::UIDSys uid_map{kernel.GetFSCore()}; ES::UIDSys uid_map{kernel.GetFSCore()};

View File

@ -309,12 +309,6 @@ Kernel::Kernel(IOSC::ConsoleType console_type) : m_iosc(console_type)
Kernel::~Kernel() 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) if (m_is_responsible_for_nand_root)
Core::ShutdownWiiRoot(); Core::ShutdownWiiRoot();
} }
@ -351,6 +345,10 @@ EmulationKernel::EmulationKernel(Core::System& system, u64 title_id)
EmulationKernel::~EmulationKernel() EmulationKernel::~EmulationKernel()
{ {
Core::System::GetInstance().GetCoreTiming().RemoveAllEvents(s_event_enqueue); 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. // 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. // 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). // 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; m_ppc_uid = uid;
} }
u32 Kernel::GetUidForPPC() const u32 EmulationKernel::GetUidForPPC() const
{ {
return m_ppc_uid; return m_ppc_uid;
} }
void Kernel::SetGidForPPC(u16 gid) void EmulationKernel::SetGidForPPC(u16 gid)
{ {
m_ppc_gid = gid; m_ppc_gid = gid;
} }
u16 Kernel::GetGidForPPC() const u16 EmulationKernel::GetGidForPPC() const
{ {
return m_ppc_gid; 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. // 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. // 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. // Seeking and processing overhead is ignored as most time is spent reading from the NAND.
u64 ticks = 0; 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 // 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 // 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. // 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, bool EmulationKernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_ppc,
const std::string& boot_content_path) const std::string& boot_content_path)
{ {
// IOS suspends regular PPC<->ARM IPC before loading a new IOS. // IOS suspends regular PPC<->ARM IPC before loading a new IOS.
// IPC is not resumed if the boot fails for any reason. // 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; return true;
} }
void Kernel::InitIPC() void EmulationKernel::InitIPC()
{ {
if (!Core::IsRunning()) if (!Core::IsRunning())
return; return;
@ -552,7 +550,7 @@ void Kernel::InitIPC()
GenerateAck(0); GenerateAck(0);
} }
void Kernel::AddDevice(std::unique_ptr<Device> device) void EmulationKernel::AddDevice(std::unique_ptr<Device> device)
{ {
ASSERT(device->GetDeviceType() == Device::DeviceType::Static); ASSERT(device->GetDeviceType() == Device::DeviceType::Static);
m_device_map.insert_or_assign(device->GetDeviceName(), std::move(device)); m_device_map.insert_or_assign(device->GetDeviceName(), std::move(device));
@ -648,18 +646,13 @@ s32 EmulationKernel::GetFreeDeviceID()
return -1; 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); std::lock_guard lock(m_device_map_mutex);
const auto iterator = m_device_map.find(device_name); const auto iterator = m_device_map.find(device_name);
return iterator != m_device_map.end() ? iterator->second : nullptr; 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. // Returns the FD for the newly opened device (on success) or an error code.
std::optional<IPCReply> EmulationKernel::OpenDevice(OpenRequest& request) std::optional<IPCReply> EmulationKernel::OpenDevice(OpenRequest& request)
{ {

View File

@ -127,15 +127,6 @@ public:
FSCore& GetFSCore(); FSCore& GetFSCore();
ESCore& GetESCore(); 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; u32 GetVersion() const;
IOSC& GetIOSC(); IOSC& GetIOSC();
@ -143,28 +134,11 @@ public:
protected: protected:
explicit Kernel(u64 title_id); 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<FSCore> m_fs_core;
std::unique_ptr<ESCore> m_es_core; std::unique_ptr<ESCore> m_es_core;
bool m_is_responsible_for_nand_root = false; bool m_is_responsible_for_nand_root = false;
u64 m_title_id = 0; 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; IOSC m_iosc;
std::shared_ptr<FS::FileSystem> m_fs; 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, void EnqueueIPCReply(const Request& request, s32 return_value, s64 cycles_in_future = 0,
CoreTiming::FromThread from = CoreTiming::FromThread::CPU); 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; } Core::System& GetSystem() const { return m_system; }
private: private:
Core::System& m_system;
void ExecuteIPCCommand(u32 address); void ExecuteIPCCommand(u32 address);
std::optional<IPCReply> HandleIPCCommand(const Request& request); std::optional<IPCReply> HandleIPCCommand(const Request& request);
void AddDevice(std::unique_ptr<Device> device);
void AddStaticDevices(); void AddStaticDevices();
s32 GetFreeDeviceID(); s32 GetFreeDeviceID();
std::optional<IPCReply> OpenDevice(OpenRequest& request); 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. // Used for controlling and accessing an IOS instance that is tied to emulation.