summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-04-18 00:32:01 -0700
committerGravatar GitHub2017-04-18 00:32:01 -0700
commit941a3dda8a0505dc575cb71e1fc0ef4c1a13eca2 (patch)
treec9642c7f67f91033329cec7cc9e09d71f286c06d /src
parentMerge pull request #2667 from wwylele/button_from_axis (diff)
parentldr_ro: use IPC helper (diff)
downloadyuzu-941a3dda8a0505dc575cb71e1fc0ef4c1a13eca2.tar.gz
yuzu-941a3dda8a0505dc575cb71e1fc0ef4c1a13eca2.tar.xz
yuzu-941a3dda8a0505dc575cb71e1fc0ef4c1a13eca2.zip
Merge pull request #2532 from wwylele/ldrro-ipc
ldr_ro: use IPC helper
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/ldr_ro/ldr_ro.cpp331
1 files changed, 138 insertions, 193 deletions
diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp
index 7af76676b..d1e6d869f 100644
--- a/src/core/hle/service/ldr_ro/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp
@@ -40,9 +40,6 @@ static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08
40static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D 40static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D
41 ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, 41 ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState,
42 ErrorLevel::Permanent); 42 ErrorLevel::Permanent);
43static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830
44 ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
45 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
46 43
47static MemorySynchronizer memory_synchronizer; 44static MemorySynchronizer memory_synchronizer;
48 45
@@ -71,66 +68,61 @@ static bool VerifyBufferState(VAddr buffer_ptr, u32 size) {
71 * 1 : Result of function, 0 on success, otherwise error code 68 * 1 : Result of function, 0 on success, otherwise error code
72 */ 69 */
73static void Initialize(Interface* self) { 70static void Initialize(Interface* self) {
74 u32* cmd_buff = Kernel::GetCommandBuffer(); 71 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x01, 3, 2);
75 VAddr crs_buffer_ptr = cmd_buff[1]; 72 VAddr crs_buffer_ptr = rp.Pop<u32>();
76 u32 crs_size = cmd_buff[2]; 73 u32 crs_size = rp.Pop<u32>();
77 VAddr crs_address = cmd_buff[3]; 74 VAddr crs_address = rp.Pop<u32>();
78 u32 descriptor = cmd_buff[4]; 75 // TODO (wwylele): RO service checks the descriptor here and return error 0xD9001830 for
79 u32 process = cmd_buff[5]; 76 // incorrect descriptor. This error return should be probably built in IPC::RequestParser.
80 77 // All other service functions below have the same issue.
81 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, " 78 Kernel::Handle process = rp.PopHandle();
82 "descriptor=0x%08X, process=0x%08X", 79
83 crs_buffer_ptr, crs_address, crs_size, descriptor, process); 80 LOG_DEBUG(Service_LDR,
84 81 "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, process=0x%08X",
85 if (descriptor != 0) { 82 crs_buffer_ptr, crs_address, crs_size, process);
86 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
87 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
88 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
89 return;
90 }
91 83
92 cmd_buff[0] = IPC::MakeHeader(1, 1, 0); 84 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
93 85
94 if (loaded_crs != 0) { 86 if (loaded_crs != 0) {
95 LOG_ERROR(Service_LDR, "Already initialized"); 87 LOG_ERROR(Service_LDR, "Already initialized");
96 cmd_buff[1] = ERROR_ALREADY_INITIALIZED.raw; 88 rb.Push(ERROR_ALREADY_INITIALIZED);
97 return; 89 return;
98 } 90 }
99 91
100 if (crs_size < CRO_HEADER_SIZE) { 92 if (crs_size < CRO_HEADER_SIZE) {
101 LOG_ERROR(Service_LDR, "CRS is too small"); 93 LOG_ERROR(Service_LDR, "CRS is too small");
102 cmd_buff[1] = ERROR_BUFFER_TOO_SMALL.raw; 94 rb.Push(ERROR_BUFFER_TOO_SMALL);
103 return; 95 return;
104 } 96 }
105 97
106 if (crs_buffer_ptr & Memory::PAGE_MASK) { 98 if (crs_buffer_ptr & Memory::PAGE_MASK) {
107 LOG_ERROR(Service_LDR, "CRS original address is not aligned"); 99 LOG_ERROR(Service_LDR, "CRS original address is not aligned");
108 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 100 rb.Push(ERROR_MISALIGNED_ADDRESS);
109 return; 101 return;
110 } 102 }
111 103
112 if (crs_address & Memory::PAGE_MASK) { 104 if (crs_address & Memory::PAGE_MASK) {
113 LOG_ERROR(Service_LDR, "CRS mapping address is not aligned"); 105 LOG_ERROR(Service_LDR, "CRS mapping address is not aligned");
114 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 106 rb.Push(ERROR_MISALIGNED_ADDRESS);
115 return; 107 return;
116 } 108 }
117 109
118 if (crs_size & Memory::PAGE_MASK) { 110 if (crs_size & Memory::PAGE_MASK) {
119 LOG_ERROR(Service_LDR, "CRS size is not aligned"); 111 LOG_ERROR(Service_LDR, "CRS size is not aligned");
120 cmd_buff[1] = ERROR_MISALIGNED_SIZE.raw; 112 rb.Push(ERROR_MISALIGNED_SIZE);
121 return; 113 return;
122 } 114 }
123 115
124 if (!VerifyBufferState(crs_buffer_ptr, crs_size)) { 116 if (!VerifyBufferState(crs_buffer_ptr, crs_size)) {
125 LOG_ERROR(Service_LDR, "CRS original buffer is in invalid state"); 117 LOG_ERROR(Service_LDR, "CRS original buffer is in invalid state");
126 cmd_buff[1] = ERROR_INVALID_MEMORY_STATE.raw; 118 rb.Push(ERROR_INVALID_MEMORY_STATE);
127 return; 119 return;
128 } 120 }
129 121
130 if (crs_address < Memory::PROCESS_IMAGE_VADDR || 122 if (crs_address < Memory::PROCESS_IMAGE_VADDR ||
131 crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) { 123 crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) {
132 LOG_ERROR(Service_LDR, "CRS mapping address is not in the process image region"); 124 LOG_ERROR(Service_LDR, "CRS mapping address is not in the process image region");
133 cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; 125 rb.Push(ERROR_ILLEGAL_ADDRESS);
134 return; 126 return;
135 } 127 }
136 128
@@ -145,7 +137,7 @@ static void Initialize(Interface* self) {
145 .Code(); 137 .Code();
146 if (result.IsError()) { 138 if (result.IsError()) {
147 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); 139 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw);
148 cmd_buff[1] = result.raw; 140 rb.Push(result);
149 return; 141 return;
150 } 142 }
151 143
@@ -153,7 +145,7 @@ static void Initialize(Interface* self) {
153 Kernel::VMAPermission::Read); 145 Kernel::VMAPermission::Read);
154 if (result.IsError()) { 146 if (result.IsError()) {
155 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); 147 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw);
156 cmd_buff[1] = result.raw; 148 rb.Push(result);
157 return; 149 return;
158 } 150 }
159 151
@@ -172,7 +164,7 @@ static void Initialize(Interface* self) {
172 result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true); 164 result = crs.Rebase(0, crs_size, 0, 0, 0, 0, true);
173 if (result.IsError()) { 165 if (result.IsError()) {
174 LOG_ERROR(Service_LDR, "Error rebasing CRS 0x%08X", result.raw); 166 LOG_ERROR(Service_LDR, "Error rebasing CRS 0x%08X", result.raw);
175 cmd_buff[1] = result.raw; 167 rb.Push(result);
176 return; 168 return;
177 } 169 }
178 170
@@ -180,7 +172,7 @@ static void Initialize(Interface* self) {
180 172
181 loaded_crs = crs_address; 173 loaded_crs = crs_address;
182 174
183 cmd_buff[1] = RESULT_SUCCESS.raw; 175 rb.Push(RESULT_SUCCESS);
184} 176}
185 177
186/** 178/**
@@ -196,25 +188,17 @@ static void Initialize(Interface* self) {
196 * 1 : Result of function, 0 on success, otherwise error code 188 * 1 : Result of function, 0 on success, otherwise error code
197 */ 189 */
198static void LoadCRR(Interface* self) { 190static void LoadCRR(Interface* self) {
199 u32* cmd_buff = Kernel::GetCommandBuffer(); 191 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x02, 2, 2);
200 u32 crr_buffer_ptr = cmd_buff[1]; 192 VAddr crr_buffer_ptr = rp.Pop<u32>();
201 u32 crr_size = cmd_buff[2]; 193 u32 crr_size = rp.Pop<u32>();
202 u32 descriptor = cmd_buff[3]; 194 Kernel::Handle process = rp.PopHandle();
203 u32 process = cmd_buff[4];
204
205 if (descriptor != 0) {
206 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
207 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
208 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
209 return;
210 }
211 195
212 cmd_buff[0] = IPC::MakeHeader(2, 1, 0); 196 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
213 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 197 rb.Push(RESULT_SUCCESS);
214 198
215 LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, " 199 LOG_WARNING(Service_LDR,
216 "descriptor=0x%08X, process=0x%08X", 200 "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, process=0x%08X",
217 crr_buffer_ptr, crr_size, descriptor, process); 201 crr_buffer_ptr, crr_size, process);
218} 202}
219 203
220/** 204/**
@@ -229,24 +213,15 @@ static void LoadCRR(Interface* self) {
229 * 1 : Result of function, 0 on success, otherwise error code 213 * 1 : Result of function, 0 on success, otherwise error code
230 */ 214 */
231static void UnloadCRR(Interface* self) { 215static void UnloadCRR(Interface* self) {
232 u32* cmd_buff = Kernel::GetCommandBuffer(); 216 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x03, 1, 2);
233 u32 crr_buffer_ptr = cmd_buff[1]; 217 u32 crr_buffer_ptr = rp.Pop<u32>();
234 u32 descriptor = cmd_buff[2]; 218 Kernel::Handle process = rp.PopHandle();
235 u32 process = cmd_buff[3];
236
237 if (descriptor != 0) {
238 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
239 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
240 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
241 return;
242 }
243 219
244 cmd_buff[0] = IPC::MakeHeader(3, 1, 0); 220 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
245 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 221 rb.Push(RESULT_SUCCESS);
246 222
247 LOG_WARNING(Service_LDR, 223 LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, process=0x%08X",
248 "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", 224 crr_buffer_ptr, process);
249 crr_buffer_ptr, descriptor, process);
250} 225}
251 226
252/** 227/**
@@ -276,87 +251,85 @@ static void UnloadCRR(Interface* self) {
276 * There is a dispatcher template below. 251 * There is a dispatcher template below.
277 */ 252 */
278static void LoadCRO(Interface* self, bool link_on_load_bug_fix) { 253static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
279 u32* cmd_buff = Kernel::GetCommandBuffer(); 254 IPC::RequestParser rp(Kernel::GetCommandBuffer(), link_on_load_bug_fix ? 0x09 : 0x04, 11, 2);
280 VAddr cro_buffer_ptr = cmd_buff[1]; 255 VAddr cro_buffer_ptr = rp.Pop<u32>();
281 VAddr cro_address = cmd_buff[2]; 256 VAddr cro_address = rp.Pop<u32>();
282 u32 cro_size = cmd_buff[3]; 257 u32 cro_size = rp.Pop<u32>();
283 VAddr data_segment_address = cmd_buff[4]; 258 VAddr data_segment_address = rp.Pop<u32>();
284 u32 zero = cmd_buff[5]; 259 u32 zero = rp.Pop<u32>();
285 u32 data_segment_size = cmd_buff[6]; 260 u32 data_segment_size = rp.Pop<u32>();
286 u32 bss_segment_address = cmd_buff[7]; 261 u32 bss_segment_address = rp.Pop<u32>();
287 u32 bss_segment_size = cmd_buff[8]; 262 u32 bss_segment_size = rp.Pop<u32>();
288 bool auto_link = (cmd_buff[9] & 0xFF) != 0; 263 bool auto_link = rp.Pop<bool>();
289 u32 fix_level = cmd_buff[10]; 264 u32 fix_level = rp.Pop<u32>();
290 VAddr crr_address = cmd_buff[11]; 265 VAddr crr_address = rp.Pop<u32>();
291 u32 descriptor = cmd_buff[12]; 266 Kernel::Handle process = rp.PopHandle();
292 u32 process = cmd_buff[13]; 267
293 268 LOG_DEBUG(Service_LDR, "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, "
294 LOG_DEBUG(Service_LDR, 269 "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, "
295 "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, " 270 "bss_segment_address=0x%08X, bss_segment_size=0x%X, auto_link=%s, "
296 "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, " 271 "fix_level=%d, crr_address=0x%08X, process=0x%08X",
297 "bss_segment_address=0x%08X, bss_segment_size=0x%X, "
298 "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X",
299 link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size, 272 link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size,
300 data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size, 273 data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size,
301 auto_link ? "true" : "false", fix_level, crr_address, descriptor, process); 274 auto_link ? "true" : "false", fix_level, crr_address, process);
302
303 if (descriptor != 0) {
304 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
305 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
306 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
307 return;
308 }
309 275
310 cmd_buff[0] = IPC::MakeHeader(link_on_load_bug_fix ? 9 : 4, 2, 0); 276 IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
311 277
312 if (loaded_crs == 0) { 278 if (loaded_crs == 0) {
313 LOG_ERROR(Service_LDR, "Not initialized"); 279 LOG_ERROR(Service_LDR, "Not initialized");
314 cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; 280 rb.Push(ERROR_NOT_INITIALIZED);
281 rb.Push<u32>(0);
315 return; 282 return;
316 } 283 }
317 284
318 if (cro_size < CRO_HEADER_SIZE) { 285 if (cro_size < CRO_HEADER_SIZE) {
319 LOG_ERROR(Service_LDR, "CRO too small"); 286 LOG_ERROR(Service_LDR, "CRO too small");
320 cmd_buff[1] = ERROR_BUFFER_TOO_SMALL.raw; 287 rb.Push(ERROR_BUFFER_TOO_SMALL);
288 rb.Push<u32>(0);
321 return; 289 return;
322 } 290 }
323 291
324 if (cro_buffer_ptr & Memory::PAGE_MASK) { 292 if (cro_buffer_ptr & Memory::PAGE_MASK) {
325 LOG_ERROR(Service_LDR, "CRO original address is not aligned"); 293 LOG_ERROR(Service_LDR, "CRO original address is not aligned");
326 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 294 rb.Push(ERROR_MISALIGNED_ADDRESS);
295 rb.Push<u32>(0);
327 return; 296 return;
328 } 297 }
329 298
330 if (cro_address & Memory::PAGE_MASK) { 299 if (cro_address & Memory::PAGE_MASK) {
331 LOG_ERROR(Service_LDR, "CRO mapping address is not aligned"); 300 LOG_ERROR(Service_LDR, "CRO mapping address is not aligned");
332 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 301 rb.Push(ERROR_MISALIGNED_ADDRESS);
302 rb.Push<u32>(0);
333 return; 303 return;
334 } 304 }
335 305
336 if (cro_size & Memory::PAGE_MASK) { 306 if (cro_size & Memory::PAGE_MASK) {
337 LOG_ERROR(Service_LDR, "CRO size is not aligned"); 307 LOG_ERROR(Service_LDR, "CRO size is not aligned");
338 cmd_buff[1] = ERROR_MISALIGNED_SIZE.raw; 308 rb.Push(ERROR_MISALIGNED_SIZE);
309 rb.Push<u32>(0);
339 return; 310 return;
340 } 311 }
341 312
342 if (!VerifyBufferState(cro_buffer_ptr, cro_size)) { 313 if (!VerifyBufferState(cro_buffer_ptr, cro_size)) {
343 LOG_ERROR(Service_LDR, "CRO original buffer is in invalid state"); 314 LOG_ERROR(Service_LDR, "CRO original buffer is in invalid state");
344 cmd_buff[1] = ERROR_INVALID_MEMORY_STATE.raw; 315 rb.Push(ERROR_INVALID_MEMORY_STATE);
316 rb.Push<u32>(0);
345 return; 317 return;
346 } 318 }
347 319
348 if (cro_address < Memory::PROCESS_IMAGE_VADDR || 320 if (cro_address < Memory::PROCESS_IMAGE_VADDR ||
349 cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) { 321 cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) {
350 LOG_ERROR(Service_LDR, "CRO mapping address is not in the process image region"); 322 LOG_ERROR(Service_LDR, "CRO mapping address is not in the process image region");
351 cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; 323 rb.Push(ERROR_ILLEGAL_ADDRESS);
324 rb.Push<u32>(0);
352 return; 325 return;
353 } 326 }
354 327
355 if (zero) { 328 if (zero) {
356 LOG_ERROR(Service_LDR, "Zero is not zero %d", zero); 329 LOG_ERROR(Service_LDR, "Zero is not zero %d", zero);
357 cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO, 330 rb.Push(ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO,
358 ErrorSummary::Internal, ErrorLevel::Usage) 331 ErrorSummary::Internal, ErrorLevel::Usage));
359 .raw; 332 rb.Push<u32>(0);
360 return; 333 return;
361 } 334 }
362 335
@@ -371,7 +344,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
371 .Code(); 344 .Code();
372 if (result.IsError()) { 345 if (result.IsError()) {
373 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); 346 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw);
374 cmd_buff[1] = result.raw; 347 rb.Push(result);
348 rb.Push<u32>(0);
375 return; 349 return;
376 } 350 }
377 351
@@ -380,7 +354,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
380 if (result.IsError()) { 354 if (result.IsError()) {
381 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); 355 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw);
382 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 356 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
383 cmd_buff[1] = result.raw; 357 rb.Push(result);
358 rb.Push<u32>(0);
384 return; 359 return;
385 } 360 }
386 361
@@ -400,7 +375,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
400 if (result.IsError()) { 375 if (result.IsError()) {
401 LOG_ERROR(Service_LDR, "Error verifying CRO in CRR %08X", result.raw); 376 LOG_ERROR(Service_LDR, "Error verifying CRO in CRR %08X", result.raw);
402 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 377 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
403 cmd_buff[1] = result.raw; 378 rb.Push(result);
379 rb.Push<u32>(0);
404 return; 380 return;
405 } 381 }
406 382
@@ -409,7 +385,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
409 if (result.IsError()) { 385 if (result.IsError()) {
410 LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw); 386 LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw);
411 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 387 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
412 cmd_buff[1] = result.raw; 388 rb.Push(result);
389 rb.Push<u32>(0);
413 return; 390 return;
414 } 391 }
415 392
@@ -417,7 +394,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
417 if (result.IsError()) { 394 if (result.IsError()) {
418 LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw); 395 LOG_ERROR(Service_LDR, "Error linking CRO %08X", result.raw);
419 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 396 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
420 cmd_buff[1] = result.raw; 397 rb.Push(result);
398 rb.Push<u32>(0);
421 return; 399 return;
422 } 400 }
423 401
@@ -435,7 +413,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
435 if (result.IsError()) { 413 if (result.IsError()) {
436 LOG_ERROR(Service_LDR, "Error unmapping memory block %08X", result.raw); 414 LOG_ERROR(Service_LDR, "Error unmapping memory block %08X", result.raw);
437 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 415 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
438 cmd_buff[1] = result.raw; 416 rb.Push(result);
417 rb.Push<u32>(0);
439 return; 418 return;
440 } 419 }
441 } 420 }
@@ -453,7 +432,8 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
453 if (result.IsError()) { 432 if (result.IsError()) {
454 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); 433 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw);
455 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, fix_size); 434 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, fix_size);
456 cmd_buff[1] = result.raw; 435 rb.Push(result);
436 rb.Push<u32>(0);
457 return; 437 return;
458 } 438 }
459 } 439 }
@@ -463,8 +443,7 @@ static void LoadCRO(Interface* self, bool link_on_load_bug_fix) {
463 LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(), 443 LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(),
464 cro_address, cro_address + fix_size); 444 cro_address, cro_address + fix_size);
465 445
466 cmd_buff[1] = RESULT_SUCCESS.raw; 446 rb.Push(RESULT_SUCCESS, fix_size);
467 cmd_buff[2] = fix_size;
468} 447}
469 448
470template <bool link_on_load_bug_fix> 449template <bool link_on_load_bug_fix>
@@ -486,43 +465,35 @@ static void LoadCRO(Interface* self) {
486 * 1 : Result of function, 0 on success, otherwise error code 465 * 1 : Result of function, 0 on success, otherwise error code
487 */ 466 */
488static void UnloadCRO(Interface* self) { 467static void UnloadCRO(Interface* self) {
489 u32* cmd_buff = Kernel::GetCommandBuffer(); 468 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x05, 3, 2);
490 VAddr cro_address = cmd_buff[1]; 469 VAddr cro_address = rp.Pop<u32>();
491 u32 zero = cmd_buff[2]; 470 u32 zero = rp.Pop<u32>();
492 VAddr cro_buffer_ptr = cmd_buff[3]; 471 VAddr cro_buffer_ptr = rp.Pop<u32>();
493 u32 descriptor = cmd_buff[4]; 472 Kernel::Handle process = rp.PopHandle();
494 u32 process = cmd_buff[5]; 473
495 474 LOG_DEBUG(Service_LDR,
496 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, " 475 "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, process=0x%08X",
497 "descriptor=0x%08X, process=0x%08X", 476 cro_address, zero, cro_buffer_ptr, process);
498 cro_address, zero, cro_buffer_ptr, descriptor, process);
499
500 if (descriptor != 0) {
501 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
502 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
503 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
504 return;
505 }
506 477
507 CROHelper cro(cro_address); 478 CROHelper cro(cro_address);
508 479
509 cmd_buff[0] = IPC::MakeHeader(5, 1, 0); 480 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
510 481
511 if (loaded_crs == 0) { 482 if (loaded_crs == 0) {
512 LOG_ERROR(Service_LDR, "Not initialized"); 483 LOG_ERROR(Service_LDR, "Not initialized");
513 cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; 484 rb.Push(ERROR_NOT_INITIALIZED);
514 return; 485 return;
515 } 486 }
516 487
517 if (cro_address & Memory::PAGE_MASK) { 488 if (cro_address & Memory::PAGE_MASK) {
518 LOG_ERROR(Service_LDR, "CRO address is not aligned"); 489 LOG_ERROR(Service_LDR, "CRO address is not aligned");
519 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 490 rb.Push(ERROR_MISALIGNED_ADDRESS);
520 return; 491 return;
521 } 492 }
522 493
523 if (!cro.IsLoaded()) { 494 if (!cro.IsLoaded()) {
524 LOG_ERROR(Service_LDR, "Invalid or not loaded CRO"); 495 LOG_ERROR(Service_LDR, "Invalid or not loaded CRO");
525 cmd_buff[1] = ERROR_NOT_LOADED.raw; 496 rb.Push(ERROR_NOT_LOADED);
526 return; 497 return;
527 } 498 }
528 499
@@ -535,7 +506,7 @@ static void UnloadCRO(Interface* self) {
535 ResultCode result = cro.Unlink(loaded_crs); 506 ResultCode result = cro.Unlink(loaded_crs);
536 if (result.IsError()) { 507 if (result.IsError()) {
537 LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw); 508 LOG_ERROR(Service_LDR, "Error unlinking CRO %08X", result.raw);
538 cmd_buff[1] = result.raw; 509 rb.Push(result);
539 return; 510 return;
540 } 511 }
541 512
@@ -545,7 +516,7 @@ static void UnloadCRO(Interface* self) {
545 result = cro.ClearRelocations(); 516 result = cro.ClearRelocations();
546 if (result.IsError()) { 517 if (result.IsError()) {
547 LOG_ERROR(Service_LDR, "Error clearing relocations %08X", result.raw); 518 LOG_ERROR(Service_LDR, "Error clearing relocations %08X", result.raw);
548 cmd_buff[1] = result.raw; 519 rb.Push(result);
549 return; 520 return;
550 } 521 }
551 } 522 }
@@ -565,7 +536,7 @@ static void UnloadCRO(Interface* self) {
565 536
566 Core::CPU().ClearInstructionCache(); 537 Core::CPU().ClearInstructionCache();
567 538
568 cmd_buff[1] = result.raw; 539 rb.Push(result);
569} 540}
570 541
571/** 542/**
@@ -580,40 +551,31 @@ static void UnloadCRO(Interface* self) {
580 * 1 : Result of function, 0 on success, otherwise error code 551 * 1 : Result of function, 0 on success, otherwise error code
581 */ 552 */
582static void LinkCRO(Interface* self) { 553static void LinkCRO(Interface* self) {
583 u32* cmd_buff = Kernel::GetCommandBuffer(); 554 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x06, 1, 2);
584 VAddr cro_address = cmd_buff[1]; 555 VAddr cro_address = rp.Pop<u32>();
585 u32 descriptor = cmd_buff[2]; 556 Kernel::Handle process = rp.PopHandle();
586 u32 process = cmd_buff[3]; 557
587 558 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, process=0x%08X", cro_address, process);
588 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X",
589 cro_address, descriptor, process);
590
591 if (descriptor != 0) {
592 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
593 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
594 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
595 return;
596 }
597 559
598 CROHelper cro(cro_address); 560 CROHelper cro(cro_address);
599 561
600 cmd_buff[0] = IPC::MakeHeader(6, 1, 0); 562 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
601 563
602 if (loaded_crs == 0) { 564 if (loaded_crs == 0) {
603 LOG_ERROR(Service_LDR, "Not initialized"); 565 LOG_ERROR(Service_LDR, "Not initialized");
604 cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; 566 rb.Push(ERROR_NOT_INITIALIZED);
605 return; 567 return;
606 } 568 }
607 569
608 if (cro_address & Memory::PAGE_MASK) { 570 if (cro_address & Memory::PAGE_MASK) {
609 LOG_ERROR(Service_LDR, "CRO address is not aligned"); 571 LOG_ERROR(Service_LDR, "CRO address is not aligned");
610 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 572 rb.Push(ERROR_MISALIGNED_ADDRESS);
611 return; 573 return;
612 } 574 }
613 575
614 if (!cro.IsLoaded()) { 576 if (!cro.IsLoaded()) {
615 LOG_ERROR(Service_LDR, "Invalid or not loaded CRO"); 577 LOG_ERROR(Service_LDR, "Invalid or not loaded CRO");
616 cmd_buff[1] = ERROR_NOT_LOADED.raw; 578 rb.Push(ERROR_NOT_LOADED);
617 return; 579 return;
618 } 580 }
619 581
@@ -627,7 +589,7 @@ static void LinkCRO(Interface* self) {
627 memory_synchronizer.SynchronizeOriginalMemory(); 589 memory_synchronizer.SynchronizeOriginalMemory();
628 Core::CPU().ClearInstructionCache(); 590 Core::CPU().ClearInstructionCache();
629 591
630 cmd_buff[1] = result.raw; 592 rb.Push(result);
631} 593}
632 594
633/** 595/**
@@ -642,40 +604,31 @@ static void LinkCRO(Interface* self) {
642 * 1 : Result of function, 0 on success, otherwise error code 604 * 1 : Result of function, 0 on success, otherwise error code
643 */ 605 */
644static void UnlinkCRO(Interface* self) { 606static void UnlinkCRO(Interface* self) {
645 u32* cmd_buff = Kernel::GetCommandBuffer(); 607 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x07, 1, 2);
646 VAddr cro_address = cmd_buff[1]; 608 VAddr cro_address = rp.Pop<u32>();
647 u32 descriptor = cmd_buff[2]; 609 Kernel::Handle process = rp.PopHandle();
648 u32 process = cmd_buff[3]; 610
649 611 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, process=0x%08X", cro_address, process);
650 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X",
651 cro_address, descriptor, process);
652
653 if (descriptor != 0) {
654 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
655 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
656 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
657 return;
658 }
659 612
660 CROHelper cro(cro_address); 613 CROHelper cro(cro_address);
661 614
662 cmd_buff[0] = IPC::MakeHeader(7, 1, 0); 615 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
663 616
664 if (loaded_crs == 0) { 617 if (loaded_crs == 0) {
665 LOG_ERROR(Service_LDR, "Not initialized"); 618 LOG_ERROR(Service_LDR, "Not initialized");
666 cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; 619 rb.Push(ERROR_NOT_INITIALIZED);
667 return; 620 return;
668 } 621 }
669 622
670 if (cro_address & Memory::PAGE_MASK) { 623 if (cro_address & Memory::PAGE_MASK) {
671 LOG_ERROR(Service_LDR, "CRO address is not aligned"); 624 LOG_ERROR(Service_LDR, "CRO address is not aligned");
672 cmd_buff[1] = ERROR_MISALIGNED_ADDRESS.raw; 625 rb.Push(ERROR_MISALIGNED_ADDRESS);
673 return; 626 return;
674 } 627 }
675 628
676 if (!cro.IsLoaded()) { 629 if (!cro.IsLoaded()) {
677 LOG_ERROR(Service_LDR, "Invalid or not loaded CRO"); 630 LOG_ERROR(Service_LDR, "Invalid or not loaded CRO");
678 cmd_buff[1] = ERROR_NOT_LOADED.raw; 631 rb.Push(ERROR_NOT_LOADED);
679 return; 632 return;
680 } 633 }
681 634
@@ -689,7 +642,7 @@ static void UnlinkCRO(Interface* self) {
689 memory_synchronizer.SynchronizeOriginalMemory(); 642 memory_synchronizer.SynchronizeOriginalMemory();
690 Core::CPU().ClearInstructionCache(); 643 Core::CPU().ClearInstructionCache();
691 644
692 cmd_buff[1] = result.raw; 645 rb.Push(result);
693} 646}
694 647
695/** 648/**
@@ -704,29 +657,21 @@ static void UnlinkCRO(Interface* self) {
704 * 1 : Result of function, 0 on success, otherwise error code 657 * 1 : Result of function, 0 on success, otherwise error code
705 */ 658 */
706static void Shutdown(Interface* self) { 659static void Shutdown(Interface* self) {
707 u32* cmd_buff = Kernel::GetCommandBuffer(); 660 IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x08, 1, 2);
708 VAddr crs_buffer_ptr = cmd_buff[1]; 661 VAddr crs_buffer_ptr = rp.Pop<u32>();
709 u32 descriptor = cmd_buff[2]; 662 Kernel::Handle process = rp.PopHandle();
710 u32 process = cmd_buff[3]; 663
711 664 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, process=0x%08X", crs_buffer_ptr,
712 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", 665 process);
713 crs_buffer_ptr, descriptor, process); 666
714 667 IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
715 if (descriptor != 0) {
716 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
717 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
718 cmd_buff[1] = ERROR_INVALID_DESCRIPTOR.raw;
719 return;
720 }
721 668
722 if (loaded_crs == 0) { 669 if (loaded_crs == 0) {
723 LOG_ERROR(Service_LDR, "Not initialized"); 670 LOG_ERROR(Service_LDR, "Not initialized");
724 cmd_buff[1] = ERROR_NOT_INITIALIZED.raw; 671 rb.Push(ERROR_NOT_INITIALIZED);
725 return; 672 return;
726 } 673 }
727 674
728 cmd_buff[0] = IPC::MakeHeader(8, 1, 0);
729
730 CROHelper crs(loaded_crs); 675 CROHelper crs(loaded_crs);
731 crs.Unrebase(true); 676 crs.Unrebase(true);
732 677
@@ -744,7 +689,7 @@ static void Shutdown(Interface* self) {
744 } 689 }
745 690
746 loaded_crs = 0; 691 loaded_crs = 0;
747 cmd_buff[1] = result.raw; 692 rb.Push(result);
748} 693}
749 694
750const Interface::FunctionInfo FunctionTable[] = { 695const Interface::FunctionInfo FunctionTable[] = {