diff options
| author | Subv <subv2112@gmail.com> | 2018-01-08 21:30:22 -0500 |
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2018-01-10 23:28:29 -0500 |
| commit | 34ae2ec644f49b04d6c6b82742812b6a8a3ef8b5 (patch) | |
| tree | b3b01b63dd0fa4fdc240a549257b685595f277cf /src/core/hle/service/nvdrv/nvdrv_a.cpp | |
| parent | e21fbd9ae5d8139d585019228e1fb1a6229f244c (diff) | |
NV: Expose the nvdisp_disp0 device and a weak reference to the nvdrv:a service.
NVFlinger will call into the nvdisp_disp0 device to perform screen flips, bypassing the ioctl interface.
We now have the address of the framebuffer to draw, we just need to actually put it on the screen.
Diffstat (limited to 'src/core/hle/service/nvdrv/nvdrv_a.cpp')
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv_a.cpp | 290 |
1 files changed, 123 insertions, 167 deletions
diff --git a/src/core/hle/service/nvdrv/nvdrv_a.cpp b/src/core/hle/service/nvdrv/nvdrv_a.cpp index af6b7f7aa..cede4a883 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_a.cpp @@ -18,202 +18,156 @@ public: } }; -class nvmap : public nvdevice { -public: - u32 ioctl(u32 command, const std::vector<u8>& input, std::vector<u8>& output) override { - 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); - } +VAddr nvmap::GetObjectAddress(u32 handle) const { + auto itr = handles.find(handle); + ASSERT(itr != handles.end()); - ASSERT(false, "Unimplemented"); + 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); } -private: - // Represents an nvmap object. - struct Object { - enum class Status { Created, Allocated }; - u32 id; - u32 size; - u32 flags; - u32 align; - u8 kind; - u64 addr; - Status status; - }; + ASSERT(false, "Unimplemented"); +} - u32 next_handle = 1; - u32 next_id = 1; - std::unordered_map<u32, std::shared_ptr<Object>> handles; +u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { + IocCreateParams params; + std::memcpy(¶ms, input.data(), sizeof(params)); - enum IoctlCommands { - IocCreateCommand = 0xC0080101, - IocFromIdCommand = 0xC0080103, - IocAllocCommand = 0xC0200104, - IocParamCommand = 0xC00C0109, - IocGetIdCommand = 0xC008010E - }; + // 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; - struct IocCreateParams { - // Input - u32_le size; - // Output - u32_le handle; - }; + u32 handle = next_handle++; + handles[handle] = std::move(object); - 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; - }; + LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size); - struct IocGetIdParams { - // Output - u32_le id; - // Input - u32_le handle; - }; + params.handle = handle; - struct IocFromIdParams { - // Input - u32_le id; - // Output - u32_le handle; - }; + std::memcpy(output.data(), ¶ms, sizeof(params)); + return 0; +} - struct IocParamParams { - // Input - u32_le handle; - u32_le type; - // Output - u32_le value; - }; +u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { + IocAllocParams params; + std::memcpy(¶ms, input.data(), sizeof(params)); - u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { - IocCreateParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); + auto itr = handles.find(params.handle); + ASSERT(itr != handles.end()); - // 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; + 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; - u32 handle = next_handle++; - handles[handle] = std::move(object); + LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr); - LOG_WARNING(Service, "(STUBBED) size 0x%08X", params.size); + std::memcpy(output.data(), ¶ms, sizeof(params)); + return 0; +} - params.handle = handle; +u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { + IocGetIdParams params; + std::memcpy(¶ms, input.data(), sizeof(params)); - std::memcpy(output.data(), ¶ms, sizeof(params)); - return 0; - } + LOG_WARNING(Service, "called"); - u32 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 itr = handles.find(params.handle); - ASSERT(itr != handles.end()); + params.id = itr->second->id; - 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; + std::memcpy(output.data(), ¶ms, sizeof(params)); + return 0; +} - LOG_WARNING(Service, "(STUBBED) Allocated address 0x%llx", params.addr); +u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { + IocFromIdParams params; + std::memcpy(¶ms, input.data(), sizeof(params)); - std::memcpy(output.data(), ¶ms, sizeof(params)); - return 0; - } + LOG_WARNING(Service, "(STUBBED) called"); - u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { - IocGetIdParams params; - std::memcpy(¶ms, input.data(), sizeof(params)); + auto itr = std::find_if(handles.begin(), handles.end(), + [&](const auto& entry) { return entry.second->id == params.id; }); + ASSERT(itr != handles.end()); - LOG_WARNING(Service, "called"); + // Make a new handle for the object + u32 handle = next_handle++; + handles[handle] = itr->second; - auto itr = handles.find(params.handle); - ASSERT(itr != handles.end()); + params.handle = handle; - params.id = itr->second->id; + std::memcpy(output.data(), ¶ms, sizeof(params)); + return 0; +} - 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"); } - u32 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; +} - 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; +} - u32 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; - } -}; +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"); @@ -275,8 +229,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>(); - devices["/dev/nvmap"] = std::make_shared<nvmap>(); + devices["/dev/nvmap"] = nvmap_dev; + devices["/dev/nvdisp_disp0"] = std::make_shared<nvdisp_disp0>(nvmap_dev); } } // namespace NVDRV |
