summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Subv2016-04-17 21:12:37 -0500
committerGravatar Subv2016-05-12 20:01:20 -0500
commit9005cda66469070d9f1cd844720233e738fef74d (patch)
tree159fbc3e19b4b56ecedaa085a34675a41aeb9fec
parentKernel/Memory: Remove the Shared Memory region from the legacy memory map. (diff)
downloadyuzu-9005cda66469070d9f1cd844720233e738fef74d.tar.gz
yuzu-9005cda66469070d9f1cd844720233e738fef74d.tar.xz
yuzu-9005cda66469070d9f1cd844720233e738fef74d.zip
APT: Implement relocating the shared font to its true address.
-rw-r--r--src/core/hle/service/apt/apt.cpp83
1 files changed, 74 insertions, 9 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index e7b8f5305..ad6ba1fac 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -22,16 +22,73 @@
22namespace Service { 22namespace Service {
23namespace APT { 23namespace APT {
24 24
25// Address used for shared font (as observed on HW) 25/// BCFNT Shared Font file structures
26// TODO(bunnei): This is the hard-coded address where we currently dump the shared font from via 26namespace BCFNT {
27// https://github.com/citra-emu/3dsutils. This is technically a hack, and will not work at any 27struct CFNT {
28// address other than 0x18000000 due to internal pointers in the shared font dump that would need to 28 u8 magic[4];
29// be relocated. This might be fixed by dumping the shared font @ address 0x00000000 and then 29 u16_le endianness;
30// correctly mapping it in Citra, however we still do not understand how the mapping is determined. 30 u16_le header_size;
31static const VAddr SHARED_FONT_VADDR = 0x18000000; 31 u32_le version;
32 u32_le file_size;
33 u32_le num_blocks;
34};
35
36struct FINF {
37 u8 magic[4];
38 u32_le section_size;
39 u8 font_type;
40 u8 line_feed;
41 u16_le alter_char_index;
42 u8 default_width[3];
43 u8 encoding;
44 u32_le tglp_offset;
45 u32_le cwdh_offset;
46 u32_le cmap_offset;
47 u8 height;
48 u8 width;
49 u8 ascent;
50 u8 reserved;
51};
52
53struct TGLP {
54 u8 magic[4];
55 u32_le section_size;
56 u8 cell_width;
57 u8 cell_height;
58 u8 baseline_position;
59 u8 max_character_width;
60 u32_le sheet_size;
61 u16_le num_sheets;
62 u16_le sheet_image_format;
63 u16_le num_columns;
64 u16_le num_rows;
65 u16_le sheet_width;
66 u16_le sheet_height;
67 u32_le sheet_data_offset;
68};
69
70struct CMAP {
71 u8 magic[4];
72 u32_le section_size;
73 u16_le code_begin;
74 u16_le code_end;
75 u16_le mapping_method;
76 u16_le reserved;
77 u32_le next_cmap_offset;
78};
79
80struct CWDH {
81 u8 magic[4];
82 u32_le section_size;
83 u16_le start_index;
84 u16_le end_index;
85 u32_le next_cwdh_offset;
86};
87}
32 88
33/// Handle to shared memory region designated to for shared system font 89/// Handle to shared memory region designated to for shared system font
34static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem; 90static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
91static bool shared_font_relocated = false;
35 92
36static Kernel::SharedPtr<Kernel::Mutex> lock; 93static Kernel::SharedPtr<Kernel::Mutex> lock;
37static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event 94static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
@@ -72,12 +129,19 @@ void Initialize(Service::Interface* self) {
72void GetSharedFont(Service::Interface* self) { 129void GetSharedFont(Service::Interface* self) {
73 u32* cmd_buff = Kernel::GetCommandBuffer(); 130 u32* cmd_buff = Kernel::GetCommandBuffer();
74 131
132 // The shared font has to be relocated to the new address before being passed to the application.
133 VAddr target_address = Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address);
134 // The shared font dumped by 3dsutils (https://github.com/citra-emu/3dsutils) uses this address as base,
135 // so we relocate it from there to our real address.
136 static const VAddr SHARED_FONT_VADDR = 0x18000000;
137 if (!shared_font_relocated)
138 RelocateSharedFont(SHARED_FONT_VADDR, target_address);
75 cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2); 139 cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2);
76 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 140 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
77 // Since the SharedMemory interface doesn't provide the address at which the memory was allocated, 141 // Since the SharedMemory interface doesn't provide the address at which the memory was allocated,
78 // the APT service calculates this address by scanning the entire address space (using svcQueryMemory) 142 // the real APT service calculates this address by scanning the entire address space (using svcQueryMemory)
79 // and searches for an allocation of the same size as the Shared Font. 143 // and searches for an allocation of the same size as the Shared Font.
80 cmd_buff[2] = Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address); 144 cmd_buff[2] = target_address;
81 cmd_buff[3] = IPC::MoveHandleDesc(); 145 cmd_buff[3] = IPC::MoveHandleDesc();
82 cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom(); 146 cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
83} 147}
@@ -447,6 +511,7 @@ void Init() {
447 511
448void Shutdown() { 512void Shutdown() {
449 shared_font_mem = nullptr; 513 shared_font_mem = nullptr;
514 shared_font_relocated = false;
450 lock = nullptr; 515 lock = nullptr;
451 notification_event = nullptr; 516 notification_event = nullptr;
452 parameter_event = nullptr; 517 parameter_event = nullptr;