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, LM)                                                                               \ | ||||
|     SUB(Service, NIFM)                                                                             \ | ||||
|     SUB(Service, NS)                                                                               \ | ||||
|     SUB(Service, NVDRV)                                                                            \ | ||||
|     SUB(Service, PCTL)                                                                             \ | ||||
|     SUB(Service, SET)                                                                              \ | ||||
|  | ||||
| @ -57,6 +57,7 @@ enum class Class : ClassType { | ||||
|     Service_HID,       ///< The HID (Human interface device) service
 | ||||
|     Service_LM,        ///< The LM (Logger) service
 | ||||
|     Service_NIFM,      ///< The NIFM (Network interface) service
 | ||||
|     Service_NS,        ///< The NS services
 | ||||
|     Service_NVDRV,     ///< The NVDRV (Nvidia driver) service
 | ||||
|     Service_PCTL,      ///< The PCTL (Parental control) 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_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 | ||||
|  | ||||
| @ -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.
 | ||||
| 
 | ||||
|  | ||||
| @ -186,7 +186,9 @@ public: | ||||
|             {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, | ||||
|             {124, nullptr, "SetNpadJoyAssignmentModeDual"}, | ||||
|             {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, | ||||
|             {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"}, | ||||
|             {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"}, | ||||
|             {206, &Hid::SendVibrationValues, "SendVibrationValues"}, | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
| 
 | ||||
| @ -272,12 +274,25 @@ private: | ||||
|         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() {} | ||||
|  | ||||
							
								
								
									
										16
									
								
								src/core/hle/service/ns/ns.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/core/hle/service/ns/ns.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||
							
								
								
									
										16
									
								
								src/core/hle/service/ns/ns.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/core/hle/service/ns/ns.h
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||
							
								
								
									
										111
									
								
								src/core/hle/service/ns/pl_u.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/core/hle/service/ns/pl_u.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -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
 | ||||
							
								
								
									
										33
									
								
								src/core/hle/service/ns/pl_u.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/core/hle/service/ns/pl_u.h
									
									
									
									
									
										Normal file
									
								
							| @ -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/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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei