Merge pull request #5943 from leoetlino/features

IOS: Check for available features when adding devices
This commit is contained in:
JosJuice 2017-11-19 21:43:54 +01:00 committed by GitHub
commit b3b58b586c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 193 additions and 102 deletions

View File

@ -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

View File

@ -185,8 +185,8 @@
<ClCompile Include="IOS\DeviceStub.cpp" />
<ClCompile Include="IOS\IOS.cpp" />
<ClCompile Include="IOS\IOSC.cpp" />
<ClCompile Include="IOS\MemoryValues.cpp" />
<ClCompile Include="IOS\MIOS.cpp" />
<ClCompile Include="IOS\VersionInfo.cpp" />
<ClCompile Include="IOS\DI\DI.cpp" />
<ClCompile Include="IOS\ES\ES.cpp" />
<ClCompile Include="IOS\ES\Formats.cpp" />
@ -442,8 +442,8 @@
<ClInclude Include="IOS\DeviceStub.h" />
<ClInclude Include="IOS\IOS.h" />
<ClInclude Include="IOS\IOSC.h" />
<ClInclude Include="IOS\MemoryValues.h" />
<ClInclude Include="IOS\MIOS.h" />
<ClInclude Include="IOS\VersionInfo.h" />
<ClInclude Include="IOS\DI\DI.h" />
<ClInclude Include="IOS\ES\ES.h" />
<ClInclude Include="IOS\ES\Formats.h" />

View File

@ -769,10 +769,10 @@
<ClCompile Include="IOS\IOSC.cpp">
<Filter>IOS</Filter>
</ClCompile>
<ClCompile Include="IOS\MemoryValues.cpp">
<ClCompile Include="IOS\MIOS.cpp">
<Filter>IOS</Filter>
</ClCompile>
<ClCompile Include="IOS\MIOS.cpp">
<ClCompile Include="IOS\VersionInfo.cpp">
<Filter>IOS</Filter>
</ClCompile>
<ClCompile Include="IOS\Network\MACUtils.cpp">
@ -1511,10 +1511,10 @@
<ClInclude Include="IOS\IOSC.h">
<Filter>IOS</Filter>
</ClInclude>
<ClInclude Include="IOS\MemoryValues.h">
<ClInclude Include="IOS\MIOS.h">
<Filter>IOS</Filter>
</ClInclude>
<ClInclude Include="IOS\MIOS.h">
<ClInclude Include="IOS\VersionInfo.h">
<Filter>IOS</Filter>
</ClInclude>
<ClInclude Include="PowerPC\Jit64Common\ConstantPool.h">

View File

@ -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<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)
AddDevice(std::make_unique<Device::BluetoothEmu>(*this, "/dev/usb/oh1/57e/305"));
else
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::STMEventHook>(*this, "/dev/stm/eventhook"));
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::Stub>(*this, "/dev/sdio/slot1"));
if (GetVersion() == 59)
AddDevice(std::make_unique<Device::USB_HIDv5>(*this, "/dev/usb/hid"));
else
AddDevice(std::make_unique<Device::USB_HIDv4>(*this, "/dev/usb/hid"));
// Network modules
if (HasFeature(features, Feature::KD))
{
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::Stub>(*this, "/dev/usb/oh1"));
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::WFSI>(*this, "/dev/wfsi"));
if (HasFeature(features, Feature::NewUSB))
{
AddDevice(std::make_unique<Device::USB_HIDv5>(*this, "/dev/usb/hid"));
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()
@ -443,7 +480,8 @@ s32 Kernel::OpenDevice(OpenRequest& request)
request.fd = new_fd;
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);
}

View File

@ -1,41 +0,0 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <array>
#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<MemoryValues, 41>& GetMemoryValues();
}
}

View File

@ -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))
{
}

View File

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

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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 <array>
@ -335,5 +335,44 @@ const std::array<MemoryValues, 41>& 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);
}
}
}

View File

@ -0,0 +1,87 @@
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <array>
#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<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);
}
}