2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

nvdrv: convert nvmap

This commit is contained in:
Liam 2023-10-24 13:36:57 -04:00
parent efdb2e8f3d
commit 18450ebd78
3 changed files with 26 additions and 60 deletions

View file

@ -13,6 +13,7 @@
#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_process.h"
#include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/core/nvmap.h" #include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvmap.h" #include "core/hle/service/nvdrv/devices/nvmap.h"
#include "core/memory.h" #include "core/memory.h"
@ -31,17 +32,17 @@ NvResult nvmap::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> input,
case 0x1: case 0x1:
switch (command.cmd) { switch (command.cmd) {
case 0x1: case 0x1:
return IocCreate(input, output); return Wrap1(&nvmap::IocCreate, input, output);
case 0x3: case 0x3:
return IocFromId(input, output); return Wrap1(&nvmap::IocFromId, input, output);
case 0x4: case 0x4:
return IocAlloc(input, output); return Wrap1(&nvmap::IocAlloc, input, output);
case 0x5: case 0x5:
return IocFree(input, output); return Wrap1(&nvmap::IocFree, input, output);
case 0x9: case 0x9:
return IocParam(input, output); return Wrap1(&nvmap::IocParam, input, output);
case 0xe: case 0xe:
return IocGetId(input, output); return Wrap1(&nvmap::IocGetId, input, output);
default: default:
break; break;
} }
@ -69,9 +70,7 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> input, st
void nvmap::OnOpen(DeviceFD fd) {} void nvmap::OnOpen(DeviceFD fd) {}
void nvmap::OnClose(DeviceFD fd) {} void nvmap::OnClose(DeviceFD fd) {}
NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) { NvResult nvmap::IocCreate(IocCreateParams& params) {
IocCreateParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size); LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size);
std::shared_ptr<NvCore::NvMap::Handle> handle_description{}; std::shared_ptr<NvCore::NvMap::Handle> handle_description{};
@ -85,13 +84,10 @@ NvResult nvmap::IocCreate(std::span<const u8> input, std::span<u8> output) {
params.handle = handle_description->id; params.handle = handle_description->id;
LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size); LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size);
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) { NvResult nvmap::IocAlloc(IocAllocParams& params) {
IocAllocParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address); LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address);
if (!params.handle) { if (!params.handle) {
@ -133,14 +129,10 @@ NvResult nvmap::IocAlloc(std::span<const u8> input, std::span<u8> output) {
handle_description->size, handle_description->size,
Kernel::KMemoryPermission::None, true, false) Kernel::KMemoryPermission::None, true, false)
.IsSuccess()); .IsSuccess());
std::memcpy(output.data(), &params, sizeof(params));
return result; return result;
} }
NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) { NvResult nvmap::IocGetId(IocGetIdParams& params) {
IocGetIdParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
// See the comment in FromId for extra info on this function // See the comment in FromId for extra info on this function
@ -157,14 +149,10 @@ NvResult nvmap::IocGetId(std::span<const u8> input, std::span<u8> output) {
} }
params.id = handle_description->id; params.id = handle_description->id;
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) { NvResult nvmap::IocFromId(IocFromIdParams& params) {
IocFromIdParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id); LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id);
// Handles and IDs are always the same value in nvmap however IDs can be used globally given the // Handles and IDs are always the same value in nvmap however IDs can be used globally given the
@ -188,16 +176,12 @@ NvResult nvmap::IocFromId(std::span<const u8> input, std::span<u8> output) {
return result; return result;
} }
params.handle = handle_description->id; params.handle = handle_description->id;
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) { NvResult nvmap::IocParam(IocParamParams& params) {
enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 }; enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 };
IocParamParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called type={}", params.param); LOG_DEBUG(Service_NVDRV, "called type={}", params.param);
if (!params.handle) { if (!params.handle) {
@ -237,14 +221,10 @@ NvResult nvmap::IocParam(std::span<const u8> input, std::span<u8> output) {
return NvResult::BadValue; return NvResult::BadValue;
} }
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success; return NvResult::Success;
} }
NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) { NvResult nvmap::IocFree(IocFreeParams& params) {
IocFreeParams params;
std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "called"); LOG_DEBUG(Service_NVDRV, "called");
if (!params.handle) { if (!params.handle) {
@ -267,7 +247,6 @@ NvResult nvmap::IocFree(std::span<const u8> input, std::span<u8> output) {
// This is possible when there's internal dups or other duplicates. // This is possible when there's internal dups or other duplicates.
} }
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success; return NvResult::Success;
} }

View file

@ -99,12 +99,12 @@ public:
}; };
static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size"); static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");
NvResult IocCreate(std::span<const u8> input, std::span<u8> output); NvResult IocCreate(IocCreateParams& params);
NvResult IocAlloc(std::span<const u8> input, std::span<u8> output); NvResult IocAlloc(IocAllocParams& params);
NvResult IocGetId(std::span<const u8> input, std::span<u8> output); NvResult IocGetId(IocGetIdParams& params);
NvResult IocFromId(std::span<const u8> input, std::span<u8> output); NvResult IocFromId(IocFromIdParams& params);
NvResult IocParam(std::span<const u8> input, std::span<u8> output); NvResult IocParam(IocParamParams& params);
NvResult IocFree(std::span<const u8> input, std::span<u8> output); NvResult IocFree(IocFreeParams& params);
private: private:
/// Id to use for the next handle that is created. /// Id to use for the next handle that is created.

View file

@ -71,24 +71,17 @@ Result AllocateIoForProcessAddressSpace(Common::ProcessAddress* out_map_address,
R_SUCCEED(); R_SUCCEED();
} }
template <typename T>
std::span<u8> SerializeIoc(T& params) {
return std::span(reinterpret_cast<u8*>(std::addressof(params)), sizeof(T));
}
Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, u32 size) { Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap, u32 size) {
// Create a handle. // Create a handle.
Nvidia::Devices::nvmap::IocCreateParams create_in_params{ Nvidia::Devices::nvmap::IocCreateParams create_params{
.size = size, .size = size,
.handle = 0, .handle = 0,
}; };
Nvidia::Devices::nvmap::IocCreateParams create_out_params{}; R_UNLESS(nvmap.IocCreate(create_params) == Nvidia::NvResult::Success,
R_UNLESS(nvmap.IocCreate(SerializeIoc(create_in_params), SerializeIoc(create_out_params)) ==
Nvidia::NvResult::Success,
VI::ResultOperationFailed); VI::ResultOperationFailed);
// Assign the output handle. // Assign the output handle.
*out_nv_map_handle = create_out_params.handle; *out_nv_map_handle = create_params.handle;
// We succeeded. // We succeeded.
R_SUCCEED(); R_SUCCEED();
@ -96,13 +89,10 @@ Result CreateNvMapHandle(u32* out_nv_map_handle, Nvidia::Devices::nvmap& nvmap,
Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) { Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) {
// Free the handle. // Free the handle.
Nvidia::Devices::nvmap::IocFreeParams free_in_params{ Nvidia::Devices::nvmap::IocFreeParams free_params{
.handle = handle, .handle = handle,
}; };
Nvidia::Devices::nvmap::IocFreeParams free_out_params{}; R_UNLESS(nvmap.IocFree(free_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed);
R_UNLESS(nvmap.IocFree(SerializeIoc(free_in_params), SerializeIoc(free_out_params)) ==
Nvidia::NvResult::Success,
VI::ResultOperationFailed);
// We succeeded. // We succeeded.
R_SUCCEED(); R_SUCCEED();
@ -111,7 +101,7 @@ Result FreeNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle) {
Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer, Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::ProcessAddress buffer,
u32 size) { u32 size) {
// Assign the allocated memory to the handle. // Assign the allocated memory to the handle.
Nvidia::Devices::nvmap::IocAllocParams alloc_in_params{ Nvidia::Devices::nvmap::IocAllocParams alloc_params{
.handle = handle, .handle = handle,
.heap_mask = 0, .heap_mask = 0,
.flags = {}, .flags = {},
@ -119,10 +109,7 @@ Result AllocNvMapHandle(Nvidia::Devices::nvmap& nvmap, u32 handle, Common::Proce
.kind = 0, .kind = 0,
.address = GetInteger(buffer), .address = GetInteger(buffer),
}; };
Nvidia::Devices::nvmap::IocAllocParams alloc_out_params{}; R_UNLESS(nvmap.IocAlloc(alloc_params) == Nvidia::NvResult::Success, VI::ResultOperationFailed);
R_UNLESS(nvmap.IocAlloc(SerializeIoc(alloc_in_params), SerializeIoc(alloc_out_params)) ==
Nvidia::NvResult::Success,
VI::ResultOperationFailed);
// We succeeded. // We succeeded.
R_SUCCEED(); R_SUCCEED();