Skip to content
Permalink
Browse files
Merge pull request #9300 from leoetlino/ncd-wd-fixes
IOS: WD and NCD fixes
  • Loading branch information
delroth committed Jan 5, 2021
2 parents eafb9de + 9b3cdd0 commit 27013e8
Show file tree
Hide file tree
Showing 9 changed files with 463 additions and 38 deletions.
@@ -133,7 +133,7 @@ void DolphinAnalytics::ReportGameStart()
}

// Keep in sync with enum class GameQuirk definition.
constexpr std::array<const char*, 12> GAME_QUIRKS_NAMES{"icache-matters",
constexpr std::array<const char*, 14> GAME_QUIRKS_NAMES{"icache-matters",
"directly-reads-wiimote-input",
"uses-DVDLowStopLaser",
"uses-DVDLowOffset",
@@ -144,7 +144,9 @@ constexpr std::array<const char*, 12> GAME_QUIRKS_NAMES{"icache-matters",
"uses-different-partition-command",
"uses-di-interrupt-command",
"mismatched-gpu-texgens-between-xf-and-bp",
"mismatched-gpu-colors-between-xf-and-bp"};
"mismatched-gpu-colors-between-xf-and-bp",
"uses-uncommon-wd-mode",
"uses-wd-unimplemented-ioctl"};
static_assert(GAME_QUIRKS_NAMES.size() == static_cast<u32>(GameQuirk::COUNT),
"Game quirks names and enum definition are out of sync.");

@@ -54,6 +54,13 @@ enum class GameQuirk
MISMATCHED_GPU_TEXGENS_BETWEEN_XF_AND_BP,
MISMATCHED_GPU_COLORS_BETWEEN_XF_AND_BP,

// The WD module can be configured to operate in six different modes.
// In practice, only mode 1 (DS communications) and mode 3 (AOSS access point scanning)
// are used by games and the system menu respectively.
USES_UNCOMMON_WD_MODE,

USES_WD_UNIMPLEMENTED_IOCTL,

COUNT,
};

@@ -78,7 +78,8 @@ IOCtlVRequest::IOCtlVRequest(const u32 address_) : Request(address_)

const IOCtlVRequest::IOVector* IOCtlVRequest::GetVector(size_t index) const
{
ASSERT(index < (in_vectors.size() + io_vectors.size()));
if (index >= in_vectors.size() + io_vectors.size())
return nullptr;
if (index < in_vectors.size())
return &in_vectors[index];
return &io_vectors[index - in_vectors.size()];
@@ -154,7 +154,10 @@ struct IOCtlVRequest final : Request
// merging them into a single std::vector would make using the first out vector more complicated.
std::vector<IOVector> in_vectors;
std::vector<IOVector> io_vectors;

/// Returns the specified vector or nullptr if the index is out of bounds.
const IOVector* GetVector(size_t index) const;

explicit IOCtlVRequest(u32 address);
bool HasNumberOfValidVectors(size_t in_count, size_t io_count) const;
void Dump(std::string_view description, Common::Log::LOG_TYPE type = Common::Log::IOS,
@@ -20,6 +20,12 @@ NetNCDManage::NetNCDManage(Kernel& ios, const std::string& device_name) : Device
config.ReadConfig(ios.GetFS().get());
}

void NetNCDManage::DoState(PointerWrap& p)
{
Device::DoState(p);
p.Do(m_ipc_fd);
}

IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
{
s32 return_value = IPC_SUCCESS;
@@ -29,11 +35,51 @@ IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
switch (request.request)
{
case IOCTLV_NCD_LOCKWIRELESSDRIVER:
if (!request.HasNumberOfValidVectors(0, 1))
return GetDefaultReply(IPC_EINVAL);

if (request.io_vectors[0].size < 2 * sizeof(u32))
return GetDefaultReply(IPC_EINVAL);

if (m_ipc_fd != 0)
{
// It is an error to lock the driver again when it is already locked.
common_result = IPC_EINVAL;
}
else
{
// NCD writes the internal address of the request's file descriptor.
// We will just write the value of the file descriptor.
// The value will be positive so this will work fine.
m_ipc_fd = request.fd;
Memory::Write_U32(request.fd, request.io_vectors[0].address + 4);
}
break;

case IOCTLV_NCD_UNLOCKWIRELESSDRIVER:
// Memory::Read_U32(request.in_vectors.at(0).address);
{
if (!request.HasNumberOfValidVectors(1, 1))
return GetDefaultReply(IPC_EINVAL);

if (request.in_vectors[0].size < sizeof(u32))
return GetDefaultReply(IPC_EINVAL);

if (request.io_vectors[0].size < sizeof(u32))
return GetDefaultReply(IPC_EINVAL);

const u32 request_handle = Memory::Read_U32(request.in_vectors[0].address);
if (m_ipc_fd == request_handle)
{
m_ipc_fd = 0;
common_result = 0;
}
else
{
common_result = -3;
}

break;
}

case IOCTLV_NCD_GETCONFIG:
INFO_LOG_FMT(IOS_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETCONFIG");
@@ -20,6 +20,8 @@ class NetNCDManage : public Device

IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;

void DoState(PointerWrap& p) override;

private:
enum
{
@@ -34,5 +36,6 @@ class NetNCDManage : public Device
};

Net::WiiNetConfig config;
u32 m_ipc_fd = 0;
};
} // namespace IOS::HLE::Device

0 comments on commit 27013e8

Please sign in to comment.