From 5bc14e791a8b4260dbf130d2e8724e394db4205c Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 15:31:10 -0500 Subject: [PATCH 1/9] IPC: Push domain objects as move handles when not in a domain. --- src/core/hle/ipc_helpers.h | 22 ++++++++++++++++++++-- src/core/hle/kernel/hle_ipc.h | 8 ++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 0f1077d9e..25530a3c8 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -9,10 +9,13 @@ #include #include #include "core/hle/ipc.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/domain.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/server_port.h" namespace IPC { @@ -63,13 +66,20 @@ public: : RequestHelperBase(context) { memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH); + context.ClearIncomingObjects(); + IPC::CommandHeader header{}; // The entire size of the raw data section in u32 units, including the 16 bytes of mandatory // padding. u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size; - if (context.IsDomain()) + if (context.IsDomain()) { raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects; + } else { + // If we're not in a domain, turn the domain object parameters into move handles. + num_handles_to_move += num_domain_objects; + num_domain_objects = 0; + } header.data_size.Assign(raw_data_size); if (num_handles_to_copy || num_handles_to_move) { @@ -100,7 +110,15 @@ public: template void PushIpcInterface(Args&&... args) { - context->AddDomainObject(std::make_shared(std::forward(args)...)); + auto iface = std::make_shared(std::forward(args)...); + if (context->IsDomain()) { + context->AddDomainObject(std::move(iface)); + } else { + auto port = iface->CreatePort(); + auto session = port->Connect(); + ASSERT(session.Succeeded()); + context->AddMoveObject(std::move(session).Unwrap()); + } } // Validate on destruction, as there shouldn't be any case where we don't want it diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 164c6db69..6dceb766d 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -175,6 +175,14 @@ public: domain_objects.emplace_back(std::move(object)); } + /// Clears the list of objects so that no lingering objects are written accidentally to the + /// response buffer. + void ClearIncomingObjects() { + move_objects.clear(); + copy_objects.clear(); + domain_objects.clear(); + } + private: std::array cmd_buf; SharedPtr domain; From 3442f4b96a89309452aeaba3e4a2c8ffb6696c4f Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 15:41:16 -0500 Subject: [PATCH 2/9] SVC: Add 4.0.0+ comment to GetInfoType enum values. --- src/core/hle/kernel/svc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h index a56fd3602..42cc41da3 100644 --- a/src/core/hle/kernel/svc.h +++ b/src/core/hle/kernel/svc.h @@ -44,6 +44,7 @@ enum class GetInfoType : u64 { // 3.0.0+ IsVirtualAddressMemoryEnabled = 16, TitleId = 18, + // 4.0.0+ PrivilegedProcessId = 19, }; From bf0e20c571326f3b39d0bed0a3b5f2129cef81ea Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 15:42:57 -0500 Subject: [PATCH 3/9] SVC: Correct some return values in svcGetInfo and added TitleId and PrivilegedProcessId stubs. # Conflicts: # src/core/hle/kernel/svc.cpp --- src/core/hle/kernel/svc.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 056ba28ef..088058ebc 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -255,8 +255,9 @@ static ResultCode CancelSynchronization(Handle thread_handle) { /// Attempts to locks a mutex, creating it if it does not already exist static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr, Handle requesting_thread_handle) { - LOG_TRACE(Kernel_SVC, "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, " - "requesting_current_thread_handle=0x%08X", + LOG_TRACE(Kernel_SVC, + "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, " + "requesting_current_thread_handle=0x%08X", holding_thread_handle, mutex_addr, requesting_thread_handle); SharedPtr holding_thread = g_handle_table.Get(holding_thread_handle); @@ -304,8 +305,6 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id, info_sub_id, handle); - ASSERT(handle == 0 || handle == CurrentProcess); - auto& vm_manager = g_current_process->vm_manager; switch (static_cast(info_id)) { @@ -321,6 +320,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) case GetInfoType::MapRegionSize: *result = vm_manager.GetAddressSpaceSize(); break; + case GetInfoType::HeapRegionBaseAddr: + *result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize(); + break; + case GetInfoType::HeapRegionSize: + *result = Memory::HEAP_SIZE; + break; case GetInfoType::TotalMemoryUsage: *result = vm_manager.GetTotalMemoryUsage(); break; @@ -345,6 +350,15 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) case GetInfoType::IsVirtualAddressMemoryEnabled: *result = g_current_process->is_virtual_address_memory_enabled; break; + case GetInfoType::TitleId: + LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0"); + *result = 0; + break; + case GetInfoType::PrivilegedProcessId: + LOG_WARNING(Kernel_SVC, + "(STUBBED) Attempted to query priviledged process id bounds, returned 0"); + *result = 0; + break; default: UNIMPLEMENTED(); } @@ -533,8 +547,9 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V Core::System::GetInstance().PrepareReschedule(); - LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " - "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", + LOG_TRACE(Kernel_SVC, + "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " + "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); return RESULT_SUCCESS; From f7dc637a616fd202f213a1a8eac4888167462825 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 15:43:46 -0500 Subject: [PATCH 4/9] AppletOE: Stub a bunch of functions required by libnx homebrew. --- src/core/hle/service/am/applet_oe.cpp | 66 +++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index b629ac509..ff0390b58 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -71,6 +71,15 @@ private: // Takes 3 input u8s with each field located immediately after the previous u8, these are // bool flags. No output. + IPC::RequestParser rp{ctx}; + + struct FocusHandlingModeParams { + u8 unknown0; + u8 unknown1; + u8 unknown2; + }; + auto flags = rp.PopRaw(); + IPC::RequestBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -85,27 +94,38 @@ private: } void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + bool flag = rp.Pop(); + IPC::RequestBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service, "(STUBBED) called"); + LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast(flag)); } void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + bool flag = rp.Pop(); + IPC::RequestBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service, "(STUBBED) called"); + LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast(flag)); } void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) { // Takes 3 input u8s with each field located immediately after the previous u8, these are // bool flags. No output. + IPC::RequestParser rp{ctx}; + + bool enabled = rp.Pop(); IPC::RequestBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); - LOG_WARNING(Service, "(STUBBED) called"); + LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast(enabled)); } }; @@ -115,6 +135,8 @@ public: static const FunctionInfo functions[] = { {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"}, + {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"}, + {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"}, {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"}, }; RegisterHandlers(functions); @@ -123,6 +145,16 @@ public: } private: + enum class FocusState : u8 { + InFocus = 1, + NotInFocus = 2, + }; + + enum class OperationMode : u8 { + Handheld = 0, + Docked = 1, + }; + void GetEventHandle(Kernel::HLERequestContext& ctx) { event->Signal(); @@ -144,7 +176,23 @@ private: void GetCurrentFocusState(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(1); // 1: In focus, 2/3: Out of focus(running in "background") + rb.Push(static_cast(FocusState::InFocus)); + + LOG_WARNING(Service, "(STUBBED) called"); + } + + void GetOperationMode(Kernel::HLERequestContext& ctx) { + IPC::RequestBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(static_cast(OperationMode::Handheld)); + + LOG_WARNING(Service, "(STUBBED) called"); + } + + void GetPerformanceMode(Kernel::HLERequestContext& ctx) { + IPC::RequestBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(0); LOG_WARNING(Service, "(STUBBED) called"); } @@ -160,6 +208,7 @@ public: {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"}, {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"}, + {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, }; RegisterHandlers(functions); } @@ -187,6 +236,15 @@ private: void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); + + LOG_WARNING(Service, "(STUBBED) called"); + } + + void NotifyRunning(Kernel::HLERequestContext& ctx) { + IPC::RequestBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(0); // Unknown, seems to be ignored by official processes + LOG_WARNING(Service, "(STUBBED) called"); } }; From c5a0408ccca4af6dc27e627a077d5480a3784e84 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 17:19:32 -0500 Subject: [PATCH 5/9] Services: Stubbed APM::OpenSession and the ISession interface. # Conflicts: # src/core/hle/service/am/applet_oe.cpp # src/core/hle/service/apm/apm.cpp --- src/core/hle/service/am/applet_oe.cpp | 3 +- src/core/hle/service/apm/apm.cpp | 44 ++++++++++++++++++++++++++- src/core/hle/service/apm/apm.h | 8 +++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index ff0390b58..03d9991b9 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -6,6 +6,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/event.h" #include "core/hle/service/am/applet_oe.h" +#include "core/hle/service/apm/apm.h" namespace Service { namespace AM { @@ -184,7 +185,7 @@ private: void GetOperationMode(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast(OperationMode::Handheld)); + rb.Push(static_cast(APM::PerformanceMode::Handheld)); LOG_WARNING(Service, "(STUBBED) called"); } diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 957abdd66..66d94ff52 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -13,12 +13,54 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { std::make_shared()->InstallAsService(service_manager); } +class ISession final : public ServiceFramework { +public: + ISession() : ServiceFramework("ISession") { + static const FunctionInfo functions[] = { + {0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"}, + {1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"}, + }; + RegisterHandlers(functions); + } + +private: + void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto mode = static_cast(rp.Pop()); + u32 config = rp.Pop(); + + IPC::RequestBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + + LOG_WARNING(Service, "(STUBBED) called mode=%u config=%u", static_cast(mode), config); + } + + void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto mode = static_cast(rp.Pop()); + + IPC::RequestBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(0); // Performance configuration + + LOG_WARNING(Service, "(STUBBED) called mode=%u", static_cast(mode)); + } +}; + APM::APM() : ServiceFramework("apm") { static const FunctionInfo functions[] = { - {0x00000000, nullptr, "OpenSession"}, {0x00000001, nullptr, "GetPerformanceMode"}, + {0x00000000, &APM::OpenSession, "OpenSession"}, {0x00000001, nullptr, "GetPerformanceMode"}, }; RegisterHandlers(functions); } +void APM::OpenSession(Kernel::HLERequestContext& ctx) { + IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(); +} + } // namespace APM } // namespace Service diff --git a/src/core/hle/service/apm/apm.h b/src/core/hle/service/apm/apm.h index 377db71a4..90a1afbbc 100644 --- a/src/core/hle/service/apm/apm.h +++ b/src/core/hle/service/apm/apm.h @@ -9,10 +9,18 @@ namespace Service { namespace APM { +enum class PerformanceMode : u8 { + Handheld = 0, + Docked = 1, +}; + class APM final : public ServiceFramework { public: APM(); ~APM() = default; + +private: + void OpenSession(Kernel::HLERequestContext& ctx); }; /// Registers all AM services with the specified service manager. From f827b17dd4a3b555714032f409181b877686d10d Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 17:20:08 -0500 Subject: [PATCH 6/9] VI: Stubbed GetNativeHandle, Create/DestroyStrayLayer and CloseDisplay --- src/core/hle/service/vi/vi.cpp | 79 ++++++++++++++++++++++++++++++++-- src/core/hle/service/vi/vi.h | 9 ++++ 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 93ebbe75f..6e1bf481b 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -361,7 +361,7 @@ public: static const FunctionInfo functions[] = { {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, - {2, nullptr, "GetNativeHandle"}, + {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, {3, nullptr, "TransactParcelAuto"}, }; RegisterHandlers(functions); @@ -463,6 +463,21 @@ private: rb.Push(RESULT_SUCCESS); } + void GetNativeHandle(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + u32 id = rp.Pop(); + u32 unknown = rp.Pop(); + + auto buffer_queue = nv_flinger->GetBufferQueue(id); + + // TODO(Subv): Find out what this actually is. + + LOG_WARNING(Service, "(STUBBED) called id=%u, unknown=%08X", id, unknown); + IPC::RequestBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(buffer_queue->GetNativeHandle()); + } + std::shared_ptr nv_flinger; }; @@ -565,6 +580,15 @@ void IApplicationDisplayService::GetManagerDisplayService(Kernel::HLERequestCont rb.PushIpcInterface(nv_flinger); } +void IApplicationDisplayService::GetIndirectDisplayTransactionService( + Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + + IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(nv_flinger); +} + void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -580,6 +604,15 @@ void IApplicationDisplayService::OpenDisplay(Kernel::HLERequestContext& ctx) { rb.Push(nv_flinger->OpenDisplay(name)); } +void IApplicationDisplayService::CloseDisplay(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + u64 display_id = rp.Pop(); + + IPC::RequestBuilder rb = rp.MakeBuilder(4, 0, 0, 0); + rb.Push(RESULT_SUCCESS); +} + void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -605,6 +638,40 @@ void IApplicationDisplayService::OpenLayer(Kernel::HLERequestContext& ctx) { rb.Push(data.size()); } +void IApplicationDisplayService::CreateStrayLayer(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + u32 flags = rp.Pop(); + u64 display_id = rp.Pop(); + + auto& buffer = ctx.BufferDescriptorB()[0]; + + // TODO(Subv): What's the difference between a Stray and a Managed layer? + + u64 layer_id = nv_flinger->CreateLayer(display_id); + u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); + + NativeWindow native_window{buffer_queue_id}; + auto data = native_window.Serialize(); + Memory::WriteBlock(buffer.Address(), data.data(), data.size()); + + IPC::RequestBuilder rb = rp.MakeBuilder(6, 0, 0, 0); + rb.Push(RESULT_SUCCESS); + rb.Push(layer_id); + rb.Push(data.size()); +} + +void IApplicationDisplayService::DestroyStrayLayer(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + u64 layer_id = rp.Pop(); + + IPC::RequestBuilder rb = rp.MakeBuilder(2, 0, 0, 0); + rb.Push(RESULT_SUCCESS); +} + void IApplicationDisplayService::SetLayerScalingMode(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -633,11 +700,15 @@ IApplicationDisplayService::IApplicationDisplayService(std::shared_ptr GetNativeHandle() const { + return native_handle; + } + private: u32 id; u64 layer_id; std::vector queue; + Kernel::SharedPtr native_handle; }; struct Layer { @@ -138,9 +143,13 @@ private: void GetRelayService(Kernel::HLERequestContext& ctx); void GetSystemDisplayService(Kernel::HLERequestContext& ctx); void GetManagerDisplayService(Kernel::HLERequestContext& ctx); + void GetIndirectDisplayTransactionService(Kernel::HLERequestContext& ctx); void OpenDisplay(Kernel::HLERequestContext& ctx); + void CloseDisplay(Kernel::HLERequestContext& ctx); void SetLayerScalingMode(Kernel::HLERequestContext& ctx); void OpenLayer(Kernel::HLERequestContext& ctx); + void CreateStrayLayer(Kernel::HLERequestContext& ctx); + void DestroyStrayLayer(Kernel::HLERequestContext& ctx); void GetDisplayVsyncEvent(Kernel::HLERequestContext& ctx); std::shared_ptr nv_flinger; From 30657f9ca1485dcf9611d3c4ea3c74d52b350dec Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 17:39:00 -0500 Subject: [PATCH 7/9] NV: Move the nvdrv classes into the Nvidia namespace, and move the functionality to a s single module that services call. --- src/core/hle/service/nvdrv/devices/nvdevice.h | 4 +- .../service/nvdrv/devices/nvdisp_disp0.cpp | 4 +- .../hle/service/nvdrv/devices/nvdisp_disp0.h | 4 +- .../service/nvdrv/devices/nvhost_as_gpu.cpp | 4 +- .../hle/service/nvdrv/devices/nvhost_as_gpu.h | 4 +- src/core/hle/service/nvdrv/devices/nvmap.cpp | 4 +- src/core/hle/service/nvdrv/devices/nvmap.h | 4 +- src/core/hle/service/nvdrv/nvdrv.cpp | 43 +++++- src/core/hle/service/nvdrv/nvdrv.h | 122 +++++------------- src/core/hle/service/nvdrv/nvdrv_a.cpp | 27 +--- src/core/hle/service/nvdrv/nvdrv_a.h | 30 +---- src/core/hle/service/service.cpp | 2 +- src/core/hle/service/vi/vi.cpp | 6 +- 13 files changed, 94 insertions(+), 164 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h index 1ee2787c6..5ee33b3d6 100644 --- a/src/core/hle/service/nvdrv/devices/nvdevice.h +++ b/src/core/hle/service/nvdrv/devices/nvdevice.h @@ -8,7 +8,7 @@ #include "common/common_types.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { /// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to @@ -29,5 +29,5 @@ public: }; } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 992f70b45..c42a65b36 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -10,7 +10,7 @@ #include "video_core/video_core.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { u32 nvdisp_disp0::ioctl(u32 command, const std::vector& input, std::vector& output) { @@ -32,5 +32,5 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 } } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h index 601068af1..f5f9de3f4 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h @@ -10,7 +10,7 @@ #include "core/hle/service/nvdrv/devices/nvdevice.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { class nvmap; @@ -30,5 +30,5 @@ private: }; } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index c7bf79050..9db08339a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -7,7 +7,7 @@ #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { u32 nvhost_as_gpu::ioctl(u32 command, const std::vector& input, std::vector& output) { @@ -16,5 +16,5 @@ u32 nvhost_as_gpu::ioctl(u32 command, const std::vector& input, std::vector< } } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index 6f441b020..01f8861c8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h @@ -9,7 +9,7 @@ #include "core/hle/service/nvdrv/devices/nvdevice.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { class nvhost_as_gpu final : public nvdevice { @@ -21,5 +21,5 @@ public: }; } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 2d6f30e3e..d37b5b159 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -9,7 +9,7 @@ #include "core/hle/service/nvdrv/devices/nvmap.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { VAddr nvmap::GetObjectAddress(u32 handle) const { @@ -151,5 +151,5 @@ u32 nvmap::IocParam(const std::vector& input, std::vector& output) { } } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h index e74f356e5..6954c0324 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.h +++ b/src/core/hle/service/nvdrv/devices/nvmap.h @@ -13,7 +13,7 @@ #include "core/hle/service/nvdrv/devices/nvdevice.h" namespace Service { -namespace NVDRV { +namespace Nvidia { namespace Devices { class nvmap final : public nvdevice { @@ -104,5 +104,5 @@ private: }; } // namespace Devices -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index c874e6395..be9946505 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -2,19 +2,50 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/service/nvdrv/devices/nvdevice.h" +#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" +#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" +#include "core/hle/service/nvdrv/devices/nvmap.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvdrv/nvdrv_a.h" namespace Service { -namespace NVDRV { +namespace Nvidia { -std::weak_ptr nvdrv_a; +std::weak_ptr nvdrv; void InstallInterfaces(SM::ServiceManager& service_manager) { - auto nvdrv = std::make_shared(); - nvdrv->InstallAsService(service_manager); - nvdrv_a = nvdrv; + auto module_ = std::make_shared(); + std::make_shared(module_)->InstallAsService(service_manager); + nvdrv = module_; } -} // namespace NVDRV +Module::Module() { + auto nvmap_dev = std::make_shared(); + devices["/dev/nvhost-as-gpu"] = std::make_shared(); + devices["/dev/nvmap"] = nvmap_dev; + devices["/dev/nvdisp_disp0"] = std::make_shared(nvmap_dev); +} + +u32 Module::Open(std::string device_name) { + ASSERT_MSG(devices.find(device_name) != devices.end(), "Trying to open unknown device %s", + device_name.c_str()); + + auto device = devices[device_name]; + u32 fd = next_fd++; + + open_files[fd] = device; + + return fd; +} + +u32 Module::Ioctl(u32 fd, u32 command, const std::vector& input, std::vector& output) { + auto itr = open_files.find(fd); + ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); + + auto device = itr->second; + return device->ioctl(command, input, output); +} + +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index a1c050416..1940ced99 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -11,110 +11,46 @@ #include "core/hle/service/service.h" namespace Service { -namespace NVDRV { +namespace Nvidia { -class nvdevice { +namespace Devices { +class nvdevice; +} + +class Module final { public: - virtual ~nvdevice() = default; + Module(); + ~Module() = default; - virtual u32 ioctl(u32 command, const std::vector& input, std::vector& output) = 0; -}; + /// Returns a pointer to one of the available devices, identified by its name. + template + std::shared_ptr GetDevice(std::string name) { + auto itr = devices.find(name); + if (itr == devices.end()) + return nullptr; + return std::static_pointer_cast(itr->second); + } -class nvmap : public nvdevice { -public: - /// Returns the allocated address of an nvmap object given its handle. - VAddr GetObjectAddress(u32 handle) const; - - u32 ioctl(u32 command, const std::vector& input, std::vector& output) override; + /// Opens a device node and returns a file descriptor to it. + u32 Open(std::string device_name); + /// Sends an ioctl command to the specified file descriptor. + u32 Ioctl(u32 fd, u32 command, const std::vector& input, std::vector& output); private: - // Represents an nvmap object. - struct Object { - enum class Status { Created, Allocated }; - u32 id; - u32 size; - u32 flags; - u32 align; - u8 kind; - VAddr addr; - Status status; - }; + /// Id to use for the next open file descriptor. + u32 next_fd = 1; - u32 next_handle = 1; - u32 next_id = 1; - std::unordered_map> handles; + /// Mapping of file descriptors to the devices they reference. + std::unordered_map> open_files; - enum IoctlCommands { - IocCreateCommand = 0xC0080101, - IocFromIdCommand = 0xC0080103, - IocAllocCommand = 0xC0200104, - IocParamCommand = 0xC00C0109, - IocGetIdCommand = 0xC008010E - }; - - struct IocCreateParams { - // Input - u32_le size; - // Output - u32_le handle; - }; - - struct IocAllocParams { - // Input - u32_le handle; - u32_le heap_mask; - u32_le flags; - u32_le align; - u8 kind; - INSERT_PADDING_BYTES(7); - u64_le addr; - }; - - struct IocGetIdParams { - // Output - u32_le id; - // Input - u32_le handle; - }; - - struct IocFromIdParams { - // Input - u32_le id; - // Output - u32_le handle; - }; - - struct IocParamParams { - // Input - u32_le handle; - u32_le type; - // Output - u32_le value; - }; - - u32 IocCreate(const std::vector& input, std::vector& output); - u32 IocAlloc(const std::vector& input, std::vector& output); - u32 IocGetId(const std::vector& input, std::vector& output); - u32 IocFromId(const std::vector& input, std::vector& output); - u32 IocParam(const std::vector& input, std::vector& output); -}; - -class nvdisp_disp0 : public nvdevice { -public: - nvdisp_disp0(std::shared_ptr nvmap_dev) : nvdevice(), nvmap_dev(std::move(nvmap_dev)) {} - ~nvdisp_disp0() = default; - - u32 ioctl(u32 command, const std::vector& input, std::vector& output) override; - - /// 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); - -private: - std::shared_ptr nvmap_dev; + /// Mapping of device node names to their implementation. + std::unordered_map> devices; }; /// Registers all NVDRV services with the specified service manager. void InstallInterfaces(SM::ServiceManager& service_manager); -} // namespace NVDRV +extern std::weak_ptr nvdrv; + +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/nvdrv_a.cpp b/src/core/hle/service/nvdrv/nvdrv_a.cpp index 84d89cb49..5d3e68792 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_a.cpp @@ -4,15 +4,11 @@ #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/service/nvdrv/devices/nvdevice.h" -#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" -#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" -#include "core/hle/service/nvdrv/devices/nvmap.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvdrv/nvdrv_a.h" namespace Service { -namespace NVDRV { +namespace Nvidia { void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); @@ -21,11 +17,7 @@ void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { std::string device_name = Memory::ReadCString(buffer.Address(), buffer.Size()); - auto device = devices[device_name]; - u32 fd = next_fd++; - - open_files[fd] = device; - + u32 fd = nvdrv->Open(device_name); IPC::RequestBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(fd); @@ -46,11 +38,8 @@ void NVDRV_A::Ioctl(Kernel::HLERequestContext& ctx) { std::vector output(output_buffer.Size()); Memory::ReadBlock(input_buffer.Address(), input.data(), input_buffer.Size()); - auto itr = open_files.find(fd); - ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); - auto device = itr->second; - u32 nv_result = device->ioctl(command, input, output); + u32 nv_result = nvdrv->Ioctl(fd, command, input, output); Memory::WriteBlock(output_buffer.Address(), output.data(), output_buffer.Size()); @@ -66,19 +55,15 @@ void NVDRV_A::Initialize(Kernel::HLERequestContext& ctx) { rb.Push(0); } -NVDRV_A::NVDRV_A() : ServiceFramework("nvdrv:a") { +NVDRV_A::NVDRV_A(std::shared_ptr nvdrv) + : ServiceFramework("nvdrv:a"), nvdrv(std::move(nvdrv)) { static const FunctionInfo functions[] = { {0, &NVDRV_A::Open, "Open"}, {1, &NVDRV_A::Ioctl, "Ioctl"}, {3, &NVDRV_A::Initialize, "Initialize"}, }; RegisterHandlers(functions); - - auto nvmap_dev = std::make_shared(); - devices["/dev/nvhost-as-gpu"] = std::make_shared(); - devices["/dev/nvmap"] = nvmap_dev; - devices["/dev/nvdisp_disp0"] = std::make_shared(nvmap_dev); } -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/nvdrv/nvdrv_a.h b/src/core/hle/service/nvdrv/nvdrv_a.h index 62f10e9f6..743870555 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.h +++ b/src/core/hle/service/nvdrv/nvdrv_a.h @@ -10,42 +10,20 @@ #include "core/hle/service/service.h" namespace Service { -namespace NVDRV { - -namespace Devices { -class nvdevice; -} +namespace Nvidia { class NVDRV_A final : public ServiceFramework { public: - NVDRV_A(); + NVDRV_A(std::shared_ptr nvdrv); ~NVDRV_A() = default; - /// Returns a pointer to one of the available devices, identified by its name. - template - std::shared_ptr GetDevice(std::string name) { - auto itr = devices.find(name); - if (itr == devices.end()) - return nullptr; - return std::static_pointer_cast(itr->second); - } - private: void Open(Kernel::HLERequestContext& ctx); void Ioctl(Kernel::HLERequestContext& ctx); void Initialize(Kernel::HLERequestContext& ctx); - /// Id to use for the next open file descriptor. - u32 next_fd = 1; - - /// Mapping of file descriptors to the devices they reference. - std::unordered_map> open_files; - - /// Mapping of device node names to their implementation. - std::unordered_map> devices; + std::shared_ptr nvdrv; }; -extern std::weak_ptr nvdrv_a; - -} // namespace NVDRV +} // namespace Nvidia } // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 02d434660..44623d40f 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -170,7 +170,7 @@ void Init() { Audio::InstallInterfaces(*SM::g_service_manager); HID::InstallInterfaces(*SM::g_service_manager); LM::InstallInterfaces(*SM::g_service_manager); - NVDRV::InstallInterfaces(*SM::g_service_manager); + Nvidia::InstallInterfaces(*SM::g_service_manager); PCTL::InstallInterfaces(*SM::g_service_manager); Time::InstallInterfaces(*SM::g_service_manager); VI::InstallInterfaces(*SM::g_service_manager); diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 6e1bf481b..cae2c4466 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -9,7 +9,7 @@ #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" -#include "core/hle/service/nvdrv/nvdrv_a.h" +#include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_m.h" #include "video_core/renderer_base.h" @@ -834,12 +834,12 @@ void NVFlinger::Compose() { auto& igbp_buffer = buffer->igbp_buffer; // Now send the buffer to the GPU for drawing. - auto nvdrv = NVDRV::nvdrv_a.lock(); + auto nvdrv = Nvidia::nvdrv.lock(); ASSERT(nvdrv); // TODO(Subv): Support more than just disp0. The display device selection is probably based // on which display we're drawing (Default, Internal, External, etc) - auto nvdisp = nvdrv->GetDevice("/dev/nvdisp_disp0"); + auto nvdisp = nvdrv->GetDevice("/dev/nvdisp_disp0"); ASSERT(nvdisp); nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format, From cb75b56e454a36190f07ee34b0e4e6ee6a7a66be Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 15 Jan 2018 18:30:49 -0500 Subject: [PATCH 8/9] NV: Implemented the nvdrv service, which uses the same interface as nvdrv:a --- src/core/CMakeLists.txt | 4 ++-- .../nvdrv/{nvdrv_a.cpp => interface.cpp} | 18 +++++++++--------- .../service/nvdrv/{nvdrv_a.h => interface.h} | 6 +++--- src/core/hle/service/nvdrv/nvdrv.cpp | 6 ++++-- 4 files changed, 18 insertions(+), 16 deletions(-) rename src/core/hle/service/nvdrv/{nvdrv_a.cpp => interface.cpp} (77%) rename src/core/hle/service/nvdrv/{nvdrv_a.h => interface.h} (80%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f5c92a5aa..2eab81ad6 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -48,8 +48,8 @@ set(SRCS hle/service/nvdrv/devices/nvdisp_disp0.cpp hle/service/nvdrv/devices/nvhost_as_gpu.cpp hle/service/nvdrv/devices/nvmap.cpp + hle/service/nvdrv/interface.cpp hle/service/nvdrv/nvdrv.cpp - hle/service/nvdrv/nvdrv_a.cpp hle/service/pctl/pctl.cpp hle/service/pctl/pctl_a.cpp hle/service/service.cpp @@ -136,8 +136,8 @@ set(HEADERS hle/service/nvdrv/devices/nvdisp_disp0.h hle/service/nvdrv/devices/nvhost_as_gpu.h hle/service/nvdrv/devices/nvmap.h + hle/service/nvdrv/interface.h hle/service/nvdrv/nvdrv.h - hle/service/nvdrv/nvdrv_a.h hle/service/pctl/pctl.h hle/service/pctl/pctl_a.h hle/service/service.h diff --git a/src/core/hle/service/nvdrv/nvdrv_a.cpp b/src/core/hle/service/nvdrv/interface.cpp similarity index 77% rename from src/core/hle/service/nvdrv/nvdrv_a.cpp rename to src/core/hle/service/nvdrv/interface.cpp index 5d3e68792..0670ca155 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -4,13 +4,13 @@ #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/service/nvdrv/interface.h" #include "core/hle/service/nvdrv/nvdrv.h" -#include "core/hle/service/nvdrv/nvdrv_a.h" namespace Service { namespace Nvidia { -void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { +void NVDRV::Open(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); auto buffer = ctx.BufferDescriptorA()[0]; @@ -24,7 +24,7 @@ void NVDRV_A::Open(Kernel::HLERequestContext& ctx) { rb.Push(0); } -void NVDRV_A::Ioctl(Kernel::HLERequestContext& ctx) { +void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestParser rp{ctx}; @@ -48,19 +48,19 @@ void NVDRV_A::Ioctl(Kernel::HLERequestContext& ctx) { rb.Push(nv_result); } -void NVDRV_A::Initialize(Kernel::HLERequestContext& ctx) { +void NVDRV::Initialize(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service, "(STUBBED) called"); IPC::RequestBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push(0); } -NVDRV_A::NVDRV_A(std::shared_ptr nvdrv) - : ServiceFramework("nvdrv:a"), nvdrv(std::move(nvdrv)) { +NVDRV::NVDRV(std::shared_ptr nvdrv, const char* name) + : ServiceFramework(name), nvdrv(std::move(nvdrv)) { static const FunctionInfo functions[] = { - {0, &NVDRV_A::Open, "Open"}, - {1, &NVDRV_A::Ioctl, "Ioctl"}, - {3, &NVDRV_A::Initialize, "Initialize"}, + {0, &NVDRV::Open, "Open"}, + {1, &NVDRV::Ioctl, "Ioctl"}, + {3, &NVDRV::Initialize, "Initialize"}, }; RegisterHandlers(functions); } diff --git a/src/core/hle/service/nvdrv/nvdrv_a.h b/src/core/hle/service/nvdrv/interface.h similarity index 80% rename from src/core/hle/service/nvdrv/nvdrv_a.h rename to src/core/hle/service/nvdrv/interface.h index 743870555..8c95b7217 100644 --- a/src/core/hle/service/nvdrv/nvdrv_a.h +++ b/src/core/hle/service/nvdrv/interface.h @@ -12,10 +12,10 @@ namespace Service { namespace Nvidia { -class NVDRV_A final : public ServiceFramework { +class NVDRV final : public ServiceFramework { public: - NVDRV_A(std::shared_ptr nvdrv); - ~NVDRV_A() = default; + NVDRV(std::shared_ptr nvdrv, const char* name); + ~NVDRV() = default; private: void Open(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index be9946505..cf525a875 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -2,12 +2,13 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/ipc_helpers.h" #include "core/hle/service/nvdrv/devices/nvdevice.h" #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" #include "core/hle/service/nvdrv/devices/nvmap.h" #include "core/hle/service/nvdrv/nvdrv.h" -#include "core/hle/service/nvdrv/nvdrv_a.h" +#include "core/hle/service/nvdrv/interface.h" namespace Service { namespace Nvidia { @@ -16,7 +17,8 @@ std::weak_ptr nvdrv; void InstallInterfaces(SM::ServiceManager& service_manager) { auto module_ = std::make_shared(); - std::make_shared(module_)->InstallAsService(service_manager); + std::make_shared(module_, "nvdrv")->InstallAsService(service_manager); + std::make_shared(module_, "nvdrv:a")->InstallAsService(service_manager); nvdrv = module_; } From f621310da23bee3e68f9b251cf9846c2ebf45e2d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 16 Jan 2018 20:32:08 -0500 Subject: [PATCH 9/9] applet_oe: Fix GetOperationMode and GetPerformanceMode. --- src/core/hle/service/am/applet_oe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index 03d9991b9..b360e7e5f 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -185,7 +185,7 @@ private: void GetOperationMode(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(static_cast(APM::PerformanceMode::Handheld)); + rb.Push(static_cast(OperationMode::Handheld)); LOG_WARNING(Service, "(STUBBED) called"); } @@ -193,7 +193,7 @@ private: void GetPerformanceMode(Kernel::HLERequestContext& ctx) { IPC::RequestBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - rb.Push(0); + rb.Push(static_cast(APM::PerformanceMode::Handheld)); LOG_WARNING(Service, "(STUBBED) called"); }