/dev/nvhost-as-gpu

This commit is contained in:
David Marcec
2018-02-05 01:40:25 -08:00
parent 1fd1581201
commit 04b711a1b2
2 changed files with 142 additions and 1 deletions

View File

@@ -11,7 +11,81 @@ namespace Nvidia {
namespace Devices {
u32 nvhost_as_gpu::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) {
UNIMPLEMENTED();
LOG_DEBUG(Service_NVDRV, "Got Ioctl 0x%x, inputsz: 0x%x, outputsz: 0x%x", command, input.size(),
output.size());
switch (static_cast<IoctlCommand>(command)) {
case IoctlCommand::IocInitalizeExCommand:
return InitalizeEx(input, output);
case IoctlCommand::IocAllocateSpaceCommand:
return AllocateSpace(input, output);
case IoctlCommand::IocMapBufferExCommand:
return MapBufferEx(input, output);
case IoctlCommand::IocBindChannelCommand:
return BindChannel(input, output);
case IoctlCommand::IocGetVaRegionsCommand:
return GetVARegions(input, output);
}
return 0;
}
u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output) {
initalize_ex params{};
std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x%x", params.big_page_size);
std::memcpy(output.data(), &params, output.size());
return 0;
}
u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) {
alloc_space params{};
std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service_NVDRV, "(STUBBED) called, pages=%x, page_size=%x, flags=%x", params.pages,
params.page_size, params.flags);
params.offset = 0xdeadbeef; // TODO(ogniK): Actually allocate space and give a real offset
std::memcpy(output.data(), &params, output.size());
return 0;
}
u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
map_buffer_ex params{};
std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service_NVDRV,
"(STUBBED) called, flags=%x, nvmap_handle=%x, buffer_offset=%lx, mapping_size=%lx, "
"offset=%lx",
params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size,
params.offset);
params.offset = 0x0; // TODO(ogniK): Actually map and give a real offset
std::memcpy(output.data(), &params, output.size());
return 0;
}
u32 nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) {
bind_channel params{};
std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, fd=%x", params.fd);
channel = params.fd;
std::memcpy(output.data(), &params, output.size());
return 0;
}
u32 nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) {
get_va_regions params{};
std::memcpy(&params, input.data(), input.size());
LOG_WARNING(Service, "(STUBBED) called, buf_addr=%lx, buf_size=%x", params.buf_addr,
params.buf_size);
params.buf_size = 0x30;
params.regions[0].offset = 0x04000000;
params.regions[0].page_size = 0x1000;
params.regions[0].pages = 0x3fbfff;
params.regions[1].offset = 0x04000000;
params.regions[1].page_size = 0x10000;
params.regions[1].pages = 0x1bffff;
// TODO(ogniK): This probably can stay stubbed but should add support way way later
std::memcpy(output.data(), &params, output.size());
return 0;
}

View File

@@ -6,6 +6,7 @@
#include <vector>
#include "common/common_types.h"
#include "common/swap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
namespace Service {
@@ -18,6 +19,72 @@ public:
~nvhost_as_gpu() override = default;
u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override;
private:
enum class IoctlCommand : u32 {
IocInitalizeExCommand = 0x40284109,
IocAllocateSpaceCommand = 0xC0184102,
IocMapBufferExCommand = 0xC0284106,
IocBindChannelCommand = 0x40044101,
IocGetVaRegionsCommand = 0xC0404108,
};
struct initalize_ex {
u32_le big_page_size; // depends on GPU's available_big_page_sizes; 0=default
s32_le as_fd; // ignored; passes 0
u32_le flags; // passes 0
u32_le reserved; // ignored; passes 0
u64_le unk0;
u64_le unk1;
u64_le unk2;
};
struct alloc_space {
u32_le pages;
u32_le page_size;
u32_le flags;
u32_le pad;
union {
u64_le offset;
u64_le align;
};
};
struct map_buffer_ex {
u32_le flags; // bit0: fixed_offset, bit2: cacheable
u32_le kind; // -1 is default
u32_le nvmap_handle;
u32_le page_size; // 0 means don't care
u64_le buffer_offset;
u64_le mapping_size;
u64_le offset;
};
struct bind_channel {
u32_le fd;
};
struct va_region {
u64_le offset;
u32_le page_size;
u32_le pad;
u64_le pages;
};
struct get_va_regions {
u64_le buf_addr; // (contained output user ptr on linux, ignored)
u32_le buf_size; // forced to 2*sizeof(struct va_region)
u32_le reserved;
va_region regions[2];
};
u32 channel{};
u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output);
};
} // namespace Devices