Merge pull request #195 from bunnei/shared-font
pl_u: Add basic support for shared fonts.
This commit is contained in:
commit
98ffad4303
|
@ -40,6 +40,7 @@ namespace Log {
|
||||||
SUB(Service, HID) \
|
SUB(Service, HID) \
|
||||||
SUB(Service, LM) \
|
SUB(Service, LM) \
|
||||||
SUB(Service, NIFM) \
|
SUB(Service, NIFM) \
|
||||||
|
SUB(Service, NS) \
|
||||||
SUB(Service, NVDRV) \
|
SUB(Service, NVDRV) \
|
||||||
SUB(Service, PCTL) \
|
SUB(Service, PCTL) \
|
||||||
SUB(Service, SET) \
|
SUB(Service, SET) \
|
||||||
|
|
|
@ -57,6 +57,7 @@ enum class Class : ClassType {
|
||||||
Service_HID, ///< The HID (Human interface device) service
|
Service_HID, ///< The HID (Human interface device) service
|
||||||
Service_LM, ///< The LM (Logger) service
|
Service_LM, ///< The LM (Logger) service
|
||||||
Service_NIFM, ///< The NIFM (Network interface) service
|
Service_NIFM, ///< The NIFM (Network interface) service
|
||||||
|
Service_NS, ///< The NS services
|
||||||
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
|
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
|
||||||
Service_PCTL, ///< The PCTL (Parental control) service
|
Service_PCTL, ///< The PCTL (Parental control) service
|
||||||
Service_SET, ///< The SET (Settings) service
|
Service_SET, ///< The SET (Settings) service
|
||||||
|
|
|
@ -124,6 +124,10 @@ add_library(core STATIC
|
||||||
hle/service/nifm/nifm_s.h
|
hle/service/nifm/nifm_s.h
|
||||||
hle/service/nifm/nifm_u.cpp
|
hle/service/nifm/nifm_u.cpp
|
||||||
hle/service/nifm/nifm_u.h
|
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/nvdevice.h
|
||||||
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
||||||
hle/service/nvdrv/devices/nvdisp_disp0.h
|
hle/service/nvdrv/devices/nvdisp_disp0.h
|
||||||
|
|
|
@ -111,13 +111,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||||
return ERR_INVALID_COMBINATION;
|
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.
|
// Error out if the provided permissions are not compatible with what the creator process needs.
|
||||||
if (other_permissions != MemoryPermission::DontCare &&
|
if (other_permissions != MemoryPermission::DontCare &&
|
||||||
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
|
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;
|
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
|
// 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.
|
// can not map it in its own address space unless it was created with addr=0, result 0xD900182C.
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,9 @@ public:
|
||||||
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
|
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
|
||||||
{124, nullptr, "SetNpadJoyAssignmentModeDual"},
|
{124, nullptr, "SetNpadJoyAssignmentModeDual"},
|
||||||
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
|
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
|
||||||
|
{200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
|
||||||
{203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
|
{203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
|
||||||
|
{206, &Hid::SendVibrationValues, "SendVibrationValues"},
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
@ -272,12 +274,25 @@ private:
|
||||||
LOG_WARNING(Service_HID, "(STUBBED) called");
|
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) {
|
void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<IActiveVibrationDeviceList>();
|
rb.PushIpcInterface<IActiveVibrationDeviceList>();
|
||||||
LOG_DEBUG(Service_HID, "called");
|
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() {}
|
void ReloadInputDevices() {}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -23,6 +23,7 @@
|
||||||
#include "core/hle/service/hid/hid.h"
|
#include "core/hle/service/hid/hid.h"
|
||||||
#include "core/hle/service/lm/lm.h"
|
#include "core/hle/service/lm/lm.h"
|
||||||
#include "core/hle/service/nifm/nifm.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/nvdrv/nvdrv.h"
|
||||||
#include "core/hle/service/pctl/pctl.h"
|
#include "core/hle/service/pctl/pctl.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
@ -182,6 +183,7 @@ void Init() {
|
||||||
HID::InstallInterfaces(*SM::g_service_manager);
|
HID::InstallInterfaces(*SM::g_service_manager);
|
||||||
LM::InstallInterfaces(*SM::g_service_manager);
|
LM::InstallInterfaces(*SM::g_service_manager);
|
||||||
NIFM::InstallInterfaces(*SM::g_service_manager);
|
NIFM::InstallInterfaces(*SM::g_service_manager);
|
||||||
|
NS::InstallInterfaces(*SM::g_service_manager);
|
||||||
Nvidia::InstallInterfaces(*SM::g_service_manager);
|
Nvidia::InstallInterfaces(*SM::g_service_manager);
|
||||||
PCTL::InstallInterfaces(*SM::g_service_manager);
|
PCTL::InstallInterfaces(*SM::g_service_manager);
|
||||||
Sockets::InstallInterfaces(*SM::g_service_manager);
|
Sockets::InstallInterfaces(*SM::g_service_manager);
|
||||||
|
|
Reference in New Issue