mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-27 08:10:13 -06:00
180 lines
5.9 KiB
C++
180 lines
5.9 KiB
C++
// Copyright 2008 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "Common/ChunkFile.h"
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/Logging/Log.h"
|
|
#include "Core/IOS/IPC.h"
|
|
|
|
namespace IOS
|
|
{
|
|
namespace HLE
|
|
{
|
|
enum IOSReturnCode : s32
|
|
{
|
|
IPC_SUCCESS = 0, // Success
|
|
IPC_EACCES = -1, // Permission denied
|
|
IPC_EEXIST = -2, // File exists
|
|
IPC_EINVAL = -4, // Invalid argument or fd
|
|
IPC_ENOENT = -6, // File not found
|
|
IPC_EQUEUEFULL = -8, // Queue full
|
|
IPC_EIO = -12, // ECC error
|
|
IPC_ENOMEM = -22, // Alloc failed during request
|
|
FS_EINVAL = -101, // Invalid path
|
|
FS_EACCESS = -102, // Permission denied
|
|
FS_ECORRUPT = -103, // Corrupted NAND
|
|
FS_EEXIST = -105, // File exists
|
|
FS_ENOENT = -106, // No such file or directory
|
|
FS_ENFILE = -107, // Too many fds open
|
|
FS_EFBIG = -108, // Max block count reached?
|
|
FS_EFDEXHAUSTED = -109, // Too many fds open
|
|
FS_ENAMELEN = -110, // Pathname is too long
|
|
FS_EFDOPEN = -111, // FD is already open
|
|
FS_EIO = -114, // ECC error
|
|
FS_ENOTEMPTY = -115, // Directory not empty
|
|
FS_EDIRDEPTH = -116, // Max directory depth exceeded
|
|
FS_EBUSY = -118, // Resource busy
|
|
IPC_EESEXHAUSTED = -1016, // Max of 2 ES handles exceeded
|
|
};
|
|
|
|
struct IOSRequest
|
|
{
|
|
u32 address = 0;
|
|
IPCCommandType command = IPC_CMD_OPEN;
|
|
u32 fd = 0;
|
|
explicit IOSRequest(u32 address);
|
|
virtual ~IOSRequest() = default;
|
|
};
|
|
|
|
enum IOSOpenMode : s32
|
|
{
|
|
IOS_OPEN_READ = 1,
|
|
IOS_OPEN_WRITE = 2,
|
|
IOS_OPEN_RW = (IOS_OPEN_READ | IOS_OPEN_WRITE)
|
|
};
|
|
|
|
struct IOSOpenRequest final : IOSRequest
|
|
{
|
|
std::string path;
|
|
IOSOpenMode flags = IOS_OPEN_READ;
|
|
explicit IOSOpenRequest(u32 address);
|
|
};
|
|
|
|
struct IOSReadWriteRequest final : IOSRequest
|
|
{
|
|
u32 buffer = 0;
|
|
u32 size = 0;
|
|
explicit IOSReadWriteRequest(u32 address);
|
|
};
|
|
|
|
struct IOSSeekRequest final : IOSRequest
|
|
{
|
|
enum SeekMode
|
|
{
|
|
IOS_SEEK_SET = 0,
|
|
IOS_SEEK_CUR = 1,
|
|
IOS_SEEK_END = 2,
|
|
};
|
|
u32 offset = 0;
|
|
SeekMode mode = IOS_SEEK_SET;
|
|
explicit IOSSeekRequest(u32 address);
|
|
};
|
|
|
|
struct IOSIOCtlRequest final : IOSRequest
|
|
{
|
|
u32 request = 0;
|
|
u32 buffer_in = 0;
|
|
u32 buffer_in_size = 0;
|
|
// Contrary to the name, the output buffer can also be used for input.
|
|
u32 buffer_out = 0;
|
|
u32 buffer_out_size = 0;
|
|
explicit IOSIOCtlRequest(u32 address);
|
|
void Log(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE,
|
|
LogTypes::LOG_LEVELS level = LogTypes::LINFO) const;
|
|
void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE,
|
|
LogTypes::LOG_LEVELS level = LogTypes::LINFO) const;
|
|
void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE,
|
|
LogTypes::LOG_LEVELS level = LogTypes::LERROR) const;
|
|
};
|
|
|
|
struct IOSIOCtlVRequest final : IOSRequest
|
|
{
|
|
struct IOVector
|
|
{
|
|
u32 address = 0;
|
|
u32 size = 0;
|
|
};
|
|
u32 request = 0;
|
|
// In vectors are *mostly* used for input buffers. Sometimes they are also used as
|
|
// output buffers (notably in the network code).
|
|
// IO vectors are *mostly* used for output buffers. However, as indicated in the name,
|
|
// they're also used as input buffers.
|
|
// So both of them are technically IO vectors. But we're keeping them separated because
|
|
// 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;
|
|
explicit IOSIOCtlVRequest(u32 address);
|
|
bool HasInputVectorWithAddress(u32 vector_address) const;
|
|
void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE,
|
|
LogTypes::LOG_LEVELS level = LogTypes::LINFO) const;
|
|
void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::WII_IPC_HLE,
|
|
LogTypes::LOG_LEVELS level = LogTypes::LERROR) const;
|
|
};
|
|
|
|
namespace Device
|
|
{
|
|
class Device
|
|
{
|
|
public:
|
|
enum class DeviceType : u32
|
|
{
|
|
Static, // Devices which appear in s_device_map.
|
|
FileIO, // FileIO devices which are created dynamically.
|
|
};
|
|
|
|
Device(u32 device_id, const std::string& device_name, DeviceType type = DeviceType::Static);
|
|
|
|
virtual ~Device() = default;
|
|
// Release any resources which might interfere with savestating.
|
|
virtual void PrepareForState(PointerWrap::Mode mode) {}
|
|
virtual void DoState(PointerWrap& p);
|
|
void DoStateShared(PointerWrap& p);
|
|
|
|
const std::string& GetDeviceName() const { return m_name; }
|
|
u32 GetDeviceID() const { return m_device_id; }
|
|
// Replies to Open and Close requests are sent by the IPC request handler (HandleCommand),
|
|
// not by the devices themselves.
|
|
virtual IOSReturnCode Open(const IOSOpenRequest& request);
|
|
virtual void Close();
|
|
virtual IPCCommandResult Seek(const IOSSeekRequest& seek) { return Unsupported(seek); }
|
|
virtual IPCCommandResult Read(const IOSReadWriteRequest& read) { return Unsupported(read); }
|
|
virtual IPCCommandResult Write(const IOSReadWriteRequest& write) { return Unsupported(write); }
|
|
virtual IPCCommandResult IOCtl(const IOSIOCtlRequest& ioctl) { return Unsupported(ioctl); }
|
|
virtual IPCCommandResult IOCtlV(const IOSIOCtlVRequest& ioctlv) { return Unsupported(ioctlv); }
|
|
virtual void Update() {}
|
|
virtual DeviceType GetDeviceType() const { return m_device_type; }
|
|
virtual bool IsOpened() const { return m_is_active; }
|
|
static IPCCommandResult GetDefaultReply(s32 return_value);
|
|
static IPCCommandResult GetNoReply();
|
|
|
|
protected:
|
|
std::string m_name;
|
|
// STATE_TO_SAVE
|
|
u32 m_device_id;
|
|
DeviceType m_device_type;
|
|
bool m_is_active = false;
|
|
|
|
private:
|
|
IPCCommandResult Unsupported(const IOSRequest& request);
|
|
};
|
|
} // namespace Device
|
|
} // namespace HLE
|
|
} // namespace IOS
|