diff options
| author | 2018-02-07 22:10:42 -0800 | |
|---|---|---|
| committer | 2018-02-07 22:10:42 -0800 | |
| commit | db11c9a0b927a8f1d09f4cdf6bbe524485cb61b4 (patch) | |
| tree | a9a7ab29e0c2e89bf2ec9874df074eb9db792dcc /src | |
| parent | Merge pull request #168 from mailwl/new-stubs (diff) | |
| parent | nvhost_as_gpu: Implement AllocateSpace and MapBufferEx. (diff) | |
| download | yuzu-db11c9a0b927a8f1d09f4cdf6bbe524485cb61b4.tar.gz yuzu-db11c9a0b927a8f1d09f4cdf6bbe524485cb61b4.tar.xz yuzu-db11c9a0b927a8f1d09f4cdf6bbe524485cb61b4.zip | |
Merge pull request #169 from bunnei/gpu-mem
nvdrv: Implement AllocateSpace and MapBufferEx
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 38 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 12 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 27 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.h | 14 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/memory_manager.cpp | 112 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/memory_manager.h | 48 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv.cpp | 2 |
8 files changed, 225 insertions, 30 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 02c178441..eab08207d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -137,6 +137,8 @@ add_library(core STATIC | |||
| 137 | hle/service/nvdrv/devices/nvmap.h | 137 | hle/service/nvdrv/devices/nvmap.h |
| 138 | hle/service/nvdrv/interface.cpp | 138 | hle/service/nvdrv/interface.cpp |
| 139 | hle/service/nvdrv/interface.h | 139 | hle/service/nvdrv/interface.h |
| 140 | hle/service/nvdrv/memory_manager.cpp | ||
| 141 | hle/service/nvdrv/memory_manager.h | ||
| 140 | hle/service/nvdrv/nvdrv.cpp | 142 | hle/service/nvdrv/nvdrv.cpp |
| 141 | hle/service/nvdrv/nvdrv.h | 143 | hle/service/nvdrv/nvdrv.h |
| 142 | hle/service/nvdrv/nvmemp.cpp | 144 | hle/service/nvdrv/nvmemp.cpp |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 11ab25545..cf3601f02 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 7 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| 8 | #include "core/hle/service/nvdrv/devices/nvmap.h" | ||
| 8 | 9 | ||
| 9 | namespace Service { | 10 | namespace Service { |
| 10 | namespace Nvidia { | 11 | namespace Nvidia { |
| @@ -40,9 +41,16 @@ u32 nvhost_as_gpu::InitalizeEx(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 40 | u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { | 41 | u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output) { |
| 41 | IoctlAllocSpace params{}; | 42 | IoctlAllocSpace params{}; |
| 42 | std::memcpy(¶ms, input.data(), input.size()); | 43 | std::memcpy(¶ms, input.data(), input.size()); |
| 43 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, pages=%x, page_size=%x, flags=%x", params.pages, | 44 | LOG_DEBUG(Service_NVDRV, "called, pages=%x, page_size=%x, flags=%x", params.pages, |
| 44 | params.page_size, params.flags); | 45 | params.page_size, params.flags); |
| 45 | params.offset = 0xdeadbeef; // TODO(ogniK): Actually allocate space and give a real offset | 46 | |
| 47 | const u64 size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)}; | ||
| 48 | if (params.flags & 1) { | ||
| 49 | params.offset = memory_manager->AllocateSpace(params.offset, size, 1); | ||
| 50 | } else { | ||
| 51 | params.offset = memory_manager->AllocateSpace(size, params.align); | ||
| 52 | } | ||
| 53 | |||
| 46 | std::memcpy(output.data(), ¶ms, output.size()); | 54 | std::memcpy(output.data(), ¶ms, output.size()); |
| 47 | return 0; | 55 | return 0; |
| 48 | } | 56 | } |
| @@ -51,12 +59,24 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 51 | IoctlMapBufferEx params{}; | 59 | IoctlMapBufferEx params{}; |
| 52 | std::memcpy(¶ms, input.data(), input.size()); | 60 | std::memcpy(¶ms, input.data(), input.size()); |
| 53 | 61 | ||
| 54 | LOG_WARNING(Service_NVDRV, | 62 | LOG_DEBUG(Service_NVDRV, |
| 55 | "(STUBBED) called, flags=%x, nvmap_handle=%x, buffer_offset=%lx, mapping_size=%lx, " | 63 | "called, flags=%x, nvmap_handle=%x, buffer_offset=%lx, mapping_size=%lx, offset=%lx", |
| 56 | "offset=%lx", | 64 | params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, |
| 57 | params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size, | 65 | params.offset); |
| 58 | params.offset); | 66 | |
| 59 | params.offset = 0x0; // TODO(ogniK): Actually map and give a real offset | 67 | if (!params.nvmap_handle) { |
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | auto object = nvmap_dev->GetObject(params.nvmap_handle); | ||
| 72 | ASSERT(object); | ||
| 73 | |||
| 74 | if (params.flags & 1) { | ||
| 75 | params.offset = memory_manager->MapBufferEx(object->addr, params.offset, object->size); | ||
| 76 | } else { | ||
| 77 | params.offset = memory_manager->MapBufferEx(object->addr, object->size); | ||
| 78 | } | ||
| 79 | |||
| 60 | std::memcpy(output.data(), ¶ms, output.size()); | 80 | std::memcpy(output.data(), ¶ms, output.size()); |
| 61 | return 0; | 81 | return 0; |
| 62 | } | 82 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 06c256d5d..9d37b971a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -4,18 +4,25 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | ||
| 8 | #include <utility> | ||
| 7 | #include <vector> | 9 | #include <vector> |
| 8 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 13 | #include "core/hle/service/nvdrv/memory_manager.h" | ||
| 11 | 14 | ||
| 12 | namespace Service { | 15 | namespace Service { |
| 13 | namespace Nvidia { | 16 | namespace Nvidia { |
| 14 | namespace Devices { | 17 | namespace Devices { |
| 15 | 18 | ||
| 19 | class nvmap; | ||
| 20 | |||
| 16 | class nvhost_as_gpu final : public nvdevice { | 21 | class nvhost_as_gpu final : public nvdevice { |
| 17 | public: | 22 | public: |
| 18 | nvhost_as_gpu() = default; | 23 | nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) { |
| 24 | memory_manager = std::make_shared<MemoryManager>(); | ||
| 25 | } | ||
| 19 | ~nvhost_as_gpu() override = default; | 26 | ~nvhost_as_gpu() override = default; |
| 20 | 27 | ||
| 21 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 28 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| @@ -92,6 +99,9 @@ private: | |||
| 92 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | 99 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); |
| 93 | u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); | 100 | u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); |
| 94 | u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); | 101 | u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); |
| 102 | |||
| 103 | std::shared_ptr<nvmap> nvmap_dev; | ||
| 104 | std::shared_ptr<MemoryManager> memory_manager; | ||
| 95 | }; | 105 | }; |
| 96 | 106 | ||
| 97 | } // namespace Devices | 107 | } // namespace Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index cb3692689..02b33374a 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -13,10 +13,8 @@ namespace Nvidia { | |||
| 13 | namespace Devices { | 13 | namespace Devices { |
| 14 | 14 | ||
| 15 | VAddr nvmap::GetObjectAddress(u32 handle) const { | 15 | VAddr nvmap::GetObjectAddress(u32 handle) const { |
| 16 | auto itr = handles.find(handle); | 16 | auto object = GetObject(handle); |
| 17 | ASSERT(itr != handles.end()); | 17 | ASSERT(object); |
| 18 | |||
| 19 | auto object = itr->second; | ||
| 20 | ASSERT(object->status == Object::Status::Allocated); | 18 | ASSERT(object->status == Object::Status::Allocated); |
| 21 | return object->addr; | 19 | return object->addr; |
| 22 | } | 20 | } |
| @@ -52,7 +50,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 52 | u32 handle = next_handle++; | 50 | u32 handle = next_handle++; |
| 53 | handles[handle] = std::move(object); | 51 | handles[handle] = std::move(object); |
| 54 | 52 | ||
| 55 | LOG_WARNING(Service_NVDRV, "(STUBBED) size 0x%08X", params.size); | 53 | LOG_DEBUG(Service_NVDRV, "size=0x%08X", params.size); |
| 56 | 54 | ||
| 57 | params.handle = handle; | 55 | params.handle = handle; |
| 58 | 56 | ||
| @@ -64,17 +62,16 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 64 | IocAllocParams params; | 62 | IocAllocParams params; |
| 65 | std::memcpy(¶ms, input.data(), sizeof(params)); | 63 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| 66 | 64 | ||
| 67 | auto itr = handles.find(params.handle); | 65 | auto object = GetObject(params.handle); |
| 68 | ASSERT(itr != handles.end()); | 66 | ASSERT(object); |
| 69 | 67 | ||
| 70 | auto object = itr->second; | ||
| 71 | object->flags = params.flags; | 68 | object->flags = params.flags; |
| 72 | object->align = params.align; | 69 | object->align = params.align; |
| 73 | object->kind = params.kind; | 70 | object->kind = params.kind; |
| 74 | object->addr = params.addr; | 71 | object->addr = params.addr; |
| 75 | object->status = Object::Status::Allocated; | 72 | object->status = Object::Status::Allocated; |
| 76 | 73 | ||
| 77 | LOG_WARNING(Service_NVDRV, "(STUBBED) Allocated address 0x%llx", params.addr); | 74 | LOG_DEBUG(Service_NVDRV, "called, addr=0x%llx", params.addr); |
| 78 | 75 | ||
| 79 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 76 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 80 | return 0; | 77 | return 0; |
| @@ -86,10 +83,10 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 86 | 83 | ||
| 87 | LOG_WARNING(Service_NVDRV, "called"); | 84 | LOG_WARNING(Service_NVDRV, "called"); |
| 88 | 85 | ||
| 89 | auto itr = handles.find(params.handle); | 86 | auto object = GetObject(params.handle); |
| 90 | ASSERT(itr != handles.end()); | 87 | ASSERT(object); |
| 91 | 88 | ||
| 92 | params.id = itr->second->id; | 89 | params.id = object->id; |
| 93 | 90 | ||
| 94 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 91 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 95 | return 0; | 92 | return 0; |
| @@ -123,10 +120,8 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | |||
| 123 | 120 | ||
| 124 | LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type); | 121 | LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type); |
| 125 | 122 | ||
| 126 | auto itr = handles.find(params.handle); | 123 | auto object = GetObject(params.handle); |
| 127 | ASSERT(itr != handles.end()); | 124 | ASSERT(object); |
| 128 | |||
| 129 | auto object = itr->second; | ||
| 130 | ASSERT(object->status == Object::Status::Allocated); | 125 | ASSERT(object->status == Object::Status::Allocated); |
| 131 | 126 | ||
| 132 | switch (static_cast<ParamTypes>(params.type)) { | 127 | switch (static_cast<ParamTypes>(params.type)) { |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index 1591ac8ff..4681e438b 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h | |||
| @@ -26,8 +26,7 @@ public: | |||
| 26 | 26 | ||
| 27 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; | 27 | u32 ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override; |
| 28 | 28 | ||
| 29 | private: | 29 | /// Represents an nvmap object. |
| 30 | // Represents an nvmap object. | ||
| 31 | struct Object { | 30 | struct Object { |
| 32 | enum class Status { Created, Allocated }; | 31 | enum class Status { Created, Allocated }; |
| 33 | u32 id; | 32 | u32 id; |
| @@ -39,10 +38,19 @@ private: | |||
| 39 | Status status; | 38 | Status status; |
| 40 | }; | 39 | }; |
| 41 | 40 | ||
| 41 | std::shared_ptr<Object> GetObject(u32 handle) const { | ||
| 42 | auto itr = handles.find(handle); | ||
| 43 | if (itr != handles.end()) { | ||
| 44 | return itr->second; | ||
| 45 | } | ||
| 46 | return {}; | ||
| 47 | } | ||
| 48 | |||
| 49 | private: | ||
| 42 | /// Id to use for the next handle that is created. | 50 | /// Id to use for the next handle that is created. |
| 43 | u32 next_handle = 1; | 51 | u32 next_handle = 1; |
| 44 | 52 | ||
| 45 | // Id to use for the next object that is created. | 53 | /// Id to use for the next object that is created. |
| 46 | u32 next_id = 1; | 54 | u32 next_id = 1; |
| 47 | 55 | ||
| 48 | /// Mapping of currently allocated handles to the objects they represent. | 56 | /// Mapping of currently allocated handles to the objects they represent. |
diff --git a/src/core/hle/service/nvdrv/memory_manager.cpp b/src/core/hle/service/nvdrv/memory_manager.cpp new file mode 100644 index 000000000..55a8675d5 --- /dev/null +++ b/src/core/hle/service/nvdrv/memory_manager.cpp | |||
| @@ -0,0 +1,112 @@ | |||
| 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 "core/hle/service/nvdrv/memory_manager.h" | ||
| 7 | |||
| 8 | namespace Service { | ||
| 9 | namespace Nvidia { | ||
| 10 | |||
| 11 | PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { | ||
| 12 | boost::optional<PAddr> paddr = FindFreeBlock(size, align); | ||
| 13 | ASSERT(paddr); | ||
| 14 | |||
| 15 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 16 | PageSlot(*paddr + offset) = static_cast<u64>(PageStatus::Allocated); | ||
| 17 | } | ||
| 18 | |||
| 19 | return *paddr; | ||
| 20 | } | ||
| 21 | |||
| 22 | PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { | ||
| 23 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 24 | if (IsPageMapped(paddr + offset)) { | ||
| 25 | return AllocateSpace(size, align); | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 30 | PageSlot(paddr + offset) = static_cast<u64>(PageStatus::Allocated); | ||
| 31 | } | ||
| 32 | |||
| 33 | return paddr; | ||
| 34 | } | ||
| 35 | |||
| 36 | PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { | ||
| 37 | vaddr &= ~Memory::PAGE_MASK; | ||
| 38 | |||
| 39 | boost::optional<PAddr> paddr = FindFreeBlock(size); | ||
| 40 | ASSERT(paddr); | ||
| 41 | |||
| 42 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 43 | PageSlot(*paddr + offset) = vaddr + offset; | ||
| 44 | } | ||
| 45 | |||
| 46 | return *paddr; | ||
| 47 | } | ||
| 48 | |||
| 49 | PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { | ||
| 50 | vaddr &= ~Memory::PAGE_MASK; | ||
| 51 | paddr &= ~Memory::PAGE_MASK; | ||
| 52 | |||
| 53 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 54 | if (PageSlot(paddr + offset) != static_cast<u64>(PageStatus::Allocated)) { | ||
| 55 | return MapBufferEx(vaddr, size); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | for (u64 offset = 0; offset < size; offset += Memory::PAGE_SIZE) { | ||
| 60 | PageSlot(paddr + offset) = vaddr + offset; | ||
| 61 | } | ||
| 62 | |||
| 63 | return paddr; | ||
| 64 | } | ||
| 65 | |||
| 66 | boost::optional<PAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { | ||
| 67 | PAddr paddr{}; | ||
| 68 | u64 free_space{}; | ||
| 69 | align = (align + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; | ||
| 70 | |||
| 71 | while (paddr + free_space < MAX_ADDRESS) { | ||
| 72 | if (!IsPageMapped(paddr + free_space)) { | ||
| 73 | free_space += Memory::PAGE_SIZE; | ||
| 74 | if (free_space >= size) { | ||
| 75 | return paddr; | ||
| 76 | } | ||
| 77 | } else { | ||
| 78 | paddr += free_space + Memory::PAGE_SIZE; | ||
| 79 | free_space = 0; | ||
| 80 | const u64 remainder{paddr % align}; | ||
| 81 | if (!remainder) { | ||
| 82 | paddr = (paddr - remainder) + align; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | return {}; | ||
| 88 | } | ||
| 89 | |||
| 90 | VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { | ||
| 91 | VAddr base_addr = PageSlot(paddr); | ||
| 92 | ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); | ||
| 93 | return base_addr + (paddr & Memory::PAGE_MASK); | ||
| 94 | } | ||
| 95 | |||
| 96 | bool MemoryManager::IsPageMapped(PAddr paddr) { | ||
| 97 | return PageSlot(paddr) != static_cast<u64>(PageStatus::Unmapped); | ||
| 98 | } | ||
| 99 | |||
| 100 | VAddr& MemoryManager::PageSlot(PAddr paddr) { | ||
| 101 | auto& block = page_table[(paddr >> (Memory::PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; | ||
| 102 | if (!block) { | ||
| 103 | block = std::make_unique<PageBlock>(); | ||
| 104 | for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { | ||
| 105 | (*block)[index] = static_cast<u64>(PageStatus::Unmapped); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | return (*block)[(paddr >> Memory::PAGE_BITS) & PAGE_BLOCK_MASK]; | ||
| 109 | } | ||
| 110 | |||
| 111 | } // namespace Nvidia | ||
| 112 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/memory_manager.h b/src/core/hle/service/nvdrv/memory_manager.h new file mode 100644 index 000000000..4ba1a3952 --- /dev/null +++ b/src/core/hle/service/nvdrv/memory_manager.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <memory> | ||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "core/memory.h" | ||
| 11 | |||
| 12 | namespace Service { | ||
| 13 | namespace Nvidia { | ||
| 14 | |||
| 15 | class MemoryManager final { | ||
| 16 | public: | ||
| 17 | MemoryManager() = default; | ||
| 18 | |||
| 19 | PAddr AllocateSpace(u64 size, u64 align); | ||
| 20 | PAddr AllocateSpace(PAddr paddr, u64 size, u64 align); | ||
| 21 | PAddr MapBufferEx(VAddr vaddr, u64 size); | ||
| 22 | PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); | ||
| 23 | VAddr PhysicalToVirtualAddress(PAddr paddr); | ||
| 24 | |||
| 25 | private: | ||
| 26 | boost::optional<PAddr> FindFreeBlock(u64 size, u64 align = 1); | ||
| 27 | bool IsPageMapped(PAddr paddr); | ||
| 28 | VAddr& PageSlot(PAddr paddr); | ||
| 29 | |||
| 30 | enum class PageStatus : u64 { | ||
| 31 | Unmapped = 0xFFFFFFFFFFFFFFFFULL, | ||
| 32 | Allocated = 0xFFFFFFFFFFFFFFFEULL, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static constexpr u64 MAX_ADDRESS{0x10000000000ULL}; | ||
| 36 | static constexpr u64 PAGE_TABLE_BITS{14}; | ||
| 37 | static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS}; | ||
| 38 | static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1}; | ||
| 39 | static constexpr u64 PAGE_BLOCK_BITS{14}; | ||
| 40 | static constexpr u64 PAGE_BLOCK_SIZE{1 << PAGE_BLOCK_BITS}; | ||
| 41 | static constexpr u64 PAGE_BLOCK_MASK{PAGE_BLOCK_SIZE - 1}; | ||
| 42 | |||
| 43 | using PageBlock = std::array<VAddr, PAGE_BLOCK_SIZE>; | ||
| 44 | std::array<std::unique_ptr<PageBlock>, PAGE_TABLE_SIZE> page_table{}; | ||
| 45 | }; | ||
| 46 | |||
| 47 | } // namespace Nvidia | ||
| 48 | } // namespace Service | ||
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 1cf8f3175..a98634422 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -31,7 +31,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { | |||
| 31 | 31 | ||
| 32 | Module::Module() { | 32 | Module::Module() { |
| 33 | auto nvmap_dev = std::make_shared<Devices::nvmap>(); | 33 | auto nvmap_dev = std::make_shared<Devices::nvmap>(); |
| 34 | devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(); | 34 | devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(nvmap_dev); |
| 35 | devices["/dev/nvhost-ctrl-gpu"] = std::make_shared<Devices::nvhost_ctrl_gpu>(); | 35 | devices["/dev/nvhost-ctrl-gpu"] = std::make_shared<Devices::nvhost_ctrl_gpu>(); |
| 36 | devices["/dev/nvmap"] = nvmap_dev; | 36 | devices["/dev/nvmap"] = nvmap_dev; |
| 37 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); | 37 | devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); |