mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 02:34:11 +01:00 
			
		
		
		
	NV: Move the nv device nodes to their own directory and namespace.
This commit is contained in:
		
							parent
							
								
									977ce4abbc
								
							
						
					
					
						commit
						1ca800ccee
					
				| @ -45,6 +45,9 @@ set(SRCS | ||||
|             hle/service/gsp_gpu.cpp | ||||
|             hle/service/hid/hid.cpp | ||||
|             hle/service/lm/lm.cpp | ||||
|             hle/service/nvdrv/devices/nvdisp_disp0.cpp | ||||
|             hle/service/nvdrv/devices/nvhost_as_gpu.cpp | ||||
|             hle/service/nvdrv/devices/nvmap.cpp | ||||
|             hle/service/nvdrv/nvdrv.cpp | ||||
|             hle/service/nvdrv/nvdrv_a.cpp | ||||
|             hle/service/pctl/pctl.cpp | ||||
| @ -132,6 +135,10 @@ set(HEADERS | ||||
|             hle/service/gsp_gpu.h | ||||
|             hle/service/hid/hid.h | ||||
|             hle/service/lm/lm.h | ||||
|             hle/service/nvdrv/devices/nvdevice.h | ||||
|             hle/service/nvdrv/devices/nvdisp_disp0.h | ||||
|             hle/service/nvdrv/devices/nvhost_as_gpu.h | ||||
|             hle/service/nvdrv/devices/nvmap.h | ||||
|             hle/service/nvdrv/nvdrv.h | ||||
|             hle/service/nvdrv/nvdrv_a.h | ||||
|             hle/service/pctl/pctl.h | ||||
|  | ||||
							
								
								
									
										33
									
								
								src/core/hle/service/nvdrv/devices/nvdevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/core/hle/service/nvdrv/devices/nvdevice.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| /// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to
 | ||||
| /// implement the ioctl interface.
 | ||||
| class nvdevice { | ||||
| public: | ||||
|     nvdevice() = default; | ||||
|     virtual ~nvdevice() = default; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Handles an ioctl request. | ||||
|      * @param command The ioctl command id. | ||||
|      * @param input A buffer containing the input data for the ioctl. | ||||
|      * @param output A buffer where the output data will be written to. | ||||
|      * @returns The result code of the ioctl. | ||||
|      */ | ||||
|     virtual u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) = 0; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
							
								
								
									
										29
									
								
								src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvmap.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| u32 nvdisp_disp0::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     ASSERT(false, "Unimplemented"); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | ||||
|                         u32 stride) { | ||||
|     VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | ||||
|     LOG_WARNING(Service, | ||||
|                 "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", | ||||
|                 addr, offset, width, height, stride, format); | ||||
| } | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
							
								
								
									
										34
									
								
								src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| class nvmap; | ||||
| 
 | ||||
| class nvdisp_disp0 final : public nvdevice { | ||||
| public: | ||||
|     nvdisp_disp0(std::shared_ptr<nvmap> nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) {} | ||||
|     ~nvdisp_disp0() = default; | ||||
| 
 | ||||
|     u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||||
| 
 | ||||
|     /// Performs a screen flip, drawing the buffer pointed to by the handle.
 | ||||
|     void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride); | ||||
| 
 | ||||
| private: | ||||
|     std::shared_ptr<nvmap> nvmap_dev; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
							
								
								
									
										20
									
								
								src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| u32 nvhost_as_gpu::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     ASSERT(false, "Unimplemented"); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
							
								
								
									
										25
									
								
								src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| class nvhost_as_gpu final : public nvdevice { | ||||
| public: | ||||
|     nvhost_as_gpu() = default; | ||||
|     ~nvhost_as_gpu() override = default; | ||||
| 
 | ||||
|     u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
							
								
								
									
										153
									
								
								src/core/hle/service/nvdrv/devices/nvmap.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/core/hle/service/nvdrv/devices/nvmap.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,153 @@ | ||||
| // Copyright 2018 Yuzu Emulator Team
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvmap.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| VAddr nvmap::GetObjectAddress(u32 handle) const { | ||||
|     auto itr = handles.find(handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     auto object = itr->second; | ||||
|     ASSERT(object->status == Object::Status::Allocated); | ||||
|     return object->addr; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     switch (command) { | ||||
|     case IocCreateCommand: | ||||
|         return IocCreate(input, output); | ||||
|     case IocAllocCommand: | ||||
|         return IocAlloc(input, output); | ||||
|     case IocGetIdCommand: | ||||
|         return IocGetId(input, output); | ||||
|     case IocFromIdCommand: | ||||
|         return IocFromId(input, output); | ||||
|     case IocParamCommand: | ||||
|         return IocParam(input, output); | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(false, "Unimplemented"); | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocCreateParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     // Create a new nvmap object and obtain a handle to it.
 | ||||
|     auto object = std::make_shared<Object>(); | ||||
|     object->id = next_id++; | ||||
|     object->size = params.size; | ||||
|     object->status = Object::Status::Created; | ||||
| 
 | ||||
|     u32 handle = next_handle++; | ||||
|     handles[handle] = std::move(object); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size); | ||||
| 
 | ||||
|     params.handle = handle; | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocAllocParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     auto itr = handles.find(params.handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     auto object = itr->second; | ||||
|     object->flags = params.flags; | ||||
|     object->align = params.align; | ||||
|     object->kind = params.kind; | ||||
|     object->addr = params.addr; | ||||
|     object->status = Object::Status::Allocated; | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr); | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocGetIdParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "called"); | ||||
| 
 | ||||
|     auto itr = handles.find(params.handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     params.id = itr->second->id; | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocFromIdParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) called"); | ||||
| 
 | ||||
|     auto itr = std::find_if(handles.begin(), handles.end(), | ||||
|                             [&](const auto& entry) { return entry.second->id == params.id; }); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     // Make a new handle for the object
 | ||||
|     u32 handle = next_handle++; | ||||
|     handles[handle] = itr->second; | ||||
| 
 | ||||
|     params.handle = handle; | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; | ||||
| 
 | ||||
|     IocParamParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) called type=%u", params.type); | ||||
| 
 | ||||
|     auto itr = handles.find(params.handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     auto object = itr->second; | ||||
|     ASSERT(object->status == Object::Status::Allocated); | ||||
| 
 | ||||
|     switch (static_cast<ParamTypes>(params.type)) { | ||||
|     case ParamTypes::Size: | ||||
|         params.value = object->size; | ||||
|         break; | ||||
|     case ParamTypes::Alignment: | ||||
|         params.value = object->align; | ||||
|         break; | ||||
|     case ParamTypes::Heap: | ||||
|         // TODO(Subv): Seems to be a hardcoded value?
 | ||||
|         params.value = 0x40000000; | ||||
|         break; | ||||
|     case ParamTypes::Kind: | ||||
|         params.value = object->kind; | ||||
|         break; | ||||
|     default: | ||||
|         ASSERT(false, "Unimplemented"); | ||||
|     } | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
							
								
								
									
										108
									
								
								src/core/hle/service/nvdrv/devices/nvmap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/core/hle/service/nvdrv/devices/nvmap.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| // Copyright 2018 Citra Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <unordered_map> | ||||
| #include <vector> | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/swap.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| namespace Devices { | ||||
| 
 | ||||
| class nvmap final : public nvdevice { | ||||
| public: | ||||
|     nvmap() = default; | ||||
|     ~nvmap() override = default; | ||||
| 
 | ||||
|     /// Returns the allocated address of an nvmap object given its handle.
 | ||||
|     VAddr GetObjectAddress(u32 handle) const; | ||||
| 
 | ||||
|     u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override; | ||||
| 
 | ||||
| private: | ||||
|     // Represents an nvmap object.
 | ||||
|     struct Object { | ||||
|         enum class Status { Created, Allocated }; | ||||
|         u32 id; | ||||
|         u32 size; | ||||
|         u32 flags; | ||||
|         u32 align; | ||||
|         u8 kind; | ||||
|         VAddr addr; | ||||
|         Status status; | ||||
|     }; | ||||
| 
 | ||||
|     /// Id to use for the next handle that is created.
 | ||||
|     u32 next_handle = 1; | ||||
| 
 | ||||
|     // Id to use for the next object that is created.
 | ||||
|     u32 next_id = 1; | ||||
| 
 | ||||
|     /// Mapping of currently allocated handles to the objects they represent.
 | ||||
|     std::unordered_map<u32, std::shared_ptr<Object>> handles; | ||||
| 
 | ||||
|     enum IoctlCommands { | ||||
|         IocCreateCommand = 0xC0080101, | ||||
|         IocFromIdCommand = 0xC0080103, | ||||
|         IocAllocCommand = 0xC0200104, | ||||
|         IocParamCommand = 0xC00C0109, | ||||
|         IocGetIdCommand = 0xC008010E | ||||
|     }; | ||||
| 
 | ||||
|     struct IocCreateParams { | ||||
|         // Input
 | ||||
|         u32_le size; | ||||
|         // Output
 | ||||
|         u32_le handle; | ||||
|     }; | ||||
| 
 | ||||
|     struct IocAllocParams { | ||||
|         // Input
 | ||||
|         u32_le handle; | ||||
|         u32_le heap_mask; | ||||
|         u32_le flags; | ||||
|         u32_le align; | ||||
|         u8 kind; | ||||
|         INSERT_PADDING_BYTES(7); | ||||
|         u64_le addr; | ||||
|     }; | ||||
| 
 | ||||
|     struct IocGetIdParams { | ||||
|         // Output
 | ||||
|         u32_le id; | ||||
|         // Input
 | ||||
|         u32_le handle; | ||||
|     }; | ||||
| 
 | ||||
|     struct IocFromIdParams { | ||||
|         // Input
 | ||||
|         u32_le id; | ||||
|         // Output
 | ||||
|         u32_le handle; | ||||
|     }; | ||||
| 
 | ||||
|     struct IocParamParams { | ||||
|         // Input
 | ||||
|         u32_le handle; | ||||
|         u32_le type; | ||||
|         // Output
 | ||||
|         u32_le value; | ||||
|     }; | ||||
| 
 | ||||
|     u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output); | ||||
|     u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output); | ||||
|     u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output); | ||||
|     u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output); | ||||
|     u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output); | ||||
| }; | ||||
| 
 | ||||
| } // namespace Devices
 | ||||
| } // namespace NVDRV
 | ||||
| } // namespace Service
 | ||||
| @ -4,171 +4,16 @@ | ||||
| 
 | ||||
| #include "common/logging/log.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdevice.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvmap.h" | ||||
| #include "core/hle/service/nvdrv/nvdrv.h" | ||||
| #include "core/hle/service/nvdrv/nvdrv_a.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| 
 | ||||
| class nvhost_as_gpu : public nvdevice { | ||||
| public: | ||||
|     u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override { | ||||
|         ASSERT(false, "Unimplemented"); | ||||
|         return 0; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| VAddr nvmap::GetObjectAddress(u32 handle) const { | ||||
|     auto itr = handles.find(handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     auto object = itr->second; | ||||
|     ASSERT(object->status == Object::Status::Allocated); | ||||
|     return object->addr; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     switch (command) { | ||||
|     case IocCreateCommand: | ||||
|         return IocCreate(input, output); | ||||
|     case IocAllocCommand: | ||||
|         return IocAlloc(input, output); | ||||
|     case IocGetIdCommand: | ||||
|         return IocGetId(input, output); | ||||
|     case IocFromIdCommand: | ||||
|         return IocFromId(input, output); | ||||
|     case IocParamCommand: | ||||
|         return IocParam(input, output); | ||||
|     } | ||||
| 
 | ||||
|     ASSERT(false, "Unimplemented"); | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocCreateParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     // Create a new nvmap object and obtain a handle to it.
 | ||||
|     auto object = std::make_shared<Object>(); | ||||
|     object->id = next_id++; | ||||
|     object->size = params.size; | ||||
|     object->status = Object::Status::Created; | ||||
| 
 | ||||
|     u32 handle = next_handle++; | ||||
|     handles[handle] = std::move(object); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size); | ||||
| 
 | ||||
|     params.handle = handle; | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocAllocParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     auto itr = handles.find(params.handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     auto object = itr->second; | ||||
|     object->flags = params.flags; | ||||
|     object->align = params.align; | ||||
|     object->kind = params.kind; | ||||
|     object->addr = params.addr; | ||||
|     object->status = Object::Status::Allocated; | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr); | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocGetIdParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "called"); | ||||
| 
 | ||||
|     auto itr = handles.find(params.handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     params.id = itr->second->id; | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     IocFromIdParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) called"); | ||||
| 
 | ||||
|     auto itr = std::find_if(handles.begin(), handles.end(), | ||||
|                             [&](const auto& entry) { return entry.second->id == params.id; }); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     // Make a new handle for the object
 | ||||
|     u32 handle = next_handle++; | ||||
|     handles[handle] = itr->second; | ||||
| 
 | ||||
|     params.handle = handle; | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; | ||||
| 
 | ||||
|     IocParamParams params; | ||||
|     std::memcpy(¶ms, input.data(), sizeof(params)); | ||||
| 
 | ||||
|     LOG_WARNING(Service, "(STUBBED) called type=%u", params.type); | ||||
| 
 | ||||
|     auto itr = handles.find(params.handle); | ||||
|     ASSERT(itr != handles.end()); | ||||
| 
 | ||||
|     auto object = itr->second; | ||||
|     ASSERT(object->status == Object::Status::Allocated); | ||||
| 
 | ||||
|     switch (static_cast<ParamTypes>(params.type)) { | ||||
|     case ParamTypes::Size: | ||||
|         params.value = object->size; | ||||
|         break; | ||||
|     case ParamTypes::Alignment: | ||||
|         params.value = object->align; | ||||
|         break; | ||||
|     case ParamTypes::Heap: | ||||
|         // TODO(Subv): Seems to be a hardcoded value?
 | ||||
|         params.value = 0x40000000; | ||||
|         break; | ||||
|     case ParamTypes::Kind: | ||||
|         params.value = object->kind; | ||||
|         break; | ||||
|     default: | ||||
|         ASSERT(false, "Unimplemented"); | ||||
|     } | ||||
| 
 | ||||
|     std::memcpy(output.data(), ¶ms, sizeof(params)); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| u32 nvdisp_disp0::ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) { | ||||
|     ASSERT(false, "Unimplemented"); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, | ||||
|                         u32 stride) { | ||||
|     VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle); | ||||
|     LOG_WARNING(Service, | ||||
|                 "Drawing from address %llx offset %08X Width %u Height %u Stride %u Format %u", | ||||
|                 addr, offset, width, height, stride, format); | ||||
| } | ||||
| 
 | ||||
| void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service, "(STUBBED) called"); | ||||
| 
 | ||||
| @ -229,10 +74,10 @@ NVDRV_A::NVDRV_A() : ServiceFramework("nvdrv:a") { | ||||
|     }; | ||||
|     RegisterHandlers(functions); | ||||
| 
 | ||||
|     auto nvmap_dev = std::make_shared<nvmap>(); | ||||
|     devices["/dev/nvhost-as-gpu"] = std::make_shared<nvhost_as_gpu>(); | ||||
|     auto nvmap_dev = std::make_shared<Devices::nvmap>(); | ||||
|     devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(); | ||||
|     devices["/dev/nvmap"] = nvmap_dev; | ||||
|     devices["/dev/nvdisp_disp0"] = std::make_shared<nvdisp_disp0>(nvmap_dev); | ||||
|     devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(nvmap_dev); | ||||
| } | ||||
| 
 | ||||
| } // namespace NVDRV
 | ||||
|  | ||||
| @ -5,12 +5,17 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include "core/hle/service/service.h" | ||||
| #include <string> | ||||
| #include "core/hle/service/nvdrv/nvdrv.h" | ||||
| #include "core/hle/service/service.h" | ||||
| 
 | ||||
| namespace Service { | ||||
| namespace NVDRV { | ||||
| 
 | ||||
| namespace Devices { | ||||
| class nvdevice; | ||||
| } | ||||
| 
 | ||||
| class NVDRV_A final : public ServiceFramework<NVDRV_A> { | ||||
| public: | ||||
|     NVDRV_A(); | ||||
| @ -30,10 +35,14 @@ private: | ||||
|     void Ioctl(Kernel::HLERequestContext& ctx); | ||||
|     void Initialize(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     /// Id to use for the next open file descriptor.
 | ||||
|     u32 next_fd = 1; | ||||
| 
 | ||||
|     std::unordered_map<u32, std::shared_ptr<nvdevice>> open_files; | ||||
|     std::unordered_map<std::string, std::shared_ptr<nvdevice>> devices; | ||||
|     /// Mapping of file descriptors to the devices they reference.
 | ||||
|     std::unordered_map<u32, std::shared_ptr<Devices::nvdevice>> open_files; | ||||
| 
 | ||||
|     /// Mapping of device node names to their implementation.
 | ||||
|     std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; | ||||
| }; | ||||
| 
 | ||||
| extern std::weak_ptr<NVDRV_A> nvdrv_a; | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| #include "common/scope_exit.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | ||||
| #include "core/hle/service/nvdrv/nvdrv_a.h" | ||||
| #include "core/hle/service/vi/vi.h" | ||||
| #include "core/hle/service/vi/vi_m.h" | ||||
| @ -752,7 +753,7 @@ void NVFlinger::Compose() { | ||||
| 
 | ||||
|         // TODO(Subv): Support more than just disp0. The display device selection is probably based
 | ||||
|         // on which display we're drawing (Default, Internal, External, etc)
 | ||||
|         auto nvdisp = nvdrv->GetDevice<NVDRV::nvdisp_disp0>("/dev/nvdisp_disp0"); | ||||
|         auto nvdisp = nvdrv->GetDevice<NVDRV::Devices::nvdisp_disp0>("/dev/nvdisp_disp0"); | ||||
|         ASSERT(nvdisp); | ||||
| 
 | ||||
|         nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user