diff options
| author | 2018-01-09 10:41:13 -0500 | |
|---|---|---|
| committer | 2018-01-10 23:28:40 -0500 | |
| commit | 1ca800cceecd3f37ad874e12fd657f6145ae13c7 (patch) | |
| tree | d5c935b854585739970c9a7c2a6b9981e31fdeca /src | |
| parent | VI: Use a Pulse event instead of OneShot for the vblank events. (diff) | |
| download | yuzu-1ca800cceecd3f37ad874e12fd657f6145ae13c7.tar.gz yuzu-1ca800cceecd3f37ad874e12fd657f6145ae13c7.tar.xz yuzu-1ca800cceecd3f37ad874e12fd657f6145ae13c7.zip | |
NV: Move the nv device nodes to their own directory and namespace.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdevice.h | 33 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 29 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | 34 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 25 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 153 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.h | 108 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv_a.cpp | 169 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv_a.h | 15 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 3 |
11 files changed, 430 insertions, 166 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cc2b5b084..c836c0196 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -45,6 +45,9 @@ set(SRCS | |||
| 45 | hle/service/gsp_gpu.cpp | 45 | hle/service/gsp_gpu.cpp |
| 46 | hle/service/hid/hid.cpp | 46 | hle/service/hid/hid.cpp |
| 47 | hle/service/lm/lm.cpp | 47 | hle/service/lm/lm.cpp |
| 48 | hle/service/nvdrv/devices/nvdisp_disp0.cpp | ||
| 49 | hle/service/nvdrv/devices/nvhost_as_gpu.cpp | ||
| 50 | hle/service/nvdrv/devices/nvmap.cpp | ||
| 48 | hle/service/nvdrv/nvdrv.cpp | 51 | hle/service/nvdrv/nvdrv.cpp |
| 49 | hle/service/nvdrv/nvdrv_a.cpp | 52 | hle/service/nvdrv/nvdrv_a.cpp |
| 50 | hle/service/pctl/pctl.cpp | 53 | hle/service/pctl/pctl.cpp |
| @@ -132,6 +135,10 @@ set(HEADERS | |||
| 132 | hle/service/gsp_gpu.h | 135 | hle/service/gsp_gpu.h |
| 133 | hle/service/hid/hid.h | 136 | hle/service/hid/hid.h |
| 134 | hle/service/lm/lm.h | 137 | hle/service/lm/lm.h |
| 138 | hle/service/nvdrv/devices/nvdevice.h | ||
| 139 | hle/service/nvdrv/devices/nvdisp_disp0.h | ||
| 140 | hle/service/nvdrv/devices/nvhost_as_gpu.h | ||
| 141 | hle/service/nvdrv/devices/nvmap.h | ||
| 135 | hle/service/nvdrv/nvdrv.h | 142 | hle/service/nvdrv/nvdrv.h |
| 136 | hle/service/nvdrv/nvdrv_a.h | 143 | hle/service/nvdrv/nvdrv_a.h |
| 137 | hle/service/pctl/pctl.h | 144 | hle/service/pctl/pctl.h |
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h new file mode 100644 index 000000000..b4efce3a1 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <vector> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | |||
| 10 | namespace Service { | ||
| 11 | namespace NVDRV { | ||
| 12 | namespace Devices { | ||
| 13 | |||
| 14 | /// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to | ||
| 15 | /// implement the ioctl interface. | ||
| 16 | class nvdevice { | ||
| 17 | public: | ||
| 18 | nvdevice() = default; | ||
| 19 | virtual ~nvdevice() = default; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Handles an ioctl request. | ||
| 23 | * @param command The ioctl command id. | ||
| 24 | * @param input A buffer containing the input data for the ioctl. | ||
| 25 | * @param output A buffer where the output data will be written to. | ||
| 26 | * @returns The result code of the ioctl. | ||
| 27 | */ | ||
| 28 | virtual u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) = 0; | ||
| 29 | }; | ||
| 30 | |||
| 31 | } // namespace Devices | ||
| 32 | } // namespace NVDRV | ||
| 33 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp new file mode 100644 index 000000000..faed626ba --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | // Copyright 2018 Yuzu Emulator Team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 8 | #include "core/hle/service/nvdrv/devices/nvmap.h" | ||
| 9 | |||
| 10 | namespace Service { | ||
| 11 | namespace NVDRV { | ||
| 12 | namespace Devices { | ||
| 13 | |||
| 14 | u32 nvdisp_disp0::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 15 | ASSERT(false, "Unimplemented"); | ||
| 16 | return 0; | ||
| 17 | } | ||
| 18 | |||
| 19 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | ||
| 20 | u32 stride) { | ||
| 21 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | ||
| 22 | LOG_WARNING(Service, | ||
| 23 | "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", | ||
| 24 | addr, offset, width, height, stride, format); | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace Devices | ||
| 28 | } // namespace NVDRV | ||
| 29 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h new file mode 100644 index 000000000..54725917f --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <vector> | ||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 11 | |||
| 12 | namespace Service { | ||
| 13 | namespace NVDRV { | ||
| 14 | namespace Devices { | ||
| 15 | |||
| 16 | class nvmap; | ||
| 17 | |||
| 18 | class nvdisp_disp0 final : public nvdevice { | ||
| 19 | public: | ||
| 20 | nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) {} | ||
| 21 | ~nvdisp_disp0() = default; | ||
| 22 | |||
| 23 | u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||
| 24 | |||
| 25 | /// Performs a screen flip, drawing the buffer pointed to by the handle. | ||
| 26 | void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride); | ||
| 27 | |||
| 28 | private: | ||
| 29 | std::shared_ptr<nvmap> nvmap_dev; | ||
| 30 | }; | ||
| 31 | |||
| 32 | } // namespace Devices | ||
| 33 | } // namespace NVDRV | ||
| 34 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp new file mode 100644 index 000000000..50fee8f46 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright 2018 Yuzu Emulator Team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | ||
| 8 | |||
| 9 | namespace Service { | ||
| 10 | namespace NVDRV { | ||
| 11 | namespace Devices { | ||
| 12 | |||
| 13 | u32 nvhost_as_gpu::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 14 | ASSERT(false, "Unimplemented"); | ||
| 15 | return 0; | ||
| 16 | } | ||
| 17 | |||
| 18 | } // namespace Devices | ||
| 19 | } // namespace NVDRV | ||
| 20 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h new file mode 100644 index 000000000..411275922 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <vector> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 10 | |||
| 11 | namespace Service { | ||
| 12 | namespace NVDRV { | ||
| 13 | namespace Devices { | ||
| 14 | |||
| 15 | class nvhost_as_gpu final : public nvdevice { | ||
| 16 | public: | ||
| 17 | nvhost_as_gpu() = default; | ||
| 18 | ~nvhost_as_gpu() override = default; | ||
| 19 | |||
| 20 | u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||
| 21 | }; | ||
| 22 | |||
| 23 | } // namespace Devices | ||
| 24 | } // namespace NVDRV | ||
| 25 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp new file mode 100644 index 000000000..fdf2f7be5 --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | // Copyright 2018 Yuzu Emulator Team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/hle/service/nvdrv/devices/nvmap.h" | ||
| 8 | |||
| 9 | namespace Service { | ||
| 10 | namespace NVDRV { | ||
| 11 | namespace Devices { | ||
| 12 | |||
| 13 | VAddr nvmap::GetObjectAddress(u32 handle) const { | ||
| 14 | auto itr = handles.find(handle); | ||
| 15 | ASSERT(itr != handles.end()); | ||
| 16 | |||
| 17 | auto object = itr->second; | ||
| 18 | ASSERT(object->status == Object::Status::Allocated); | ||
| 19 | return object->addr; | ||
| 20 | } | ||
| 21 | |||
| 22 | u32 nvmap::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 23 | switch (command) { | ||
| 24 | case IocCreateCommand: | ||
| 25 | return IocCreate(input, output); | ||
| 26 | case IocAllocCommand: | ||
| 27 | return IocAlloc(input, output); | ||
| 28 | case IocGetIdCommand: | ||
| 29 | return IocGetId(input, output); | ||
| 30 | case IocFromIdCommand: | ||
| 31 | return IocFromId(input, output); | ||
| 32 | case IocParamCommand: | ||
| 33 | return IocParam(input, output); | ||
| 34 | } | ||
| 35 | |||
| 36 | ASSERT(false, "Unimplemented"); | ||
| 37 | } | ||
| 38 | |||
| 39 | u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 40 | IocCreateParams params; | ||
| 41 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 42 | |||
| 43 | // Create a new nvmap object and obtain a handle to it. | ||
| 44 | auto object = std::make_shared<Object>(); | ||
| 45 | object->id = next_id++; | ||
| 46 | object->size = params.size; | ||
| 47 | object->status = Object::Status::Created; | ||
| 48 | |||
| 49 | u32 handle = next_handle++; | ||
| 50 | handles[handle] = std::move(object); | ||
| 51 | |||
| 52 | LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size); | ||
| 53 | |||
| 54 | params.handle = handle; | ||
| 55 | |||
| 56 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 61 | IocAllocParams params; | ||
| 62 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 63 | |||
| 64 | auto itr = handles.find(params.handle); | ||
| 65 | ASSERT(itr != handles.end()); | ||
| 66 | |||
| 67 | auto object = itr->second; | ||
| 68 | object->flags = params.flags; | ||
| 69 | object->align = params.align; | ||
| 70 | object->kind = params.kind; | ||
| 71 | object->addr = params.addr; | ||
| 72 | object->status = Object::Status::Allocated; | ||
| 73 | |||
| 74 | LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr); | ||
| 75 | |||
| 76 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 77 | return 0; | ||
| 78 | } | ||
| 79 | |||
| 80 | u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 81 | IocGetIdParams params; | ||
| 82 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 83 | |||
| 84 | LOG_WARNING(Service, "called"); | ||
| 85 | |||
| 86 | auto itr = handles.find(params.handle); | ||
| 87 | ASSERT(itr != handles.end()); | ||
| 88 | |||
| 89 | params.id = itr->second->id; | ||
| 90 | |||
| 91 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 96 | IocFromIdParams params; | ||
| 97 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 98 | |||
| 99 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 100 | |||
| 101 | auto itr = std::find_if(handles.begin(), handles.end(), | ||
| 102 | [&](const auto& entry) { return entry.second->id == params.id; }); | ||
| 103 | ASSERT(itr != handles.end()); | ||
| 104 | |||
| 105 | // Make a new handle for the object | ||
| 106 | u32 handle = next_handle++; | ||
| 107 | handles[handle] = itr->second; | ||
| 108 | |||
| 109 | params.handle = handle; | ||
| 110 | |||
| 111 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 116 | enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; | ||
| 117 | |||
| 118 | IocParamParams params; | ||
| 119 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 120 | |||
| 121 | LOG_WARNING(Service, "(STUBBED) called type=%u", params.type); | ||
| 122 | |||
| 123 | auto itr = handles.find(params.handle); | ||
| 124 | ASSERT(itr != handles.end()); | ||
| 125 | |||
| 126 | auto object = itr->second; | ||
| 127 | ASSERT(object->status == Object::Status::Allocated); | ||
| 128 | |||
| 129 | switch (static_cast<ParamTypes>(params.type)) { | ||
| 130 | case ParamTypes::Size: | ||
| 131 | params.value = object->size; | ||
| 132 | break; | ||
| 133 | case ParamTypes::Alignment: | ||
| 134 | params.value = object->align; | ||
| 135 | break; | ||
| 136 | case ParamTypes::Heap: | ||
| 137 | // TODO(Subv): Seems to be a hardcoded value? | ||
| 138 | params.value = 0x40000000; | ||
| 139 | break; | ||
| 140 | case ParamTypes::Kind: | ||
| 141 | params.value = object->kind; | ||
| 142 | break; | ||
| 143 | default: | ||
| 144 | ASSERT(false, "Unimplemented"); | ||
| 145 | } | ||
| 146 | |||
| 147 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | } // namespace Devices | ||
| 152 | } // namespace NVDRV | ||
| 153 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h new file mode 100644 index 000000000..e8b08f3fb --- /dev/null +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <unordered_map> | ||
| 9 | #include <vector> | ||
| 10 | #include "common/common_funcs.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "common/swap.h" | ||
| 13 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 14 | |||
| 15 | namespace Service { | ||
| 16 | namespace NVDRV { | ||
| 17 | namespace Devices { | ||
| 18 | |||
| 19 | class nvmap final : public nvdevice { | ||
| 20 | public: | ||
| 21 | nvmap() = default; | ||
| 22 | ~nvmap() override = default; | ||
| 23 | |||
| 24 | /// Returns the allocated address of an nvmap object given its handle. | ||
| 25 | VAddr GetObjectAddress(u32 handle) const; | ||
| 26 | |||
| 27 | u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||
| 28 | |||
| 29 | private: | ||
| 30 | // Represents an nvmap object. | ||
| 31 | struct Object { | ||
| 32 | enum class Status { Created, Allocated }; | ||
| 33 | u32 id; | ||
| 34 | u32 size; | ||
| 35 | u32 flags; | ||
| 36 | u32 align; | ||
| 37 | u8 kind; | ||
| 38 | VAddr addr; | ||
| 39 | Status status; | ||
| 40 | }; | ||
| 41 | |||
| 42 | /// Id to use for the next handle that is created. | ||
| 43 | u32 next_handle = 1; | ||
| 44 | |||
| 45 | // Id to use for the next object that is created. | ||
| 46 | u32 next_id = 1; | ||
| 47 | |||
| 48 | /// Mapping of currently allocated handles to the objects they represent. | ||
| 49 | std::unordered_map<u32, std::shared_ptr<Object>> handles; | ||
| 50 | |||
| 51 | enum IoctlCommands { | ||
| 52 | IocCreateCommand = 0xC0080101, | ||
| 53 | IocFromIdCommand = 0xC0080103, | ||
| 54 | IocAllocCommand = 0xC0200104, | ||
| 55 | IocParamCommand = 0xC00C0109, | ||
| 56 | IocGetIdCommand = 0xC008010E | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct IocCreateParams { | ||
| 60 | // Input | ||
| 61 | u32_le size; | ||
| 62 | // Output | ||
| 63 | u32_le handle; | ||
| 64 | }; | ||
| 65 | |||
| 66 | struct IocAllocParams { | ||
| 67 | // Input | ||
| 68 | u32_le handle; | ||
| 69 | u32_le heap_mask; | ||
| 70 | u32_le flags; | ||
| 71 | u32_le align; | ||
| 72 | u8 kind; | ||
| 73 | INSERT_PADDING_BYTES(7); | ||
| 74 | u64_le addr; | ||
| 75 | }; | ||
| 76 | |||
| 77 | struct IocGetIdParams { | ||
| 78 | // Output | ||
| 79 | u32_le id; | ||
| 80 | // Input | ||
| 81 | u32_le handle; | ||
| 82 | }; | ||
| 83 | |||
| 84 | struct IocFromIdParams { | ||
| 85 | // Input | ||
| 86 | u32_le id; | ||
| 87 | // Output | ||
| 88 | u32_le handle; | ||
| 89 | }; | ||
| 90 | |||
| 91 | struct IocParamParams { | ||
| 92 | // Input | ||
| 93 | u32_le handle; | ||
| 94 | u32_le type; | ||
| 95 | // Output | ||
| 96 | u32_le value; | ||
| 97 | }; | ||
| 98 | |||
| 99 | u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 100 | u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 101 | u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 102 | u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 103 | u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 104 | }; | ||
| 105 | |||
| 106 | } // namespace Devices | ||
| 107 | } // namespace NVDRV | ||
| 108 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/nvdrv_a.cpp b/src/core/hle/service/nvdrv/nvdrv_a.cpp index cede4a883..cfecea924 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_a.cpp | |||
| @@ -4,171 +4,16 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||
| 8 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | ||
| 10 | #include "core/hle/service/nvdrv/devices/nvmap.h" | ||
| 7 | #include "core/hle/service/nvdrv/nvdrv.h" | 11 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 8 | #include "core/hle/service/nvdrv/nvdrv_a.h" | 12 | #include "core/hle/service/nvdrv/nvdrv_a.h" |
| 9 | 13 | ||
| 10 | namespace Service { | 14 | namespace Service { |
| 11 | namespace NVDRV { | 15 | namespace NVDRV { |
| 12 | 16 | ||
| 13 | class nvhost_as_gpu : public nvdevice { | ||
| 14 | public: | ||
| 15 | u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override { | ||
| 16 | ASSERT(false, "Unimplemented"); | ||
| 17 | return 0; | ||
| 18 | } | ||
| 19 | }; | ||
| 20 | |||
| 21 | VAddr nvmap::GetObjectAddress(u32 handle) const { | ||
| 22 | auto itr = handles.find(handle); | ||
| 23 | ASSERT(itr != handles.end()); | ||
| 24 | |||
| 25 | auto object = itr->second; | ||
| 26 | ASSERT(object->status == Object::Status::Allocated); | ||
| 27 | return object->addr; | ||
| 28 | } | ||
| 29 | |||
| 30 | u32 nvmap::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 31 | switch (command) { | ||
| 32 | case IocCreateCommand: | ||
| 33 | return IocCreate(input, output); | ||
| 34 | case IocAllocCommand: | ||
| 35 | return IocAlloc(input, output); | ||
| 36 | case IocGetIdCommand: | ||
| 37 | return IocGetId(input, output); | ||
| 38 | case IocFromIdCommand: | ||
| 39 | return IocFromId(input, output); | ||
| 40 | case IocParamCommand: | ||
| 41 | return IocParam(input, output); | ||
| 42 | } | ||
| 43 | |||
| 44 | ASSERT(false, "Unimplemented"); | ||
| 45 | } | ||
| 46 | |||
| 47 | u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 48 | IocCreateParams params; | ||
| 49 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 50 | |||
| 51 | // Create a new nvmap object and obtain a handle to it. | ||
| 52 | auto object = std::make_shared<Object>(); | ||
| 53 | object->id = next_id++; | ||
| 54 | object->size = params.size; | ||
| 55 | object->status = Object::Status::Created; | ||
| 56 | |||
| 57 | u32 handle = next_handle++; | ||
| 58 | handles[handle] = std::move(object); | ||
| 59 | |||
| 60 | LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size); | ||
| 61 | |||
| 62 | params.handle = handle; | ||
| 63 | |||
| 64 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 69 | IocAllocParams params; | ||
| 70 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 71 | |||
| 72 | auto itr = handles.find(params.handle); | ||
| 73 | ASSERT(itr != handles.end()); | ||
| 74 | |||
| 75 | auto object = itr->second; | ||
| 76 | object->flags = params.flags; | ||
| 77 | object->align = params.align; | ||
| 78 | object->kind = params.kind; | ||
| 79 | object->addr = params.addr; | ||
| 80 | object->status = Object::Status::Allocated; | ||
| 81 | |||
| 82 | LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr); | ||
| 83 | |||
| 84 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 89 | IocGetIdParams params; | ||
| 90 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 91 | |||
| 92 | LOG_WARNING(Service, "called"); | ||
| 93 | |||
| 94 | auto itr = handles.find(params.handle); | ||
| 95 | ASSERT(itr != handles.end()); | ||
| 96 | |||
| 97 | params.id = itr->second->id; | ||
| 98 | |||
| 99 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 104 | IocFromIdParams params; | ||
| 105 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 106 | |||
| 107 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 108 | |||
| 109 | auto itr = std::find_if(handles.begin(), handles.end(), | ||
| 110 | [&](const auto& entry) { return entry.second->id == params.id; }); | ||
| 111 | ASSERT(itr != handles.end()); | ||
| 112 | |||
| 113 | // Make a new handle for the object | ||
| 114 | u32 handle = next_handle++; | ||
| 115 | handles[handle] = itr->second; | ||
| 116 | |||
| 117 | params.handle = handle; | ||
| 118 | |||
| 119 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 124 | enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; | ||
| 125 | |||
| 126 | IocParamParams params; | ||
| 127 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 128 | |||
| 129 | LOG_WARNING(Service, "(STUBBED) called type=%u", params.type); | ||
| 130 | |||
| 131 | auto itr = handles.find(params.handle); | ||
| 132 | ASSERT(itr != handles.end()); | ||
| 133 | |||
| 134 | auto object = itr->second; | ||
| 135 | ASSERT(object->status == Object::Status::Allocated); | ||
| 136 | |||
| 137 | switch (static_cast<ParamTypes>(params.type)) { | ||
| 138 | case ParamTypes::Size: | ||
| 139 | params.value = object->size; | ||
| 140 | break; | ||
| 141 | case ParamTypes::Alignment: | ||
| 142 | params.value = object->align; | ||
| 143 | break; | ||
| 144 | case ParamTypes::Heap: | ||
| 145 | // TODO(Subv): Seems to be a hardcoded value? | ||
| 146 | params.value = 0x40000000; | ||
| 147 | break; | ||
| 148 | case ParamTypes::Kind: | ||
| 149 | params.value = object->kind; | ||
| 150 | break; | ||
| 151 | default: | ||
| 152 | ASSERT(false, "Unimplemented"); | ||
| 153 | } | ||
| 154 | |||
| 155 | std::memcpy(output.data(), ¶ms, sizeof(params)); | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | u32 nvdisp_disp0::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 160 | ASSERT(false, "Unimplemented"); | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | ||
| 165 | u32 stride) { | ||
| 166 | VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | ||
| 167 | LOG_WARNING(Service, | ||
| 168 | "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", | ||
| 169 | addr, offset, width, height, stride, format); | ||
| 170 | } | ||
| 171 | |||
| 172 | void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { | 17 | void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { |
| 173 | LOG_WARNING(Service, "(STUBBED) called"); | 18 | LOG_WARNING(Service, "(STUBBED) called"); |
| 174 | 19 | ||
| @@ -229,10 +74,10 @@ NVDRV_A::NVDRV_A() : ServiceFramework("nvdrv:a") { | |||
| 229 | }; | 74 | }; |
| 230 | RegisterHandlers(functions); | 75 | RegisterHandlers(functions); |
| 231 | 76 | ||
| 232 | auto nvmap_dev = std::make_shared<nvmap>(); | 77 | auto nvmap_dev = std::make_shared<Devices::nvmap>(); |
| 233 | devices["/dev/nvhost-as-gpu"] = std::make_shared<nvhost_as_gpu>(); | 78 | devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(); |
| 234 | devices["/dev/nvmap"] = nvmap_dev; | 79 | devices["/dev/nvmap"] = nvmap_dev; |
| 235 | devices["/dev/nvdisp_disp0"] = std::make_shared<nvdisp_disp0>(nvmap_dev); | 80 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); |
| 236 | } | 81 | } |
| 237 | 82 | ||
| 238 | } // namespace NVDRV | 83 | } // namespace NVDRV |
diff --git a/src/core/hle/service/nvdrv/nvdrv_a.h b/src/core/hle/service/nvdrv/nvdrv_a.h index af1017881..4cd04adea 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.h +++ b/src/core/hle/service/nvdrv/nvdrv_a.h | |||
| @@ -5,12 +5,17 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include "core/hle/service/service.h" | 8 | #include <string> |
| 9 | #include "core/hle/service/nvdrv/nvdrv.h" | 9 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 10 | #include "core/hle/service/service.h" | ||
| 10 | 11 | ||
| 11 | namespace Service { | 12 | namespace Service { |
| 12 | namespace NVDRV { | 13 | namespace NVDRV { |
| 13 | 14 | ||
| 15 | namespace Devices { | ||
| 16 | class nvdevice; | ||
| 17 | } | ||
| 18 | |||
| 14 | class NVDRV_A final : public ServiceFramework<NVDRV_A> { | 19 | class NVDRV_A final : public ServiceFramework<NVDRV_A> { |
| 15 | public: | 20 | public: |
| 16 | NVDRV_A(); | 21 | NVDRV_A(); |
| @@ -30,10 +35,14 @@ private: | |||
| 30 | void Ioctl(Kernel::HLERequestContext& ctx); | 35 | void Ioctl(Kernel::HLERequestContext& ctx); |
| 31 | void Initialize(Kernel::HLERequestContext& ctx); | 36 | void Initialize(Kernel::HLERequestContext& ctx); |
| 32 | 37 | ||
| 38 | /// Id to use for the next open file descriptor. | ||
| 33 | u32 next_fd = 1; | 39 | u32 next_fd = 1; |
| 34 | 40 | ||
| 35 | std::unordered_map<u32, std::shared_ptr<nvdevice>> open_files; | 41 | /// Mapping of file descriptors to the devices they reference. |
| 36 | std::unordered_map<std::string, std::shared_ptr<nvdevice>> devices; | 42 | std::unordered_map<u32, std::shared_ptr<Devices::nvdevice>> open_files; |
| 43 | |||
| 44 | /// Mapping of device node names to their implementation. | ||
| 45 | std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; | ||
| 37 | }; | 46 | }; |
| 38 | 47 | ||
| 39 | extern std::weak_ptr<NVDRV_A> nvdrv_a; | 48 | extern std::weak_ptr<NVDRV_A> nvdrv_a; |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 55bbd45db..0b089702c 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include "common/scope_exit.h" | 6 | #include "common/scope_exit.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||
| 9 | #include "core/hle/service/nvdrv/nvdrv_a.h" | 10 | #include "core/hle/service/nvdrv/nvdrv_a.h" |
| 10 | #include "core/hle/service/vi/vi.h" | 11 | #include "core/hle/service/vi/vi.h" |
| 11 | #include "core/hle/service/vi/vi_m.h" | 12 | #include "core/hle/service/vi/vi_m.h" |
| @@ -752,7 +753,7 @@ void NVFlinger::Compose() { | |||
| 752 | 753 | ||
| 753 | // TODO(Subv): Support more than just disp0. The display device selection is probably based | 754 | // TODO(Subv): Support more than just disp0. The display device selection is probably based |
| 754 | // on which display we're drawing (Default, Internal, External, etc) | 755 | // on which display we're drawing (Default, Internal, External, etc) |
| 755 | auto nvdisp = nvdrv->GetDevice<NVDRV::nvdisp_disp0>("/dev/nvdisp_disp0"); | 756 | auto nvdisp = nvdrv->GetDevice<NVDRV::Devices::nvdisp_disp0>("/dev/nvdisp_disp0"); |
| 756 | ASSERT(nvdisp); | 757 | ASSERT(nvdisp); |
| 757 | 758 | ||
| 758 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, | 759 | nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, |