diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index 96bbe1d15c..2ac4c204c1 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -155,8 +155,8 @@ set(SRCS
IOS/DeviceStub.cpp
IOS/IOS.cpp
IOS/IOSC.cpp
- IOS/MemoryValues.cpp
IOS/MIOS.cpp
+ IOS/VersionInfo.cpp
IOS/DI/DI.cpp
IOS/ES/ES.cpp
IOS/ES/Formats.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 5e275711de..10e0e019b9 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -185,8 +185,8 @@
-
+
@@ -442,8 +442,8 @@
-
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 167fcec007..c9f2ea8deb 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -769,10 +769,10 @@
IOS
-
+
IOS
-
+
IOS
@@ -1511,10 +1511,10 @@
IOS
-
+
IOS
-
+
IOS
diff --git a/Source/Core/Core/IOS/IOS.cpp b/Source/Core/Core/IOS/IOS.cpp
index fa5b84ed02..649d4338cf 100644
--- a/Source/Core/Core/IOS/IOS.cpp
+++ b/Source/Core/Core/IOS/IOS.cpp
@@ -34,7 +34,6 @@
#include "Core/IOS/FS/FS.h"
#include "Core/IOS/FS/FileIO.h"
#include "Core/IOS/MIOS.h"
-#include "Core/IOS/MemoryValues.h"
#include "Core/IOS/Network/IP/Top.h"
#include "Core/IOS/Network/KD/NetKDRequest.h"
#include "Core/IOS/Network/KD/NetKDTime.h"
@@ -52,6 +51,7 @@
#include "Core/IOS/USB/USB_HID/HIDv5.h"
#include "Core/IOS/USB/USB_KBD.h"
#include "Core/IOS/USB/USB_VEN/VEN.h"
+#include "Core/IOS/VersionInfo.h"
#include "Core/IOS/WFS/WFSI.h"
#include "Core/IOS/WFS/WFSSRV.h"
#include "Core/PowerPC/PowerPC.h"
@@ -377,32 +377,69 @@ void Kernel::AddStaticDevices()
{
std::lock_guard lock(m_device_map_mutex);
+ const Feature features = GetFeatures(GetVersion());
+
+ // OH1 (Bluetooth)
+ AddDevice(std::make_unique(*this, "/dev/usb/oh1"));
if (!SConfig::GetInstance().m_bt_passthrough_enabled)
AddDevice(std::make_unique(*this, "/dev/usb/oh1/57e/305"));
else
AddDevice(std::make_unique(*this, "/dev/usb/oh1/57e/305"));
+ // Other core modules
AddDevice(std::make_unique(*this, "/dev/stm/immediate"));
AddDevice(std::make_unique(*this, "/dev/stm/eventhook"));
AddDevice(std::make_unique(*this, "/dev/di"));
- AddDevice(std::make_unique(*this, "/dev/net/kd/request"));
- AddDevice(std::make_unique(*this, "/dev/net/kd/time"));
- AddDevice(std::make_unique(*this, "/dev/net/ncd/manage"));
- AddDevice(std::make_unique(*this, "/dev/net/wd/command"));
- AddDevice(std::make_unique(*this, "/dev/net/ip/top"));
- AddDevice(std::make_unique(*this, "/dev/net/ssl"));
- AddDevice(std::make_unique(*this, "/dev/usb/kbd"));
AddDevice(std::make_unique(*this, "/dev/sdio/slot0"));
AddDevice(std::make_unique(*this, "/dev/sdio/slot1"));
- if (GetVersion() == 59)
- AddDevice(std::make_unique(*this, "/dev/usb/hid"));
- else
- AddDevice(std::make_unique(*this, "/dev/usb/hid"));
+
+ // Network modules
+ if (HasFeature(features, Feature::KD))
+ {
+ AddDevice(std::make_unique(*this, "/dev/net/kd/request"));
+ AddDevice(std::make_unique(*this, "/dev/net/kd/time"));
+ }
+ if (HasFeature(features, Feature::NCD))
+ {
+ AddDevice(std::make_unique(*this, "/dev/net/ncd/manage"));
+ }
+ if (HasFeature(features, Feature::WiFi))
+ {
+ AddDevice(std::make_unique(*this, "/dev/net/wd/command"));
+ }
+ if (HasFeature(features, Feature::SO))
+ {
+ AddDevice(std::make_unique(*this, "/dev/net/ip/top"));
+ }
+ if (HasFeature(features, Feature::SSL))
+ {
+ AddDevice(std::make_unique(*this, "/dev/net/ssl"));
+ }
+
+ // USB modules
+ // OH0 is unconditionally added because this device path is registered in all cases.
AddDevice(std::make_unique(*this, "/dev/usb/oh0"));
- AddDevice(std::make_unique(*this, "/dev/usb/oh1"));
- AddDevice(std::make_unique(*this, "/dev/usb/ven"));
- AddDevice(std::make_unique(*this, "/dev/usb/wfssrv"));
- AddDevice(std::make_unique(*this, "/dev/wfsi"));
+ if (HasFeature(features, Feature::NewUSB))
+ {
+ AddDevice(std::make_unique(*this, "/dev/usb/hid"));
+ AddDevice(std::make_unique(*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(*this, "/dev/usb/hid"));
+ if (HasFeature(features, Feature::USB_KBD))
+ AddDevice(std::make_unique(*this, "/dev/usb/kbd"));
+ }
+
+ if (HasFeature(features, Feature::WFS))
+ {
+ AddDevice(std::make_unique(*this, "/dev/usb/wfssrv"));
+ AddDevice(std::make_unique(*this, "/dev/wfsi"));
+ }
}
s32 Kernel::GetFreeDeviceID()
@@ -443,7 +480,8 @@ s32 Kernel::OpenDevice(OpenRequest& request)
request.fd = new_fd;
std::shared_ptr 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(*this, request.path);
}
diff --git a/Source/Core/Core/IOS/MemoryValues.h b/Source/Core/Core/IOS/MemoryValues.h
deleted file mode 100644
index d04dedd9c5..0000000000
--- a/Source/Core/Core/IOS/MemoryValues.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2017 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include
-
-#include "Common/CommonTypes.h"
-
-namespace IOS
-{
-namespace HLE
-{
-struct MemoryValues
-{
- u16 ios_number;
- u32 ios_version;
- u32 ios_date;
- u32 mem1_physical_size;
- u32 mem1_simulated_size;
- u32 mem1_end;
- u32 mem1_arena_begin;
- u32 mem1_arena_end;
- u32 mem2_physical_size;
- u32 mem2_simulated_size;
- u32 mem2_end;
- u32 mem2_arena_begin;
- u32 mem2_arena_end;
- u32 ipc_buffer_begin;
- u32 ipc_buffer_end;
- u32 hollywood_revision;
- u32 ram_vendor;
- u32 unknown_begin;
- u32 unknown_end;
- u32 sysmenu_sync;
-};
-
-const std::array& GetMemoryValues();
-}
-}
diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
index 2b8fa3e79d..66c7bcde0f 100644
--- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
+++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
@@ -18,6 +18,7 @@
#include "Core/ConfigManager.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/IOS.h"
+#include "Core/IOS/VersionInfo.h"
namespace IOS
{
@@ -25,28 +26,8 @@ namespace HLE
{
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)
- : Device(ios, device_name), m_sdhc_supported(SupportsSDHC(ios.GetVersion()))
+ : Device(ios, device_name), m_sdhc_supported(HasFeature(ios.GetVersion(), Feature::SDv2))
{
}
diff --git a/Source/Core/Core/IOS/USB/OH0/OH0.cpp b/Source/Core/Core/IOS/USB/OH0/OH0.cpp
index 85760299bd..3b574bcc5c 100644
--- a/Source/Core/Core/IOS/USB/OH0/OH0.cpp
+++ b/Source/Core/Core/IOS/USB/OH0/OH0.cpp
@@ -18,6 +18,7 @@
#include "Core/HW/Memmap.h"
#include "Core/IOS/USB/Common.h"
#include "Core/IOS/USB/USBV0.h"
+#include "Core/IOS/VersionInfo.h"
namespace IOS
{
@@ -36,8 +37,7 @@ OH0::~OH0()
ReturnCode OH0::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)
+ if (HasFeature(m_ios.GetVersion(), Feature::NewUSB))
return IPC_EACCES;
return USBHost::Open(request);
}
diff --git a/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp b/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp
index ab1cafc25b..0b8c56d0ea 100644
--- a/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp
+++ b/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp
@@ -57,10 +57,6 @@ void OH0Device::DoState(PointerWrap& p)
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)
return IPC_ENOENT;
diff --git a/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp b/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp
index 8e71f5b6d9..25519b753d 100644
--- a/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp
+++ b/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp
@@ -24,14 +24,6 @@ constexpr u32 USBV5_VERSION = 0x50001;
USB_VEN::~USB_VEN() = default;
-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)
{
request.Log(GetDeviceName(), LogTypes::IOS_USB);
diff --git a/Source/Core/Core/IOS/USB/USB_VEN/VEN.h b/Source/Core/Core/IOS/USB/USB_VEN/VEN.h
index 8205b0ca2d..1bc62225b9 100644
--- a/Source/Core/Core/IOS/USB/USB_VEN/VEN.h
+++ b/Source/Core/Core/IOS/USB/USB_VEN/VEN.h
@@ -21,7 +21,6 @@ public:
using USBV5ResourceManager::USBV5ResourceManager;
~USB_VEN() override;
- ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
diff --git a/Source/Core/Core/IOS/MemoryValues.cpp b/Source/Core/Core/IOS/VersionInfo.cpp
similarity index 90%
rename from Source/Core/Core/IOS/MemoryValues.cpp
rename to Source/Core/Core/IOS/VersionInfo.cpp
index ec05088df5..38e4eb003e 100644
--- a/Source/Core/Core/IOS/MemoryValues.cpp
+++ b/Source/Core/Core/IOS/VersionInfo.cpp
@@ -2,7 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
-#include "Core/IOS/MemoryValues.h"
+#include "Core/IOS/VersionInfo.h"
#include
@@ -335,5 +335,44 @@ const std::array& GetMemoryValues()
{
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);
+}
}
}
diff --git a/Source/Core/Core/IOS/VersionInfo.h b/Source/Core/Core/IOS/VersionInfo.h
new file mode 100644
index 0000000000..1b64b8b2aa
--- /dev/null
+++ b/Source/Core/Core/IOS/VersionInfo.h
@@ -0,0 +1,87 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+
+#include "Common/CommonTypes.h"
+
+namespace IOS
+{
+namespace HLE
+{
+struct MemoryValues
+{
+ u16 ios_number;
+ u32 ios_version;
+ u32 ios_date;
+ u32 mem1_physical_size;
+ u32 mem1_simulated_size;
+ u32 mem1_end;
+ u32 mem1_arena_begin;
+ u32 mem1_arena_end;
+ u32 mem2_physical_size;
+ u32 mem2_simulated_size;
+ u32 mem2_end;
+ u32 mem2_arena_begin;
+ u32 mem2_arena_end;
+ u32 ipc_buffer_begin;
+ u32 ipc_buffer_end;
+ u32 hollywood_revision;
+ u32 ram_vendor;
+ u32 unknown_begin;
+ u32 unknown_end;
+ u32 sysmenu_sync;
+};
+
+const std::array& 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(static_cast(lhs) | static_cast(rhs));
+}
+
+constexpr Feature& operator|=(Feature& lhs, Feature rhs)
+{
+ lhs = lhs | rhs;
+ return lhs;
+}
+
+constexpr bool HasFeature(Feature features, Feature feature)
+{
+ return (static_cast(features) & static_cast(feature)) != 0;
+}
+
+bool HasFeature(u32 major_version, Feature feature);
+Feature GetFeatures(u32 major_version);
+}
+}