summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/common_paths.h3
-rw-r--r--src/core/hle/service/apt_u.cpp134
2 files changed, 103 insertions, 34 deletions
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index 95479a529..42e1a29c1 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -58,6 +58,9 @@
58#define DEBUGGER_CONFIG "debugger.ini" 58#define DEBUGGER_CONFIG "debugger.ini"
59#define LOGGER_CONFIG "logger.ini" 59#define LOGGER_CONFIG "logger.ini"
60 60
61// Sys files
62#define SHARED_FONT "shared_font.bin"
63
61// Files in the directory returned by GetUserPath(D_LOGS_IDX) 64// Files in the directory returned by GetUserPath(D_LOGS_IDX)
62#define MAIN_LOG "emu.log" 65#define MAIN_LOG "emu.log"
63 66
diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp
index 4bb05ce40..181763724 100644
--- a/src/core/hle/service/apt_u.cpp
+++ b/src/core/hle/service/apt_u.cpp
@@ -4,10 +4,12 @@
4 4
5 5
6#include "common/common.h" 6#include "common/common.h"
7#include "common/file_util.h"
7 8
8#include "core/hle/hle.h" 9#include "core/hle/hle.h"
9#include "core/hle/kernel/event.h" 10#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/mutex.h" 11#include "core/hle/kernel/mutex.h"
12#include "core/hle/kernel/shared_memory.h"
11#include "apt_u.h" 13#include "apt_u.h"
12 14
13//////////////////////////////////////////////////////////////////////////////////////////////////// 15////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -15,7 +17,19 @@
15 17
16namespace APT_U { 18namespace APT_U {
17 19
20// Address used for shared font (as observed on HW)
21// TODO(bunnei): This is the hard-coded address where we currently dump the shared font from via
22// https://github.com/citra-emu/3dsutils. This is technically a hack, and will not work at any
23// address other than 0x18000000 due to internal pointers in the shared font dump that would need to
24// be relocated. This might be fixed by dumping the shared font @ address 0x00000000 and then
25// correctly mapping it in Citra, however we still do not understand how the mapping is determined.
26static const VAddr SHARED_FONT_VADDR = 0x18000000;
27
28// Handle to shared memory region designated to for shared system font
29static Handle shared_font_mem = 0;
30
18static Handle lock_handle = 0; 31static Handle lock_handle = 0;
32static std::vector<u8> shared_font;
19 33
20/// Signals used by APT functions 34/// Signals used by APT functions
21enum class SignalType : u32 { 35enum class SignalType : u32 {
@@ -84,18 +98,18 @@ void InquireNotification(Service::Interface* self) {
84 * state so that this command will return an error if this command is used again if parameters were 98 * state so that this command will return an error if this command is used again if parameters were
85 * not set again. This is called when the second Initialize event is triggered. It returns a signal 99 * not set again. This is called when the second Initialize event is triggered. It returns a signal
86 * type indicating why it was triggered. 100 * type indicating why it was triggered.
87 * Inputs: 101 * Inputs:
88 * 1 : AppID 102 * 1 : AppID
89 * 2 : Parameter buffer size, max size is 0x1000 103 * 2 : Parameter buffer size, max size is 0x1000
90 * Outputs: 104 * Outputs:
91 * 1 : Result of function, 0 on success, otherwise error code 105 * 1 : Result of function, 0 on success, otherwise error code
92 * 2 : Unknown, for now assume AppID of the process which sent these parameters 106 * 2 : Unknown, for now assume AppID of the process which sent these parameters
93 * 3 : Unknown, for now assume Signal type 107 * 3 : Unknown, for now assume Signal type
94 * 4 : Actual parameter buffer size, this is <= to the the input size 108 * 4 : Actual parameter buffer size, this is <= to the the input size
95 * 5 : Value 109 * 5 : Value
96 * 6 : Handle from the source process which set the parameters, likely used for shared memory 110 * 6 : Handle from the source process which set the parameters, likely used for shared memory
97 * 7 : Size 111 * 7 : Size
98 * 8 : Output parameter buffer ptr 112 * 8 : Output parameter buffer ptr
99 */ 113 */
100void ReceiveParameter(Service::Interface* self) { 114void ReceiveParameter(Service::Interface* self) {
101 u32* cmd_buff = Service::GetCommandBuffer(); 115 u32* cmd_buff = Service::GetCommandBuffer();
@@ -115,18 +129,18 @@ void ReceiveParameter(Service::Interface* self) {
115 * APT_U::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter 129 * APT_U::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter
116 * (except for the word value prior to the output handle), except this will not clear the flag 130 * (except for the word value prior to the output handle), except this will not clear the flag
117 * (except when responseword[3]==8 || responseword[3]==9) in NS state. 131 * (except when responseword[3]==8 || responseword[3]==9) in NS state.
118 * Inputs: 132 * Inputs:
119 * 1 : AppID 133 * 1 : AppID
120 * 2 : Parameter buffer size, max size is 0x1000 134 * 2 : Parameter buffer size, max size is 0x1000
121 * Outputs: 135 * Outputs:
122 * 1 : Result of function, 0 on success, otherwise error code 136 * 1 : Result of function, 0 on success, otherwise error code
123 * 2 : Unknown, for now assume AppID of the process which sent these parameters 137 * 2 : Unknown, for now assume AppID of the process which sent these parameters
124 * 3 : Unknown, for now assume Signal type 138 * 3 : Unknown, for now assume Signal type
125 * 4 : Actual parameter buffer size, this is <= to the the input size 139 * 4 : Actual parameter buffer size, this is <= to the the input size
126 * 5 : Value 140 * 5 : Value
127 * 6 : Handle from the source process which set the parameters, likely used for shared memory 141 * 6 : Handle from the source process which set the parameters, likely used for shared memory
128 * 7 : Size 142 * 7 : Size
129 * 8 : Output parameter buffer ptr 143 * 8 : Output parameter buffer ptr
130 */ 144 */
131void GlanceParameter(Service::Interface* self) { 145void GlanceParameter(Service::Interface* self) {
132 u32* cmd_buff = Service::GetCommandBuffer(); 146 u32* cmd_buff = Service::GetCommandBuffer();
@@ -146,14 +160,14 @@ void GlanceParameter(Service::Interface* self) {
146 160
147/** 161/**
148 * APT_U::AppletUtility service function 162 * APT_U::AppletUtility service function
149 * Inputs: 163 * Inputs:
150 * 1 : Unknown, but clearly used for something 164 * 1 : Unknown, but clearly used for something
151 * 2 : Buffer 1 size (purpose is unknown) 165 * 2 : Buffer 1 size (purpose is unknown)
152 * 3 : Buffer 2 size (purpose is unknown) 166 * 3 : Buffer 2 size (purpose is unknown)
153 * 5 : Buffer 1 address (purpose is unknown) 167 * 5 : Buffer 1 address (purpose is unknown)
154 * 65 : Buffer 2 address (purpose is unknown) 168 * 65 : Buffer 2 address (purpose is unknown)
155 * Outputs: 169 * Outputs:
156 * 1 : Result of function, 0 on success, otherwise error code 170 * 1 : Result of function, 0 on success, otherwise error code
157 */ 171 */
158void AppletUtility(Service::Interface* self) { 172void AppletUtility(Service::Interface* self) {
159 u32* cmd_buff = Service::GetCommandBuffer(); 173 u32* cmd_buff = Service::GetCommandBuffer();
@@ -172,6 +186,34 @@ void AppletUtility(Service::Interface* self) {
172 buffer1_addr, buffer2_addr); 186 buffer1_addr, buffer2_addr);
173} 187}
174 188
189/**
190 * APT_U::GetSharedFont service function
191 * Outputs:
192 * 1 : Result of function, 0 on success, otherwise error code
193 * 2 : Virtual address of where shared font will be loaded in memory
194 * 4 : Handle to shared font memory
195 */
196void GetSharedFont(Service::Interface* self) {
197 DEBUG_LOG(KERNEL, "called");
198
199 u32* cmd_buff = Service::GetCommandBuffer();
200
201 if (!shared_font.empty()) {
202 // TODO(bunnei): This function shouldn't copy the shared font every time it's called.
203 // Instead, it should probably map the shared font as RO memory. We don't currently have
204 // an easy way to do this, but the copy should be sufficient for now.
205 memcpy(Memory::GetPointer(SHARED_FONT_VADDR), shared_font.data(), shared_font.size());
206
207 cmd_buff[0] = 0x00440082;
208 cmd_buff[1] = 0; // No error
209 cmd_buff[2] = SHARED_FONT_VADDR;
210 cmd_buff[4] = shared_font_mem;
211 } else {
212 cmd_buff[1] = -1; // Generic error (not really possible to verify this on hardware)
213 ERROR_LOG(KERNEL, "called, but %s has not been loaded!", SHARED_FONT);
214 }
215}
216
175const Interface::FunctionInfo FunctionTable[] = { 217const Interface::FunctionInfo FunctionTable[] = {
176 {0x00010040, GetLockHandle, "GetLockHandle"}, 218 {0x00010040, GetLockHandle, "GetLockHandle"},
177 {0x00020080, Initialize, "Initialize"}, 219 {0x00020080, Initialize, "Initialize"},
@@ -240,7 +282,7 @@ const Interface::FunctionInfo FunctionTable[] = {
240 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, 282 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
241 {0x00420080, nullptr, "SleepSystem"}, 283 {0x00420080, nullptr, "SleepSystem"},
242 {0x00430040, nullptr, "NotifyToWait"}, 284 {0x00430040, nullptr, "NotifyToWait"},
243 {0x00440000, nullptr, "GetSharedFont"}, 285 {0x00440000, GetSharedFont, "GetSharedFont"},
244 {0x00450040, nullptr, "GetWirelessRebootInfo"}, 286 {0x00450040, nullptr, "GetWirelessRebootInfo"},
245 {0x00460104, nullptr, "Wrap"}, 287 {0x00460104, nullptr, "Wrap"},
246 {0x00470104, nullptr, "Unwrap"}, 288 {0x00470104, nullptr, "Unwrap"},
@@ -259,9 +301,33 @@ const Interface::FunctionInfo FunctionTable[] = {
259// Interface class 301// Interface class
260 302
261Interface::Interface() { 303Interface::Interface() {
262 Register(FunctionTable, ARRAY_SIZE(FunctionTable)); 304 // Load the shared system font (if available).
305 // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header
306 // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided
307 // a homebrew app to do this: https://github.com/citra-emu/3dsutils. Put the resulting file
308 // "shared_font.bin" in the Citra "sysdata" directory.
309
310 shared_font.clear();
311 std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + SHARED_FONT;
312
313 FileUtil::CreateFullPath(filepath); // Create path if not already created
314 FileUtil::IOFile file(filepath, "rb");
315
316 if (file.IsOpen()) {
317 // Read shared font data
318 shared_font.resize(file.GetSize());
319 file.ReadBytes(shared_font.data(), file.GetSize());
320
321 // Create shared font memory object
322 shared_font_mem = Kernel::CreateSharedMemory("APT_U:shared_font_mem");
323 } else {
324 WARN_LOG(KERNEL, "Unable to load shared font: %s", filepath.c_str());
325 shared_font_mem = 0;
326 }
263 327
264 lock_handle = 0; 328 lock_handle = 0;
329
330 Register(FunctionTable, ARRAY_SIZE(FunctionTable));
265} 331}
266 332
267Interface::~Interface() { 333Interface::~Interface() {