1
0
Fork 0
forked from suyu/suyu

hle: service: nvdrv: Revert #4981 to remove usage of SleepClientThread.

- Note, this always processes the ioctl right away, which fixes BotW 1.0.0 issues.
This commit is contained in:
bunnei 2020-12-11 16:04:46 -08:00
parent 8bc3d66354
commit 0c81b83ca9
23 changed files with 83 additions and 211 deletions

View file

@ -31,8 +31,8 @@ public:
* @param output A buffer where the output data will be written to. * @param output A buffer where the output data will be written to.
* @returns The result code of the ioctl. * @returns The result code of the ioctl.
*/ */
virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, virtual NvResult Ioctl1(Ioctl command, const std::vector<u8>& input,
IoctlCtrl& ctrl) = 0; std::vector<u8>& output) = 0;
/** /**
* Handles an ioctl2 request. * Handles an ioctl2 request.
@ -43,8 +43,7 @@ public:
* @returns The result code of the ioctl. * @returns The result code of the ioctl.
*/ */
virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, virtual NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) = 0;
IoctlCtrl& ctrl) = 0;
/** /**
* Handles an ioctl3 request. * Handles an ioctl3 request.
@ -55,7 +54,7 @@ public:
* @returns The result code of the ioctl. * @returns The result code of the ioctl.
*/ */
virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, virtual NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) = 0; std::vector<u8>& inline_output) = 0;
protected: protected:
Core::System& system; Core::System& system;

View file

@ -18,21 +18,20 @@ nvdisp_disp0::nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_de
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
nvdisp_disp0 ::~nvdisp_disp0() = default; nvdisp_disp0 ::~nvdisp_disp0() = default;
NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvdisp_disp0::Ioctl1(Ioctl command, const std::vector<u8>& input,
IoctlCtrl& ctrl) { std::vector<u8>& output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvdisp_disp0::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvdisp_disp0::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }

View file

@ -20,13 +20,11 @@ public:
explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); explicit nvdisp_disp0(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvdisp_disp0() override; ~nvdisp_disp0() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
/// Performs a screen flip, drawing the buffer pointed to by the handle. /// Performs a screen flip, drawing the buffer pointed to by the handle.
void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride, void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,

View file

@ -21,8 +21,8 @@ nvhost_as_gpu::nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_
: nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {} : nvdevice(system), nvmap_dev(std::move(nvmap_dev)) {}
nvhost_as_gpu::~nvhost_as_gpu() = default; nvhost_as_gpu::~nvhost_as_gpu() = default;
NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
IoctlCtrl& ctrl) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'A': case 'A':
switch (command.cmd) { switch (command.cmd) {
@ -55,14 +55,13 @@ NvResult nvhost_as_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std:
} }
NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_as_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_as_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
switch (command.group) { switch (command.group) {
case 'A': case 'A':
switch (command.cmd) { switch (command.cmd) {

View file

@ -30,13 +30,11 @@ public:
explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); explicit nvhost_as_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvhost_as_gpu() override; ~nvhost_as_gpu() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
private: private:
class BufferMap final { class BufferMap final {

View file

@ -20,8 +20,7 @@ nvhost_ctrl::nvhost_ctrl(Core::System& system, EventInterface& events_interface,
: nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {} : nvdevice(system), events_interface{events_interface}, syncpoint_manager{syncpoint_manager} {}
nvhost_ctrl::~nvhost_ctrl() = default; nvhost_ctrl::~nvhost_ctrl() = default;
NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
@ -30,9 +29,9 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
case 0x1c: case 0x1c:
return IocCtrlClearEventWait(input, output); return IocCtrlClearEventWait(input, output);
case 0x1d: case 0x1d:
return IocCtrlEventWait(input, output, false, ctrl); return IocCtrlEventWait(input, output, false);
case 0x1e: case 0x1e:
return IocCtrlEventWait(input, output, true, ctrl); return IocCtrlEventWait(input, output, true);
case 0x1f: case 0x1f:
return IocCtrlEventRegister(input, output); return IocCtrlEventRegister(input, output);
case 0x20: case 0x20:
@ -48,14 +47,13 @@ NvResult nvhost_ctrl::Ioctl1(Ioctl command, const std::vector<u8>& input, std::v
} }
NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_ctrl::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_outpu) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
@ -69,7 +67,7 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector
} }
NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
bool is_async, IoctlCtrl& ctrl) { bool is_async) {
IocCtrlEventWaitParams params{}; IocCtrlEventWaitParams params{};
std::memcpy(&params, input.data(), sizeof(params)); std::memcpy(&params, input.data(), sizeof(params));
LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}", LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}",
@ -141,12 +139,6 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
params.value |= event_id; params.value |= event_id;
event.event.writable->Clear(); event.event.writable->Clear();
gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
if (!is_async && ctrl.fresh_call) {
ctrl.must_delay = true;
ctrl.timeout = params.timeout;
ctrl.event_id = event_id;
return NvResult::Timeout;
}
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Timeout; return NvResult::Timeout;
} }

View file

@ -18,13 +18,11 @@ public:
SyncpointManager& syncpoint_manager); SyncpointManager& syncpoint_manager);
~nvhost_ctrl() override; ~nvhost_ctrl() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
private: private:
struct IocSyncptReadParams { struct IocSyncptReadParams {
@ -123,8 +121,7 @@ private:
static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size"); static_assert(sizeof(IocCtrlEventKill) == 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, bool is_async, NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, bool is_async);
IoctlCtrl& ctrl);
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 IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output);

View file

@ -16,7 +16,7 @@ nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system) : nvdevice(system) {}
nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default; nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output, IoctlCtrl& ctrl) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'G': case 'G':
switch (command.cmd) { switch (command.cmd) {
@ -48,15 +48,13 @@ NvResult nvhost_ctrl_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input,
} }
NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, NvResult nvhost_ctrl_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output, std::vector<u8>& inline_output, std::vector<u8>& output, std::vector<u8>& inline_output) {
IoctlCtrl& ctrl) {
switch (command.group) { switch (command.group) {
case 'G': case 'G':
switch (command.cmd) { switch (command.cmd) {

View file

@ -16,13 +16,11 @@ public:
explicit nvhost_ctrl_gpu(Core::System& system); explicit nvhost_ctrl_gpu(Core::System& system);
~nvhost_ctrl_gpu() override; ~nvhost_ctrl_gpu() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
private: private:
struct IoctlGpuCharacteristics { struct IoctlGpuCharacteristics {

View file

@ -23,8 +23,7 @@ nvhost_gpu::nvhost_gpu(Core::System& system, std::shared_ptr<nvmap> nvmap_dev,
nvhost_gpu::~nvhost_gpu() = default; nvhost_gpu::~nvhost_gpu() = default;
NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
@ -76,8 +75,7 @@ NvResult nvhost_gpu::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
}; };
NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
switch (command.group) { switch (command.group) {
case 'H': case 'H':
switch (command.cmd) { switch (command.cmd) {
@ -91,7 +89,7 @@ NvResult nvhost_gpu::Ioctl2(Ioctl command, const std::vector<u8>& input,
} }
NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_gpu::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }

View file

@ -26,13 +26,11 @@ public:
SyncpointManager& syncpoint_manager); SyncpointManager& syncpoint_manager);
~nvhost_gpu() override; ~nvhost_gpu() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
private: private:
enum class CtxObjects : u32_le { enum class CtxObjects : u32_le {

View file

@ -15,8 +15,8 @@ nvhost_nvdec::nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_de
: nvhost_nvdec_common(system, std::move(nvmap_dev)) {} : nvhost_nvdec_common(system, std::move(nvmap_dev)) {}
nvhost_nvdec::~nvhost_nvdec() = default; nvhost_nvdec::~nvhost_nvdec() = default;
NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input,
IoctlCtrl& ctrl) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
@ -58,14 +58,13 @@ NvResult nvhost_nvdec::Ioctl1(Ioctl command, const std::vector<u8>& input, std::
} }
NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvdec::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_nvdec::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }

View file

@ -14,13 +14,11 @@ public:
explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); explicit nvhost_nvdec(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvhost_nvdec() override; ~nvhost_nvdec() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View file

@ -13,8 +13,8 @@ namespace Service::Nvidia::Devices {
nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {} nvhost_nvjpg::nvhost_nvjpg(Core::System& system) : nvdevice(system) {}
nvhost_nvjpg::~nvhost_nvjpg() = default; nvhost_nvjpg::~nvhost_nvjpg() = default;
NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input,
IoctlCtrl& ctrl) { std::vector<u8>& output) {
switch (command.group) { switch (command.group) {
case 'H': case 'H':
switch (command.cmd) { switch (command.cmd) {
@ -33,14 +33,13 @@ NvResult nvhost_nvjpg::Ioctl1(Ioctl command, const std::vector<u8>& input, std::
} }
NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_nvjpg::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_nvjpg::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }

View file

@ -16,13 +16,11 @@ public:
explicit nvhost_nvjpg(Core::System& system); explicit nvhost_nvjpg(Core::System& system);
~nvhost_nvjpg() override; ~nvhost_nvjpg() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
private: private:
struct IoctlSetNvmapFD { struct IoctlSetNvmapFD {

View file

@ -15,8 +15,7 @@ nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev)
nvhost_vic::~nvhost_vic() = default; nvhost_vic::~nvhost_vic() = default;
NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
@ -51,14 +50,13 @@ NvResult nvhost_vic::Ioctl1(Ioctl command, const std::vector<u8>& input, std::ve
} }
NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvhost_vic::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvhost_vic::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }

View file

@ -14,12 +14,10 @@ public:
explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev); explicit nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev);
~nvhost_vic(); ~nvhost_vic();
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View file

@ -19,8 +19,7 @@ nvmap::nvmap(Core::System& system) : nvdevice(system) {
nvmap::~nvmap() = default; nvmap::~nvmap() = default;
NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
switch (command.group) { switch (command.group) {
case 0x1: case 0x1:
switch (command.cmd) { switch (command.cmd) {
@ -49,14 +48,13 @@ NvResult nvmap::Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<
} }
NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult nvmap::Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult nvmap::Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& inline_output) {
UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw); UNIMPLEMENTED_MSG("Unimplemented ioctl={:08X}", command.raw);
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }

View file

@ -19,13 +19,11 @@ public:
explicit nvmap(Core::System& system); explicit nvmap(Core::System& system);
~nvmap() override; ~nvmap() override;
NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl1(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl2(Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) override;
IoctlCtrl& ctrl) override;
NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output, NvResult Ioctl3(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output, IoctlCtrl& ctrl) override; std::vector<u8>& inline_output) override;
/// Returns the allocated address of an nvmap object given its handle. /// Returns the allocated address of an nvmap object given its handle.
VAddr GetObjectAddress(u32 handle) const; VAddr GetObjectAddress(u32 handle) const;

View file

@ -61,32 +61,9 @@ void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) {
std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
const auto input_buffer = ctx.ReadBuffer(0); const auto input_buffer = ctx.ReadBuffer(0);
IoctlCtrl ctrl{}; const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer);
if (command.is_out != 0) {
const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer, ctrl); ctx.WriteBuffer(output_buffer);
if (ctrl.must_delay) {
ctrl.fresh_call = false;
ctx.SleepClientThread(
"NVServices::DelayedResponse", ctrl.timeout,
[=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
Kernel::ThreadWakeupReason reason) {
IoctlCtrl ctrl2{ctrl};
std::vector<u8> tmp_output = output_buffer;
const auto nv_result2 = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output, ctrl2);
if (command.is_out != 0) {
ctx.WriteBuffer(tmp_output);
}
IPC::ResponseBuilder rb{ctx_, 3};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(nv_result2);
},
nvdrv->GetEventWriteable(ctrl.event_id));
} else {
if (command.is_out != 0) {
ctx.WriteBuffer(output_buffer);
}
} }
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};
@ -110,36 +87,8 @@ void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
const auto input_inlined_buffer = ctx.ReadBuffer(1); const auto input_inlined_buffer = ctx.ReadBuffer(1);
std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
IoctlCtrl ctrl{};
const auto nv_result = const auto nv_result =
nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer, ctrl); nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer);
if (ctrl.must_delay) {
ctrl.fresh_call = false;
ctx.SleepClientThread(
"NVServices::DelayedResponse", ctrl.timeout,
[=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
Kernel::ThreadWakeupReason reason) {
IoctlCtrl ctrl2{ctrl};
std::vector<u8> tmp_output = output_buffer;
const auto nv_result2 = nvdrv->Ioctl2(fd, command, input_buffer,
input_inlined_buffer, tmp_output, ctrl2);
if (command.is_out != 0) {
ctx.WriteBuffer(tmp_output);
}
IPC::ResponseBuilder rb{ctx_, 3};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(nv_result2);
},
nvdrv->GetEventWriteable(ctrl.event_id));
} else {
if (command.is_out != 0) {
ctx.WriteBuffer(output_buffer);
}
}
if (command.is_out != 0) { if (command.is_out != 0) {
ctx.WriteBuffer(output_buffer); ctx.WriteBuffer(output_buffer);
} }
@ -165,36 +114,11 @@ void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0)); std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1)); std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1));
IoctlCtrl ctrl{};
const auto nv_result = const auto nv_result =
nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline, ctrl); nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline);
if (ctrl.must_delay) { if (command.is_out != 0) {
ctrl.fresh_call = false; ctx.WriteBuffer(output_buffer, 0);
ctx.SleepClientThread( ctx.WriteBuffer(output_buffer_inline, 1);
"NVServices::DelayedResponse", ctrl.timeout,
[=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
Kernel::ThreadWakeupReason reason) {
IoctlCtrl ctrl2{ctrl};
std::vector<u8> tmp_output = output_buffer;
std::vector<u8> tmp_output2 = output_buffer;
const auto nv_result2 =
nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output2, ctrl2);
if (command.is_out != 0) {
ctx.WriteBuffer(tmp_output, 0);
ctx.WriteBuffer(tmp_output2, 1);
}
IPC::ResponseBuilder rb{ctx_, 3};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(nv_result2);
},
nvdrv->GetEventWriteable(ctrl.event_id));
} else {
if (command.is_out != 0) {
ctx.WriteBuffer(output_buffer, 0);
ctx.WriteBuffer(output_buffer_inline, 1);
}
} }
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};

View file

@ -97,15 +97,4 @@ union Ioctl {
BitField<31, 1, u32> is_out; BitField<31, 1, u32> is_out;
}; };
struct IoctlCtrl {
// First call done to the servioce for services that call itself again after a call.
bool fresh_call{true};
// Tells the Ioctl Wrapper that it must delay the IPC response and send the thread to sleep
bool must_delay{};
// Timeout for the delay
s64 timeout{};
// NV Event Id
s32 event_id{-1};
};
} // namespace Service::Nvidia } // namespace Service::Nvidia

View file

@ -91,7 +91,7 @@ DeviceFD Module::Open(const std::string& device_name) {
} }
NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output, IoctlCtrl& ctrl) { std::vector<u8>& output) {
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
return NvResult::InvalidState; return NvResult::InvalidState;
@ -104,12 +104,11 @@ NvResult Module::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
return itr->second->Ioctl1(command, input, output, ctrl); return itr->second->Ioctl1(command, input, output);
} }
NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, const std::vector<u8>& inline_input, std::vector<u8>& output) {
IoctlCtrl& ctrl) {
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
return NvResult::InvalidState; return NvResult::InvalidState;
@ -122,11 +121,11 @@ NvResult Module::Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
return itr->second->Ioctl2(command, input, inline_input, output, ctrl); return itr->second->Ioctl2(command, input, inline_input, output);
} }
NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output, std::vector<u8>& inline_output, IoctlCtrl& ctrl) { std::vector<u8>& output, std::vector<u8>& inline_output) {
if (fd < 0) { if (fd < 0) {
LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd); LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
return NvResult::InvalidState; return NvResult::InvalidState;
@ -139,7 +138,7 @@ NvResult Module::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input
return NvResult::NotImplemented; return NvResult::NotImplemented;
} }
return itr->second->Ioctl3(command, input, output, inline_output, ctrl); return itr->second->Ioctl3(command, input, output, inline_output);
} }
NvResult Module::Close(DeviceFD fd) { NvResult Module::Close(DeviceFD fd) {

View file

@ -119,13 +119,13 @@ public:
/// Sends an ioctl command to the specified file descriptor. /// Sends an ioctl command to the specified file descriptor.
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output, IoctlCtrl& ctrl); std::vector<u8>& output);
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
const std::vector<u8>& inline_input, std::vector<u8>& output, IoctlCtrl& ctrl); const std::vector<u8>& inline_input, std::vector<u8>& output);
NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input, NvResult Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output, std::vector<u8>& inline_output, IoctlCtrl& ctrl); std::vector<u8>& output, std::vector<u8>& inline_output);
/// Closes a device file descriptor and returns operation success. /// Closes a device file descriptor and returns operation success.
NvResult Close(DeviceFD fd); NvResult Close(DeviceFD fd);