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); +} +}