mirror of
https://git.citron-emu.org/Citron/Citron.git
synced 2025-02-12 11:36:26 +01:00
nvdrv: Add GetTpcMasks2 support and improve memory mapping validation
This commit makes two main changes: 1. Adds support for GetTpcMasks2 (ioctl 0x13) in nvhost_ctrl_gpu: - Implements new GetTpcMasks2 method to handle TPC mask queries - Adds IoctlGetTpcMasks structure to store mask parameters - Returns conservative single TPC configuration for compatibility 2. Enhances memory mapping validation in HostMemory: - Adds verification check after memory mapping operations - Improves error handling for direct mapped address enabling - Adds logging for mapping and direct address failures Additional changes: - Updates copyright headers to include citron Emulator Project - Improves error handling and validation in several paths - Adds debug logging for TPC mask operations This improves GPU virtualization support and memory mapping reliability.
This commit is contained in:
parent
e8bbdbce42
commit
ecc32958ec
3 changed files with 49 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -720,10 +721,18 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
|
||||||
ASSERT(length % PageAlignment == 0);
|
ASSERT(length % PageAlignment == 0);
|
||||||
ASSERT(virtual_offset + length <= virtual_size);
|
ASSERT(virtual_offset + length <= virtual_size);
|
||||||
ASSERT(host_offset + length <= backing_size);
|
ASSERT(host_offset + length <= backing_size);
|
||||||
|
|
||||||
if (length == 0 || !virtual_base || !impl) {
|
if (length == 0 || !virtual_base || !impl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
|
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
|
||||||
|
|
||||||
|
// Verify mapping was successful
|
||||||
|
if (!impl->IsValidMapping(virtual_offset + virtual_base_offset, length)) {
|
||||||
|
LOG_CRITICAL(Common_Memory, "Failed to verify memory mapping: virtual_offset={:x}, host_offset={:x}, length={:x}",
|
||||||
|
virtual_offset, host_offset, length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
|
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
|
||||||
|
@ -756,9 +765,18 @@ void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 f
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostMemory::EnableDirectMappedAddress() {
|
void HostMemory::EnableDirectMappedAddress() {
|
||||||
if (impl) {
|
if (!impl) {
|
||||||
impl->EnableDirectMappedAddress();
|
LOG_ERROR(Common_Memory, "Implementation not initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl->EnableDirectMappedAddress();
|
||||||
|
|
||||||
|
// Only update virtual_size if the direct mapping was successful
|
||||||
|
if (impl->IsDirectMappingEnabled()) {
|
||||||
virtual_size += reinterpret_cast<uintptr_t>(virtual_base);
|
virtual_size += reinterpret_cast<uintptr_t>(virtual_base);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR(Common_Memory, "Failed to enable direct mapped address");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -45,6 +46,8 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8>
|
||||||
return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output);
|
return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output);
|
||||||
case 0x1c:
|
case 0x1c:
|
||||||
return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output);
|
return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output);
|
||||||
|
case 0x13:
|
||||||
|
return WrapFixed(this, &nvhost_ctrl_gpu::GetTpcMasks2, input, output);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -261,6 +264,24 @@ NvResult nvhost_ctrl_gpu::GetGpuTime(IoctlGetGpuTime& params) {
|
||||||
return NvResult::Success;
|
return NvResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NvResult nvhost_ctrl_gpu::GetTpcMasks2(IoctlGetTpcMasks& params) {
|
||||||
|
LOG_DEBUG(Service_NVDRV, "called, mask_buffer_size={}", params.mask_buf_size);
|
||||||
|
|
||||||
|
// Validate input parameters
|
||||||
|
if (params.mask_buf_size == 0 || params.mask_buf_size > params.tpc_mask_buf.size()) {
|
||||||
|
LOG_ERROR(Service_NVDRV, "Invalid mask buffer size {}", params.mask_buf_size);
|
||||||
|
return NvResult::InvalidValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up TPC mask values based on GPU configuration
|
||||||
|
// Using conservative values for compatibility
|
||||||
|
params.mask_buf_size = 1;
|
||||||
|
params.tpc_mask_buf[0] = 0x1; // Enable first TPC only
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_NVDRV, "TPC mask set to 0x{:x}", params.tpc_mask_buf[0]);
|
||||||
|
return NvResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) {
|
Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) {
|
||||||
switch (event_id) {
|
switch (event_id) {
|
||||||
case 1:
|
case 1:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -34,6 +35,11 @@ public:
|
||||||
|
|
||||||
Kernel::KEvent* QueryEvent(u32 event_id) override;
|
Kernel::KEvent* QueryEvent(u32 event_id) override;
|
||||||
|
|
||||||
|
struct IoctlGetTpcMasks {
|
||||||
|
u32 mask_buf_size{};
|
||||||
|
std::array<u32, 1> tpc_mask_buf{};
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr std::size_t MaxZBCTableSize = 16;
|
static constexpr std::size_t MaxZBCTableSize = 16;
|
||||||
static constexpr std::size_t MaxZBCFormats = 32;
|
static constexpr std::size_t MaxZBCFormats = 32;
|
||||||
|
@ -201,6 +207,8 @@ private:
|
||||||
NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params);
|
NvResult GetTPCMasks1(IoctlGpuGetTpcMasksArgs& params);
|
||||||
NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask);
|
NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span<u32> tpc_mask);
|
||||||
|
|
||||||
|
NvResult GetTpcMasks2(IoctlGetTpcMasks& params);
|
||||||
|
|
||||||
NvResult GetActiveSlotMask(IoctlActiveSlotMask& params);
|
NvResult GetActiveSlotMask(IoctlActiveSlotMask& params);
|
||||||
NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params);
|
NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params);
|
||||||
NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params);
|
NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params);
|
||||||
|
|
Loading…
Reference in a new issue