mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
IOS: Leverage Kernel/EmulationKernel difference for passing System to most IOS devices.
This commit is contained in:
@ -319,7 +319,8 @@ Kernel::Kernel(u64 title_id) : m_title_id(title_id)
|
||||
{
|
||||
}
|
||||
|
||||
EmulationKernel::EmulationKernel(u64 title_id) : Kernel(title_id)
|
||||
EmulationKernel::EmulationKernel(Core::System& system, u64 title_id)
|
||||
: Kernel(title_id), m_system(system)
|
||||
{
|
||||
INFO_LOG_FMT(IOS, "Starting IOS {:016x}", title_id);
|
||||
|
||||
@ -364,7 +365,7 @@ std::shared_ptr<ESDevice> Kernel::GetES()
|
||||
return std::static_pointer_cast<ESDevice>(m_device_map.at("/dev/es"));
|
||||
}
|
||||
|
||||
std::shared_ptr<WiiSockMan> Kernel::GetSocketManager()
|
||||
std::shared_ptr<WiiSockMan> EmulationKernel::GetSocketManager()
|
||||
{
|
||||
return m_socket_manager;
|
||||
}
|
||||
@ -462,11 +463,11 @@ private:
|
||||
std::vector<u8> m_bytes;
|
||||
};
|
||||
|
||||
static void FinishIOSBoot(u64 ios_title_id)
|
||||
static void FinishIOSBoot(Core::System& system, u64 ios_title_id)
|
||||
{
|
||||
// Shut down the active IOS first before switching to the new one.
|
||||
s_ios.reset();
|
||||
s_ios = std::make_unique<EmulationKernel>(ios_title_id);
|
||||
s_ios = std::make_unique<EmulationKernel>(system, ios_title_id);
|
||||
}
|
||||
|
||||
static constexpr SystemTimers::TimeBaseTick GetIOSBootTicks(u32 version)
|
||||
@ -515,7 +516,7 @@ bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_
|
||||
}
|
||||
else
|
||||
{
|
||||
FinishIOSBoot(ios_title_id);
|
||||
FinishIOSBoot(system, ios_title_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -546,7 +547,7 @@ void Kernel::AddCoreDevices()
|
||||
AddDevice(std::make_unique<ESDevice>(*this, "/dev/es"));
|
||||
}
|
||||
|
||||
void Kernel::AddStaticDevices()
|
||||
void EmulationKernel::AddStaticDevices()
|
||||
{
|
||||
std::lock_guard lock(m_device_map_mutex);
|
||||
|
||||
@ -623,7 +624,7 @@ void Kernel::AddStaticDevices()
|
||||
}
|
||||
}
|
||||
|
||||
s32 Kernel::GetFreeDeviceID()
|
||||
s32 EmulationKernel::GetFreeDeviceID()
|
||||
{
|
||||
for (u32 i = 0; i < IPC_MAX_FDS; i++)
|
||||
{
|
||||
@ -649,7 +650,7 @@ std::shared_ptr<Device> EmulationKernel::GetDeviceByName(std::string_view device
|
||||
}
|
||||
|
||||
// Returns the FD for the newly opened device (on success) or an error code.
|
||||
std::optional<IPCReply> Kernel::OpenDevice(OpenRequest& request)
|
||||
std::optional<IPCReply> EmulationKernel::OpenDevice(OpenRequest& request)
|
||||
{
|
||||
const s32 new_fd = GetFreeDeviceID();
|
||||
INFO_LOG_FMT(IOS, "Opening {} (mode {}, fd {})", request.path, static_cast<u32>(request.flags),
|
||||
@ -691,14 +692,14 @@ std::optional<IPCReply> Kernel::OpenDevice(OpenRequest& request)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
|
||||
std::optional<IPCReply> EmulationKernel::HandleIPCCommand(const Request& request)
|
||||
{
|
||||
if (request.command < IPC_CMD_OPEN || request.command > IPC_CMD_IOCTLV)
|
||||
return IPCReply{IPC_EINVAL, 978_tbticks};
|
||||
|
||||
if (request.command == IPC_CMD_OPEN)
|
||||
{
|
||||
OpenRequest open_request{request.address};
|
||||
OpenRequest open_request{GetSystem(), request.address};
|
||||
return OpenDevice(open_request);
|
||||
}
|
||||
|
||||
@ -716,19 +717,19 @@ std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
|
||||
ret = device->Close(request.fd);
|
||||
break;
|
||||
case IPC_CMD_READ:
|
||||
ret = device->Read(ReadWriteRequest{request.address});
|
||||
ret = device->Read(ReadWriteRequest{GetSystem(), request.address});
|
||||
break;
|
||||
case IPC_CMD_WRITE:
|
||||
ret = device->Write(ReadWriteRequest{request.address});
|
||||
ret = device->Write(ReadWriteRequest{GetSystem(), request.address});
|
||||
break;
|
||||
case IPC_CMD_SEEK:
|
||||
ret = device->Seek(SeekRequest{request.address});
|
||||
ret = device->Seek(SeekRequest{GetSystem(), request.address});
|
||||
break;
|
||||
case IPC_CMD_IOCTL:
|
||||
ret = device->IOCtl(IOCtlRequest{request.address});
|
||||
ret = device->IOCtl(IOCtlRequest{GetSystem(), request.address});
|
||||
break;
|
||||
case IPC_CMD_IOCTLV:
|
||||
ret = device->IOCtlV(IOCtlVRequest{request.address});
|
||||
ret = device->IOCtlV(IOCtlVRequest{GetSystem(), request.address});
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(IOS, false, "Unexpected command: {:#x}", static_cast<u32>(request.command));
|
||||
@ -747,17 +748,16 @@ std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Kernel::ExecuteIPCCommand(const u32 address)
|
||||
void EmulationKernel::ExecuteIPCCommand(const u32 address)
|
||||
{
|
||||
Request request{address};
|
||||
Request request{GetSystem(), address};
|
||||
std::optional<IPCReply> result = HandleIPCCommand(request);
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
// Ensure replies happen in order
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& core_timing = system.GetCoreTiming();
|
||||
auto& core_timing = GetSystem().GetCoreTiming();
|
||||
const s64 ticks_until_last_reply = m_last_reply_time - core_timing.GetTicks();
|
||||
if (ticks_until_last_reply > 0)
|
||||
result->reply_delay_ticks += ticks_until_last_reply;
|
||||
@ -767,20 +767,20 @@ void Kernel::ExecuteIPCCommand(const u32 address)
|
||||
}
|
||||
|
||||
// Happens AS SOON AS IPC gets a new pointer!
|
||||
void Kernel::EnqueueIPCRequest(u32 address)
|
||||
void EmulationKernel::EnqueueIPCRequest(u32 address)
|
||||
{
|
||||
// Based on hardware tests, IOS takes between 5µs and 10µs to acknowledge an IPC request.
|
||||
// Console 1: 456 TB ticks before ACK
|
||||
// Console 2: 658 TB ticks before ACK
|
||||
Core::System::GetInstance().GetCoreTiming().ScheduleEvent(500_tbticks, s_event_enqueue,
|
||||
address | ENQUEUE_REQUEST_FLAG);
|
||||
GetSystem().GetCoreTiming().ScheduleEvent(500_tbticks, s_event_enqueue,
|
||||
address | ENQUEUE_REQUEST_FLAG);
|
||||
}
|
||||
|
||||
// Called to send a reply to an IOS syscall
|
||||
void Kernel::EnqueueIPCReply(const Request& request, const s32 return_value, s64 cycles_in_future,
|
||||
CoreTiming::FromThread from)
|
||||
void EmulationKernel::EnqueueIPCReply(const Request& request, const s32 return_value,
|
||||
s64 cycles_in_future, CoreTiming::FromThread from)
|
||||
{
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& system = GetSystem();
|
||||
auto& memory = system.GetMemory();
|
||||
memory.Write_U32(static_cast<u32>(return_value), request.address + 4);
|
||||
// IOS writes back the command that was responded to in the FD field.
|
||||
@ -790,7 +790,7 @@ void Kernel::EnqueueIPCReply(const Request& request, const s32 return_value, s64
|
||||
system.GetCoreTiming().ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from);
|
||||
}
|
||||
|
||||
void Kernel::HandleIPCEvent(u64 userdata)
|
||||
void EmulationKernel::HandleIPCEvent(u64 userdata)
|
||||
{
|
||||
if (userdata & ENQUEUE_REQUEST_FLAG)
|
||||
m_request_queue.push_back(static_cast<u32>(userdata));
|
||||
@ -800,7 +800,7 @@ void Kernel::HandleIPCEvent(u64 userdata)
|
||||
UpdateIPC();
|
||||
}
|
||||
|
||||
void Kernel::UpdateIPC()
|
||||
void EmulationKernel::UpdateIPC()
|
||||
{
|
||||
if (m_ipc_paused || !IsReady())
|
||||
return;
|
||||
@ -824,7 +824,7 @@ void Kernel::UpdateIPC()
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::UpdateDevices()
|
||||
void EmulationKernel::UpdateDevices()
|
||||
{
|
||||
// Check if a hardware device must be updated
|
||||
for (const auto& entry : m_device_map)
|
||||
@ -836,7 +836,7 @@ void Kernel::UpdateDevices()
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::UpdateWantDeterminism(const bool new_want_determinism)
|
||||
void EmulationKernel::UpdateWantDeterminism(const bool new_want_determinism)
|
||||
{
|
||||
if (m_socket_manager)
|
||||
m_socket_manager->UpdateWantDeterminism(new_want_determinism);
|
||||
@ -844,7 +844,7 @@ void Kernel::UpdateWantDeterminism(const bool new_want_determinism)
|
||||
device.second->UpdateWantDeterminism(new_want_determinism);
|
||||
}
|
||||
|
||||
void Kernel::DoState(PointerWrap& p)
|
||||
void EmulationKernel::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_request_queue);
|
||||
p.Do(m_reply_queue);
|
||||
@ -954,15 +954,15 @@ void Init()
|
||||
s_event_finish_ppc_bootstrap =
|
||||
core_timing.RegisterEvent("IOSFinishPPCBootstrap", FinishPPCBootstrap);
|
||||
|
||||
s_event_finish_ios_boot =
|
||||
core_timing.RegisterEvent("IOSFinishIOSBoot", [](Core::System& system_, u64 ios_title_id,
|
||||
s64) { FinishIOSBoot(ios_title_id); });
|
||||
s_event_finish_ios_boot = core_timing.RegisterEvent(
|
||||
"IOSFinishIOSBoot",
|
||||
[](Core::System& system_, u64 ios_title_id, s64) { FinishIOSBoot(system_, ios_title_id); });
|
||||
|
||||
DIDevice::s_finish_executing_di_command =
|
||||
core_timing.RegisterEvent("FinishDICommand", DIDevice::FinishDICommandCallback);
|
||||
|
||||
// Start with IOS80 to simulate part of the Wii boot process.
|
||||
s_ios = std::make_unique<EmulationKernel>(Titles::SYSTEM_MENU_IOS);
|
||||
s_ios = std::make_unique<EmulationKernel>(system, Titles::SYSTEM_MENU_IOS);
|
||||
// On a Wii, boot2 launches the system menu IOS, which then launches the system menu
|
||||
// (which bootstraps the PPC). Bootstrapping the PPC results in memory values being set up.
|
||||
// This means that the constants in the 0x3100 region are always set up by the time
|
||||
|
Reference in New Issue
Block a user