IOS: Check for available features when adding devices
Prevents resource managers that shouldn't be visible from being exposed to titles. This adds a new function to get features for an IOS version, and also moves the version checks from the modules themselves to VersionInfo. This hopefully documents some of the differences between IOS better and should be slightly cleaner than having random version checks.
This commit is contained in:
parent
24e7b465be
commit
e4ea4da782
|
@ -345,32 +345,69 @@ void Kernel::AddStaticDevices()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_device_map_mutex);
|
std::lock_guard<std::mutex> lock(m_device_map_mutex);
|
||||||
|
|
||||||
|
const Feature features = GetFeatures(GetVersion());
|
||||||
|
|
||||||
|
// OH1 (Bluetooth)
|
||||||
|
AddDevice(std::make_unique<Device::Stub>(*this, "/dev/usb/oh1"));
|
||||||
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
|
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
|
||||||
AddDevice(std::make_unique<Device::BluetoothEmu>(*this, "/dev/usb/oh1/57e/305"));
|
AddDevice(std::make_unique<Device::BluetoothEmu>(*this, "/dev/usb/oh1/57e/305"));
|
||||||
else
|
else
|
||||||
AddDevice(std::make_unique<Device::BluetoothReal>(*this, "/dev/usb/oh1/57e/305"));
|
AddDevice(std::make_unique<Device::BluetoothReal>(*this, "/dev/usb/oh1/57e/305"));
|
||||||
|
|
||||||
|
// Other core modules
|
||||||
AddDevice(std::make_unique<Device::STMImmediate>(*this, "/dev/stm/immediate"));
|
AddDevice(std::make_unique<Device::STMImmediate>(*this, "/dev/stm/immediate"));
|
||||||
AddDevice(std::make_unique<Device::STMEventHook>(*this, "/dev/stm/eventhook"));
|
AddDevice(std::make_unique<Device::STMEventHook>(*this, "/dev/stm/eventhook"));
|
||||||
AddDevice(std::make_unique<Device::DI>(*this, "/dev/di"));
|
AddDevice(std::make_unique<Device::DI>(*this, "/dev/di"));
|
||||||
AddDevice(std::make_unique<Device::NetKDRequest>(*this, "/dev/net/kd/request"));
|
|
||||||
AddDevice(std::make_unique<Device::NetKDTime>(*this, "/dev/net/kd/time"));
|
|
||||||
AddDevice(std::make_unique<Device::NetNCDManage>(*this, "/dev/net/ncd/manage"));
|
|
||||||
AddDevice(std::make_unique<Device::NetWDCommand>(*this, "/dev/net/wd/command"));
|
|
||||||
AddDevice(std::make_unique<Device::NetIPTop>(*this, "/dev/net/ip/top"));
|
|
||||||
AddDevice(std::make_unique<Device::NetSSL>(*this, "/dev/net/ssl"));
|
|
||||||
AddDevice(std::make_unique<Device::USB_KBD>(*this, "/dev/usb/kbd"));
|
|
||||||
AddDevice(std::make_unique<Device::SDIOSlot0>(*this, "/dev/sdio/slot0"));
|
AddDevice(std::make_unique<Device::SDIOSlot0>(*this, "/dev/sdio/slot0"));
|
||||||
AddDevice(std::make_unique<Device::Stub>(*this, "/dev/sdio/slot1"));
|
AddDevice(std::make_unique<Device::Stub>(*this, "/dev/sdio/slot1"));
|
||||||
if (GetVersion() == 59)
|
|
||||||
AddDevice(std::make_unique<Device::USB_HIDv5>(*this, "/dev/usb/hid"));
|
// Network modules
|
||||||
else
|
if (HasFeature(features, Feature::KD))
|
||||||
AddDevice(std::make_unique<Device::USB_HIDv4>(*this, "/dev/usb/hid"));
|
{
|
||||||
|
AddDevice(std::make_unique<Device::NetKDRequest>(*this, "/dev/net/kd/request"));
|
||||||
|
AddDevice(std::make_unique<Device::NetKDTime>(*this, "/dev/net/kd/time"));
|
||||||
|
}
|
||||||
|
if (HasFeature(features, Feature::NCD))
|
||||||
|
{
|
||||||
|
AddDevice(std::make_unique<Device::NetNCDManage>(*this, "/dev/net/ncd/manage"));
|
||||||
|
}
|
||||||
|
if (HasFeature(features, Feature::WiFi))
|
||||||
|
{
|
||||||
|
AddDevice(std::make_unique<Device::NetWDCommand>(*this, "/dev/net/wd/command"));
|
||||||
|
}
|
||||||
|
if (HasFeature(features, Feature::SO))
|
||||||
|
{
|
||||||
|
AddDevice(std::make_unique<Device::NetIPTop>(*this, "/dev/net/ip/top"));
|
||||||
|
}
|
||||||
|
if (HasFeature(features, Feature::SSL))
|
||||||
|
{
|
||||||
|
AddDevice(std::make_unique<Device::NetSSL>(*this, "/dev/net/ssl"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// USB modules
|
||||||
|
// OH0 is unconditionally added because this device path is registered in all cases.
|
||||||
AddDevice(std::make_unique<Device::OH0>(*this, "/dev/usb/oh0"));
|
AddDevice(std::make_unique<Device::OH0>(*this, "/dev/usb/oh0"));
|
||||||
AddDevice(std::make_unique<Device::Stub>(*this, "/dev/usb/oh1"));
|
if (HasFeature(features, Feature::NewUSB))
|
||||||
AddDevice(std::make_unique<Device::USB_VEN>(*this, "/dev/usb/ven"));
|
{
|
||||||
AddDevice(std::make_unique<Device::WFSSRV>(*this, "/dev/usb/wfssrv"));
|
AddDevice(std::make_unique<Device::USB_HIDv5>(*this, "/dev/usb/hid"));
|
||||||
AddDevice(std::make_unique<Device::WFSI>(*this, "/dev/wfsi"));
|
AddDevice(std::make_unique<Device::USB_VEN>(*this, "/dev/usb/ven"));
|
||||||
|
|
||||||
|
// TODO(IOS): register /dev/usb/usb, /dev/usb/msc, /dev/usb/hub and /dev/usb/ehc
|
||||||
|
// as stubs that return IPC_EACCES.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (HasFeature(features, Feature::USB_HIDv4))
|
||||||
|
AddDevice(std::make_unique<Device::USB_HIDv4>(*this, "/dev/usb/hid"));
|
||||||
|
if (HasFeature(features, Feature::USB_KBD))
|
||||||
|
AddDevice(std::make_unique<Device::USB_KBD>(*this, "/dev/usb/kbd"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasFeature(features, Feature::WFS))
|
||||||
|
{
|
||||||
|
AddDevice(std::make_unique<Device::WFSSRV>(*this, "/dev/usb/wfssrv"));
|
||||||
|
AddDevice(std::make_unique<Device::WFSI>(*this, "/dev/wfsi"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Kernel::GetFreeDeviceID()
|
s32 Kernel::GetFreeDeviceID()
|
||||||
|
@ -411,7 +448,8 @@ s32 Kernel::OpenDevice(OpenRequest& request)
|
||||||
request.fd = new_fd;
|
request.fd = new_fd;
|
||||||
|
|
||||||
std::shared_ptr<Device::Device> device;
|
std::shared_ptr<Device::Device> device;
|
||||||
if (request.path.find("/dev/usb/oh0/") == 0 && !GetDeviceByName(request.path))
|
if (request.path.find("/dev/usb/oh0/") == 0 && !GetDeviceByName(request.path) &&
|
||||||
|
!HasFeature(GetVersion(), Feature::NewUSB))
|
||||||
{
|
{
|
||||||
device = std::make_shared<Device::OH0Device>(*this, request.path);
|
device = std::make_shared<Device::OH0Device>(*this, request.path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
|
#include "Core/IOS/VersionInfo.h"
|
||||||
|
|
||||||
namespace IOS
|
namespace IOS
|
||||||
{
|
{
|
||||||
|
@ -25,28 +26,8 @@ namespace HLE
|
||||||
{
|
{
|
||||||
namespace Device
|
namespace Device
|
||||||
{
|
{
|
||||||
constexpr bool SupportsSDHC(u32 ios_version)
|
|
||||||
{
|
|
||||||
switch (ios_version)
|
|
||||||
{
|
|
||||||
// Known versions to support SDHC
|
|
||||||
case 48:
|
|
||||||
case 56:
|
|
||||||
case 57:
|
|
||||||
case 58:
|
|
||||||
case 59:
|
|
||||||
case 60:
|
|
||||||
case 61:
|
|
||||||
case 70:
|
|
||||||
case 80:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
SDIOSlot0::SDIOSlot0(Kernel& ios, const std::string& device_name)
|
SDIOSlot0::SDIOSlot0(Kernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name), m_sdhc_supported(SupportsSDHC(ios.GetVersion()))
|
: Device(ios, device_name), m_sdhc_supported(HasFeature(ios.GetVersion(), Feature::SDv2))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/IOS/USB/Common.h"
|
#include "Core/IOS/USB/Common.h"
|
||||||
#include "Core/IOS/USB/USBV0.h"
|
#include "Core/IOS/USB/USBV0.h"
|
||||||
|
#include "Core/IOS/VersionInfo.h"
|
||||||
|
|
||||||
namespace IOS
|
namespace IOS
|
||||||
{
|
{
|
||||||
|
@ -36,8 +37,7 @@ OH0::~OH0()
|
||||||
|
|
||||||
ReturnCode OH0::Open(const OpenRequest& request)
|
ReturnCode OH0::Open(const OpenRequest& request)
|
||||||
{
|
{
|
||||||
const u32 ios_major_version = m_ios.GetVersion();
|
if (HasFeature(m_ios.GetVersion(), Feature::NewUSB))
|
||||||
if (ios_major_version == 57 || ios_major_version == 58 || ios_major_version == 59)
|
|
||||||
return IPC_EACCES;
|
return IPC_EACCES;
|
||||||
return USBHost::Open(request);
|
return USBHost::Open(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,6 @@ void OH0Device::DoState(PointerWrap& p)
|
||||||
|
|
||||||
ReturnCode OH0Device::Open(const OpenRequest& request)
|
ReturnCode OH0Device::Open(const OpenRequest& request)
|
||||||
{
|
{
|
||||||
const u32 ios_major_version = m_ios.GetVersion();
|
|
||||||
if (ios_major_version == 57 || ios_major_version == 58 || ios_major_version == 59)
|
|
||||||
return IPC_ENOENT;
|
|
||||||
|
|
||||||
if (m_vid == 0 && m_pid == 0)
|
if (m_vid == 0 && m_pid == 0)
|
||||||
return IPC_ENOENT;
|
return IPC_ENOENT;
|
||||||
|
|
||||||
|
|
|
@ -35,14 +35,6 @@ USB_VEN::~USB_VEN()
|
||||||
StopThreads();
|
StopThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnCode USB_VEN::Open(const OpenRequest& request)
|
|
||||||
{
|
|
||||||
const u32 ios_major_version = m_ios.GetVersion();
|
|
||||||
if (ios_major_version != 57 && ios_major_version != 58 && ios_major_version != 59)
|
|
||||||
return IPC_ENOENT;
|
|
||||||
return USBHost::Open(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
IPCCommandResult USB_VEN::IOCtl(const IOCtlRequest& request)
|
IPCCommandResult USB_VEN::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
request.Log(GetDeviceName(), LogTypes::IOS_USB);
|
request.Log(GetDeviceName(), LogTypes::IOS_USB);
|
||||||
|
|
|
@ -31,7 +31,6 @@ public:
|
||||||
USB_VEN(Kernel& ios, const std::string& device_name);
|
USB_VEN(Kernel& ios, const std::string& device_name);
|
||||||
~USB_VEN() override;
|
~USB_VEN() override;
|
||||||
|
|
||||||
ReturnCode Open(const OpenRequest& request) override;
|
|
||||||
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
|
||||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||||
|
|
||||||
|
|
|
@ -335,5 +335,44 @@ const std::array<MemoryValues, 41>& GetMemoryValues()
|
||||||
{
|
{
|
||||||
return ios_memory_values;
|
return ios_memory_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Feature GetFeatures(u32 version)
|
||||||
|
{
|
||||||
|
// Common features that are present in most versions.
|
||||||
|
Feature features = Feature::Core | Feature::SDIO | Feature::SO | Feature::Ethernet;
|
||||||
|
|
||||||
|
// IOS4 is a tiny IOS that was presumably used during manufacturing. It lacks network support.
|
||||||
|
if (version != 4)
|
||||||
|
features |= Feature::KD | Feature::SSL | Feature::NCD | Feature::WiFi;
|
||||||
|
|
||||||
|
if (version == 48 || (version >= 56 && version <= 62) || version == 70 || version == 80)
|
||||||
|
features |= Feature::SDv2;
|
||||||
|
|
||||||
|
if (version == 57 || version == 58 || version == 59)
|
||||||
|
features |= Feature::NewUSB;
|
||||||
|
if (version == 58 || version == 59)
|
||||||
|
features |= Feature::EHCI;
|
||||||
|
if (version == 59)
|
||||||
|
features |= Feature::WFS;
|
||||||
|
|
||||||
|
// No IOS earlier than IOS30 has USB_KBD. Any IOS with the new USB modules lacks this module.
|
||||||
|
// TODO(IOS): it is currently unknown which other versions don't have it.
|
||||||
|
if (version >= 30 && !HasFeature(features, Feature::NewUSB))
|
||||||
|
features |= Feature::USB_KBD;
|
||||||
|
|
||||||
|
// Just like KBD, USB_HIDv4 is not present on any IOS with the new USB modules
|
||||||
|
// (since it's been replaced with USB_HIDv5 there).
|
||||||
|
// Additionally, it appears that HIDv4 and KBD are never both present.
|
||||||
|
// TODO(IOS): figure out which versions have HIDv4. For now we just include both KBD and HIDv4.
|
||||||
|
if (!HasFeature(features, Feature::NewUSB))
|
||||||
|
features |= Feature::USB_HIDv4;
|
||||||
|
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasFeature(u32 major_version, Feature feature)
|
||||||
|
{
|
||||||
|
return HasFeature(GetFeatures(major_version), feature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,5 +37,51 @@ struct MemoryValues
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<MemoryValues, 41>& GetMemoryValues();
|
const std::array<MemoryValues, 41>& GetMemoryValues();
|
||||||
|
|
||||||
|
enum class Feature
|
||||||
|
{
|
||||||
|
// Kernel, ES, FS, STM, DI, OH0, OH1
|
||||||
|
Core = 1 << 0,
|
||||||
|
// SDIO
|
||||||
|
SDIO = 1 << 1,
|
||||||
|
// Network (base support: SO, Ethernet; KD, SSL, NCD, Wi-Fi)
|
||||||
|
SO = 1 << 2,
|
||||||
|
Ethernet = 1 << 3,
|
||||||
|
KD = 1 << 4,
|
||||||
|
SSL = 1 << 5,
|
||||||
|
NCD = 1 << 6,
|
||||||
|
WiFi = 1 << 7,
|
||||||
|
// KBD
|
||||||
|
USB_KBD = 1 << 8,
|
||||||
|
// USB_HID v4
|
||||||
|
USB_HIDv4 = 1 << 9,
|
||||||
|
// SDv2 support
|
||||||
|
SDv2 = 1 << 10,
|
||||||
|
// New USB modules (USB, USB_VEN, USB_HUB, USB_MSC, OHCI0, USB_HIDv5)
|
||||||
|
NewUSB = 1 << 11,
|
||||||
|
// EHCI
|
||||||
|
EHCI = 1 << 12,
|
||||||
|
// WFS (WFSSRV, WFSI, USB_SHARED)
|
||||||
|
WFS = 1 << 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr Feature operator|(Feature lhs, Feature rhs)
|
||||||
|
{
|
||||||
|
return static_cast<Feature>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Feature& operator|=(Feature& lhs, Feature rhs)
|
||||||
|
{
|
||||||
|
lhs = lhs | rhs;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool HasFeature(Feature features, Feature feature)
|
||||||
|
{
|
||||||
|
return (static_cast<int>(features) & static_cast<int>(feature)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasFeature(u32 major_version, Feature feature);
|
||||||
|
Feature GetFeatures(u32 major_version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue