NVHOST_CTRl: Implement missing method and fix some stuffs.

master
Fernando Sahmkow 2021-11-07 14:17:32 +07:00
parent 139ea93512
commit 2c62563ab5
4 changed files with 35 additions and 6 deletions

@ -121,6 +121,7 @@ else()
if (ARCHITECTURE_x86_64) if (ARCHITECTURE_x86_64)
add_compile_options("-mcx16") add_compile_options("-mcx16")
add_compile_options("-fwrapv")
endif() endif()
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)

@ -52,6 +52,8 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
return IocCtrlEventRegister(input, output); return IocCtrlEventRegister(input, output);
case 0x20: case 0x20:
return IocCtrlEventUnregister(input, output); return IocCtrlEventUnregister(input, output);
case 0x21:
return IocCtrlEventUnregisterBatch(input, output);
} }
break; break;
default: default:
@ -249,6 +251,25 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input,
return FreeEvent(event_id); return FreeEvent(event_id);
} }
NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector<u8>& input,
std::vector<u8>& output) {
IocCtrlEventUnregisterBatchParams params{};
std::memcpy(&params, input.data(), sizeof(params));
u64 event_mask = params.user_events;
LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask);
auto lock = NvEventsLock();
while (event_mask != 0) {
const u64 event_id = std::countr_zero(event_mask);
event_mask &= ~(1ULL << event_id);
const auto result = FreeEvent(static_cast<u32>(event_id));
if (result != NvResult::Success) {
return result;
}
}
return NvResult::Success;
}
NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) {
IocCtrlEventClearParams params{}; IocCtrlEventClearParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
@ -362,10 +383,11 @@ u32 nvhost_ctrl::FindFreeNvEvent(u32 syncpoint_id) {
} }
void nvhost_ctrl::SignalNvEvent(u32 syncpoint_id, u32 value) { void nvhost_ctrl::SignalNvEvent(u32 syncpoint_id, u32 value) {
const u32 max = MaxNvEvents - std::countl_zero(events_mask); u64 signal_mask = events_mask;
const u32 min = std::countr_zero(events_mask); while (signal_mask != 0) {
for (u32 i = min; i < max; i++) { const u64 event_id = std::countr_zero(signal_mask);
auto& event = events[i]; signal_mask &= ~(1ULL << event_id);
auto& event = events[event_id];
if (event.assigned_syncpt != syncpoint_id || event.assigned_value != value) { if (event.assigned_syncpt != syncpoint_id || event.assigned_value != value) {
continue; continue;
} }

@ -177,16 +177,17 @@ private:
static_assert(sizeof(IocCtrlEventUnregisterParams) == 4, static_assert(sizeof(IocCtrlEventUnregisterParams) == 4,
"IocCtrlEventUnregisterParams is incorrect size"); "IocCtrlEventUnregisterParams is incorrect size");
struct IocCtrlEventKill { struct IocCtrlEventUnregisterBatchParams {
u64_le user_events{}; u64_le user_events{};
}; };
static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size"); static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, "IocCtrlEventKill is incorrect size");
NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output); NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
bool is_allocation); bool is_allocation);
NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocCtrlEventUnregisterBatch(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output);
NvResult FreeEvent(u32 slot); NvResult FreeEvent(u32 slot);

@ -249,6 +249,11 @@ struct GPU::Impl {
void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) { void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) {
std::scoped_lock lock{sync_mutex}; std::scoped_lock lock{sync_mutex};
u32 current_value = syncpoints.at(syncpoint_id).load();
if ((static_cast<s32>(current_value) - static_cast<s32>(value)) >= 0) {
TriggerCpuInterrupt(syncpoint_id, value);
return;
}
auto& interrupt = syncpt_interrupts.at(syncpoint_id); auto& interrupt = syncpt_interrupts.at(syncpoint_id);
bool contains = std::any_of(interrupt.begin(), interrupt.end(), bool contains = std::any_of(interrupt.begin(), interrupt.end(),
[value](u32 in_value) { return in_value == value; }); [value](u32 in_value) { return in_value == value; });