mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-28 09:41:36 +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;
|
||||
|
||||
+3
-36
@@ -17,28 +17,12 @@ enum class Mode : u64 {
|
||||
Attr,
|
||||
};
|
||||
|
||||
enum class SZ : u64 {
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
F32
|
||||
};
|
||||
|
||||
enum class Shift : u64 {
|
||||
Default,
|
||||
U16,
|
||||
B32,
|
||||
};
|
||||
|
||||
IR::U32 scaleIndex(IR::IREmitter& ir, IR::U32 index, Shift shift) {
|
||||
switch (shift) {
|
||||
case Shift::Default: return index;
|
||||
case Shift::U16: return ir.ShiftLeftLogical(index, ir.Imm32(1));
|
||||
case Shift::B32: return ir.ShiftLeftLogical(index, ir.Imm32(2));
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
void TranslatorVisitor::ISBERD(u64 insn) {
|
||||
@@ -53,7 +37,6 @@ void TranslatorVisitor::ISBERD(u64 insn) {
|
||||
BitField<31, 1, u64> skew;
|
||||
BitField<32, 1, u64> o;
|
||||
BitField<33, 2, Mode> mode;
|
||||
BitField<36, 4, SZ> sz;
|
||||
BitField<47, 2, Shift> shift;
|
||||
} const isberd{insn};
|
||||
|
||||
@@ -63,31 +46,15 @@ void TranslatorVisitor::ISBERD(u64 insn) {
|
||||
if (isberd.o != 0) {
|
||||
throw NotImplementedException("ISBERD O");
|
||||
}
|
||||
if (isberd.sz.Value() > SZ::F32) {
|
||||
throw NotImplementedException("ISBERD SZ {}",
|
||||
static_cast<u64>(isberd.sz.Value()));
|
||||
}
|
||||
if (isberd.shift.Value() > Shift::B32) {
|
||||
throw NotImplementedException("ISBERD Shift {}",
|
||||
static_cast<u64>(isberd.shift.Value()));
|
||||
}
|
||||
|
||||
switch (isberd.mode.Value()) {
|
||||
case Mode::Default:
|
||||
X(isberd.dest_reg.Value(), X(isberd.src_reg.Value()));
|
||||
return;
|
||||
case Mode::Attr: {
|
||||
IR::U32 offset{};
|
||||
if (isberd.src_reg_num.Value() == 0xFF) {
|
||||
offset = ir.Imm32(isberd.imm.Value());
|
||||
} else {
|
||||
const IR::U32 index{
|
||||
scaleIndex(ir, X(isberd.src_reg.Value()), isberd.shift.Value())};
|
||||
offset = ir.IAdd(index, ir.Imm32(isberd.imm.Value()));
|
||||
}
|
||||
X(isberd.dest_reg.Value(), ir.BitCast<IR::U32>(ir.GetAttributeIndexed(offset)));
|
||||
case Mode::Attr:
|
||||
LOG_DEBUG(Shader, "(STUBBED) ISBERD Mode Attr");
|
||||
X(isberd.dest_reg.Value(), X(isberd.src_reg.Value()));
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throw NotImplementedException("ISBERD Mode {}",
|
||||
static_cast<u64>(isberd.mode.Value()));
|
||||
|
||||
Reference in New Issue
Block a user