mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-10 22:16:11 +00:00
Another pair of fixes on nvgpu
This commit is contained in:
@@ -375,39 +375,42 @@ NvResult nvhost_as_gpu::MapBufferEx(IoctlMapBufferEx& params) {
|
||||
mapping_map.insert_or_assign(params.offset, Mapping(params.handle, device_address, params.offset, size, false, big_page, false));
|
||||
}
|
||||
|
||||
map_buffer_offsets.insert(params.offset);
|
||||
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
NvResult nvhost_as_gpu::UnmapBuffer(IoctlUnmapBuffer& params) {
|
||||
LOG_DEBUG(Service_NVDRV, "called, offset={:#X}", params.offset);
|
||||
|
||||
std::scoped_lock lock(mutex);
|
||||
if (auto const offset_it = map_buffer_offsets.find(params.offset); offset_it != map_buffer_offsets.end()) {
|
||||
LOG_DEBUG(Service_NVDRV, "called, offset={:#X}", params.offset);
|
||||
if (!vm.initialised) {
|
||||
return NvResult::BadValue;
|
||||
}
|
||||
|
||||
auto const it = mapping_map.find(params.offset);
|
||||
auto const mapping = it->second;
|
||||
if (!mapping.fixed) {
|
||||
auto& allocator{mapping.big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
|
||||
u32 page_size_bits{mapping.big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
|
||||
allocator.Free(u32(mapping.offset >> page_size_bits), u32(mapping.size >> page_size_bits));
|
||||
}
|
||||
|
||||
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
|
||||
// Only FreeSpace can unmap them fully
|
||||
if (mapping.sparse_alloc) {
|
||||
gmmu->MapSparse(params.offset, mapping.size, mapping.big_page);
|
||||
} else {
|
||||
gmmu->Unmap(params.offset, mapping.size);
|
||||
}
|
||||
|
||||
nvmap.UnpinHandle(mapping.handle);
|
||||
mapping_map.erase(params.offset);
|
||||
map_buffer_offsets.erase(params.offset);
|
||||
if (!vm.initialised) {
|
||||
return NvResult::BadValue;
|
||||
}
|
||||
|
||||
auto const it = mapping_map.find(params.offset);
|
||||
if (it == mapping_map.end()) {
|
||||
LOG_WARNING(Service_NVDRV, "Couldn't find region to unmap at {:#X}", params.offset);
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
auto const mapping = it->second;
|
||||
if (!mapping.fixed) {
|
||||
auto& allocator{mapping.big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
|
||||
u32 page_size_bits{mapping.big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
|
||||
allocator.Free(u32(mapping.offset >> page_size_bits), u32(mapping.size >> page_size_bits));
|
||||
}
|
||||
|
||||
// Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
|
||||
// Only FreeSpace can unmap them fully
|
||||
if (mapping.sparse_alloc) {
|
||||
gmmu->MapSparse(params.offset, mapping.size, mapping.big_page);
|
||||
} else {
|
||||
gmmu->Unmap(params.offset, mapping.size);
|
||||
}
|
||||
|
||||
nvmap.UnpinHandle(mapping.handle);
|
||||
mapping_map.erase(it);
|
||||
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <vector>
|
||||
|
||||
#include "common/address_space.h"
|
||||
@@ -113,8 +112,6 @@ private:
|
||||
};
|
||||
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
|
||||
|
||||
ankerl::unordered_dense::set<s64_le> map_buffer_offsets{};
|
||||
|
||||
struct IoctlMapBufferEx {
|
||||
MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
|
||||
u32_le kind{}; // -1 is default
|
||||
|
||||
@@ -174,7 +174,9 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) {
|
||||
case ChannelPriority::Low: channel_timeslice = 1300; break;
|
||||
case ChannelPriority::Medium: channel_timeslice = 2600; break;
|
||||
case ChannelPriority::High: channel_timeslice = 5200; break;
|
||||
default : return NvResult::BadParameter;
|
||||
default:
|
||||
LOG_WARNING(Service_NVDRV, "unknown channel priority {:#X}", channel_priority);
|
||||
break;
|
||||
}
|
||||
|
||||
return NvResult::Success;
|
||||
@@ -278,18 +280,20 @@ NvResult nvhost_gpu::AllocateObjectContext(IoctlAllocObjCtx& params) {
|
||||
params.flags = allowed_mask;
|
||||
}
|
||||
|
||||
s32_le ctx_class_number_index =
|
||||
params.obj_id = 0;
|
||||
|
||||
s32_le ctx_class_number_index =
|
||||
GetObjectContextClassNumberIndex(static_cast<CtxClasses>(params.class_num));
|
||||
if (ctx_class_number_index < 0) {
|
||||
LOG_ERROR(Service_NVDRV, "Invalid class number for object context: {:#X}",
|
||||
params.class_num);
|
||||
return NvResult::BadParameter;
|
||||
LOG_WARNING(Service_NVDRV, "Untracked class number for object context: {:#X}",
|
||||
params.class_num);
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
if (ctxObjs[ctx_class_number_index].has_value()) {
|
||||
LOG_WARNING(Service_NVDRV, "Object context for class {:#X} already allocated on this channel",
|
||||
params.class_num);
|
||||
return NvResult::AlreadyAllocated;
|
||||
LOG_DEBUG(Service_NVDRV, "Object context for class {:#X} already allocated on this channel",
|
||||
params.class_num);
|
||||
return NvResult::Success;
|
||||
}
|
||||
|
||||
// Defer actual hardware context binding until channel is initialized.
|
||||
@@ -435,10 +439,6 @@ NvResult nvhost_gpu::ChannelSetTimeout(IoctlChannelSetTimeout& params) {
|
||||
NvResult nvhost_gpu::ChannelSetTimeslice(IoctlSetTimeslice& params) {
|
||||
LOG_INFO(Service_NVDRV, "called, timeslice={:#X}", params.timeslice);
|
||||
|
||||
if (params.timeslice < 1000 || params.timeslice > 5000) {
|
||||
return NvResult::BadParameter;
|
||||
}
|
||||
|
||||
channel_timeslice = params.timeslice;
|
||||
|
||||
return NvResult::Success;
|
||||
|
||||
Reference in New Issue
Block a user