diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/hle_ipc.cpp | 51 | ||||
-rw-r--r-- | src/core/hle/kernel/hle_ipc.h | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 13 | ||||
-rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.cpp | 58 | ||||
-rw-r--r-- | src/core/hle/service/ns/ns.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/ns/ns.h | 16 | ||||
-rw-r--r-- | src/core/hle/service/ns/pl_u.cpp | 111 | ||||
-rw-r--r-- | src/core/hle/service/ns/pl_u.h | 33 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 2 |
11 files changed, 295 insertions, 14 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index fc6cb67c7..ce68194c5 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -124,6 +124,10 @@ add_library(core STATIC hle/service/nifm/nifm_s.h hle/service/nifm/nifm_u.cpp hle/service/nifm/nifm_u.h + hle/service/ns/ns.cpp + hle/service/ns/ns.h + hle/service/ns/pl_u.cpp + hle/service/ns/pl_u.h hle/service/nvdrv/devices/nvdevice.h hle/service/nvdrv/devices/nvdisp_disp0.cpp hle/service/nvdrv/devices/nvdisp_disp0.h diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 6d16f71a7..25ba26f18 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -254,4 +254,55 @@ size_t HLERequestContext::GetWriteBufferSize() const { return is_buffer_b ? BufferDescriptorB()[0].Size() : BufferDescriptorC()[0].Size(); } +std::string HLERequestContext::Description() const { + if (!command_header) { + return "No command header available"; + } + std::ostringstream s; + s << "IPC::CommandHeader: Type:" << static_cast<u32>(command_header->type.Value()); + s << ", X(Pointer):" << command_header->num_buf_x_descriptors; + if (command_header->num_buf_x_descriptors) { + s << '['; + for (u64 i = 0; i < command_header->num_buf_x_descriptors; ++i) { + s << "0x" << std::hex << BufferDescriptorX()[i].Size(); + if (i < command_header->num_buf_x_descriptors - 1) + s << ", "; + } + s << ']'; + } + s << ", A(Send):" << command_header->num_buf_a_descriptors; + if (command_header->num_buf_a_descriptors) { + s << '['; + for (u64 i = 0; i < command_header->num_buf_a_descriptors; ++i) { + s << "0x" << std::hex << BufferDescriptorA()[i].Size(); + if (i < command_header->num_buf_a_descriptors - 1) + s << ", "; + } + s << ']'; + } + s << ", B(Receive):" << command_header->num_buf_b_descriptors; + if (command_header->num_buf_b_descriptors) { + s << '['; + for (u64 i = 0; i < command_header->num_buf_b_descriptors; ++i) { + s << "0x" << std::hex << BufferDescriptorB()[i].Size(); + if (i < command_header->num_buf_b_descriptors - 1) + s << ", "; + } + s << ']'; + } + s << ", C(ReceiveList):" << BufferDescriptorC().size(); + if (!BufferDescriptorC().empty()) { + s << '['; + for (u64 i = 0; i < BufferDescriptorC().size(); ++i) { + s << "0x" << std::hex << BufferDescriptorC()[i].Size(); + if (i < BufferDescriptorC().size() - 1) + s << ", "; + } + s << ']'; + } + s << ", data_size:" << command_header->data_size.Value(); + + return s.str(); +} + } // namespace Kernel diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 81e3489c8..b5631b773 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -202,6 +202,8 @@ public: return domain_objects.size(); } + std::string Description() const; + private: std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; SharedPtr<Kernel::ServerSession> server_session; diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 835fc710b..d4505061e 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -111,13 +111,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi return ERR_INVALID_COMBINATION; } - // Heap-backed memory blocks can not be mapped with other_permissions = DontCare - if (base_address != 0 && other_permissions == MemoryPermission::DontCare) { - LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match", - GetObjectId(), address, name.c_str()); - return ERR_INVALID_COMBINATION; - } - // Error out if the provided permissions are not compatible with what the creator process needs. if (other_permissions != MemoryPermission::DontCare && static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) { @@ -126,12 +119,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi return ERR_WRONG_PERMISSION; } - // TODO(Subv): Check for the Shared Device Mem flag in the creator process. - /*if (was_created_with_shared_device_mem && address != 0) { - return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); - }*/ - // TODO(Subv): The same process that created a SharedMemory object // can not map it in its own address space unless it was created with addr=0, result 0xD900182C. diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 20306c6cf..4efc789ac 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -53,7 +53,8 @@ private: } void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { - AudioRendererResponseData response_data = {0}; + LOG_DEBUG(Service_Audio, "%s", ctx.Description().c_str()); + AudioRendererResponseData response_data{}; response_data.section_0_size = response_data.state_entries.size() * sizeof(AudioRendererStateEntry); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index d757d2eae..dacd1862d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -176,7 +176,10 @@ public: {0, &Hid::CreateAppletResource, "CreateAppletResource"}, {1, &Hid::ActivateDebugPad, "ActivateDebugPad"}, {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"}, + {21, &Hid::ActivateMouse, "ActivateMouse"}, + {31, &Hid::ActivateKeyboard, "ActivateKeyboard"}, {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"}, + {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"}, {103, &Hid::ActivateNpad, "ActivateNpad"}, @@ -184,9 +187,15 @@ public: "AcquireNpadStyleSetUpdateEventHandle"}, {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, + {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, + "SetNpadJoyAssignmentModeSingleByDefault"}, {124, nullptr, "SetNpadJoyAssignmentModeDual"}, {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, + {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, + {201, &Hid::SendVibrationValue, "SendVibrationValue"}, + {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"}, {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"}, + {206, &Hid::SendVibrationValues, "SendVibrationValues"}, }; RegisterHandlers(functions); @@ -222,12 +231,30 @@ private: LOG_WARNING(Service_HID, "(STUBBED) called"); } + void ActivateMouse(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void ActivateKeyboard(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_HID, "(STUBBED) called"); } + void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -266,18 +293,49 @@ private: LOG_WARNING(Service_HID, "(STUBBED) called"); } + void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void SendVibrationValue(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + + void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_HID, "(STUBBED) called"); } + void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.Push<u64>(0); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } + void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<IActiveVibrationDeviceList>(); LOG_DEBUG(Service_HID, "called"); } + + void SendVibrationValues(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } }; void ReloadInputDevices() {} diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp new file mode 100644 index 000000000..45681c50f --- /dev/null +++ b/src/core/hle/service/ns/ns.cpp @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/ns/ns.h" +#include "core/hle/service/ns/pl_u.h" + +namespace Service { +namespace NS { + +void InstallInterfaces(SM::ServiceManager& service_manager) { + std::make_shared<PL_U>()->InstallAsService(service_manager); +} + +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h new file mode 100644 index 000000000..a4b7e3ded --- /dev/null +++ b/src/core/hle/service/ns/ns.h @@ -0,0 +1,16 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service { +namespace NS { + +/// Registers all NS services with the specified service manager. +void InstallInterfaces(SM::ServiceManager& service_manager); + +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp new file mode 100644 index 000000000..cc9d03a7c --- /dev/null +++ b/src/core/hle/service/ns/pl_u.cpp @@ -0,0 +1,111 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/common_paths.h" +#include "common/file_util.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/service/ns/pl_u.h" + +namespace Service { +namespace NS { + +struct FontRegion { + u32 offset; + u32 size; +}; + +// The below data is specific to shared font data dumped from Switch on f/w 2.2 +// Virtual address and offsets/sizes likely will vary by dump +static constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; +static constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000}; +static constexpr std::array<FontRegion, 6> SHARED_FONT_REGIONS{ + FontRegion{0x00000008, 0x001fe764}, FontRegion{0x001fe774, 0x00773e58}, + FontRegion{0x009725d4, 0x0001aca8}, FontRegion{0x0098d284, 0x00369cec}, + FontRegion{0x00cf6f78, 0x0039b858}, FontRegion{0x010927d8, 0x00019e80}, +}; + +enum class LoadState : u32 { + Loading = 0, + Done = 1, +}; + +PL_U::PL_U() : ServiceFramework("pl:u") { + static const FunctionInfo functions[] = { + {1, &PL_U::GetLoadState, "GetLoadState"}, + {2, &PL_U::GetSize, "GetSize"}, + {3, &PL_U::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"}, + {4, &PL_U::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}}; + RegisterHandlers(functions); + + // Attempt to load shared font data from disk + const std::string filepath{FileUtil::GetUserPath(D_SYSDATA_IDX) + SHARED_FONT}; + FileUtil::CreateFullPath(filepath); // Create path if not already created + FileUtil::IOFile file(filepath, "rb"); + + if (file.IsOpen()) { + // Read shared font data + ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); + shared_font = std::make_shared<std::vector<u8>>(static_cast<size_t>(file.GetSize())); + file.ReadBytes(shared_font->data(), shared_font->size()); + } else { + LOG_WARNING(Service_NS, "Unable to load shared font: %s", filepath.c_str()); + } +} + +void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u32 font_id{rp.Pop<u32>()}; + + LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(static_cast<u32>(LoadState::Done)); +} + +void PL_U::GetSize(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u32 font_id{rp.Pop<u32>()}; + + LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(SHARED_FONT_REGIONS[font_id].size); +} + +void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u32 font_id{rp.Pop<u32>()}; + + LOG_DEBUG(Service_NS, "called, font_id=%d", font_id); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push<u32>(SHARED_FONT_REGIONS[font_id].offset); +} + +void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { + if (shared_font != nullptr) { + // TODO(bunnei): This is a less-than-ideal solution to load a RAM dump of the Switch shared + // font data. This (likely) relies on exact address, size, and offsets from the original + // dump. In the future, we need to replace this with a more robust solution. + + // Map backing memory for the font data + Kernel::g_current_process->vm_manager.MapMemoryBlock(SHARED_FONT_MEM_VADDR, shared_font, 0, + SHARED_FONT_MEM_SIZE, + Kernel::MemoryState::Shared); + + // Create shared font memory object + shared_font_mem = Kernel::SharedMemory::Create( + Kernel::g_current_process, SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite, + Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, + "PL_U:shared_font_mem"); + } + + LOG_DEBUG(Service_NS, "called"); + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(shared_font_mem); +} + +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/ns/pl_u.h b/src/core/hle/service/ns/pl_u.h new file mode 100644 index 000000000..7a4766338 --- /dev/null +++ b/src/core/hle/service/ns/pl_u.h @@ -0,0 +1,33 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include "core/hle/kernel/shared_memory.h" +#include "core/hle/service/service.h" + +namespace Service { +namespace NS { + +class PL_U final : public ServiceFramework<PL_U> { +public: + PL_U(); + ~PL_U() = default; + +private: + void GetLoadState(Kernel::HLERequestContext& ctx); + void GetSize(Kernel::HLERequestContext& ctx); + void GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx); + void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); + + /// Handle to shared memory region designated for a shared font + Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem; + + /// Backing memory for the shared font data + std::shared_ptr<std::vector<u8>> shared_font; +}; + +} // namespace NS +} // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 1dd04a12f..5e6d83729 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -23,6 +23,7 @@ #include "core/hle/service/hid/hid.h" #include "core/hle/service/lm/lm.h" #include "core/hle/service/nifm/nifm.h" +#include "core/hle/service/ns/ns.h" #include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/pctl/pctl.h" #include "core/hle/service/service.h" @@ -182,6 +183,7 @@ void Init() { HID::InstallInterfaces(*SM::g_service_manager); LM::InstallInterfaces(*SM::g_service_manager); NIFM::InstallInterfaces(*SM::g_service_manager); + NS::InstallInterfaces(*SM::g_service_manager); Nvidia::InstallInterfaces(*SM::g_service_manager); PCTL::InstallInterfaces(*SM::g_service_manager); Sockets::InstallInterfaces(*SM::g_service_manager); |