summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/applets/applet.cpp34
-rw-r--r--src/core/hle/applets/applet.h8
-rw-r--r--src/core/hle/applets/erreula.cpp16
-rw-r--r--src/core/hle/applets/erreula.h10
-rw-r--r--src/core/hle/applets/mii_selector.cpp22
-rw-r--r--src/core/hle/applets/mii_selector.h39
-rw-r--r--src/core/hle/applets/swkbd.cpp23
-rw-r--r--src/core/hle/applets/swkbd.h13
-rw-r--r--src/core/hle/config_mem.h26
-rw-r--r--src/core/hle/function_wrappers.h105
-rw-r--r--src/core/hle/hle.cpp7
-rw-r--r--src/core/hle/hle.h2
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp24
-rw-r--r--src/core/hle/kernel/address_arbiter.h15
-rw-r--r--src/core/hle/kernel/client_port.cpp1
-rw-r--r--src/core/hle/kernel/client_port.h24
-rw-r--r--src/core/hle/kernel/event.cpp6
-rw-r--r--src/core/hle/kernel/event.h20
-rw-r--r--src/core/hle/kernel/kernel.cpp5
-rw-r--r--src/core/hle/kernel/kernel.h68
-rw-r--r--src/core/hle/kernel/memory.cpp25
-rw-r--r--src/core/hle/kernel/memory.h3
-rw-r--r--src/core/hle/kernel/mutex.cpp3
-rw-r--r--src/core/hle/kernel/mutex.h20
-rw-r--r--src/core/hle/kernel/process.cpp55
-rw-r--r--src/core/hle/kernel/process.h53
-rw-r--r--src/core/hle/kernel/resource_limit.cpp113
-rw-r--r--src/core/hle/kernel/resource_limit.h47
-rw-r--r--src/core/hle/kernel/semaphore.cpp3
-rw-r--r--src/core/hle/kernel/semaphore.h22
-rw-r--r--src/core/hle/kernel/server_port.cpp6
-rw-r--r--src/core/hle/kernel/server_port.h22
-rw-r--r--src/core/hle/kernel/session.cpp1
-rw-r--r--src/core/hle/kernel/session.h63
-rw-r--r--src/core/hle/kernel/shared_memory.cpp71
-rw-r--r--src/core/hle/kernel/shared_memory.h61
-rw-r--r--src/core/hle/kernel/thread.cpp110
-rw-r--r--src/core/hle/kernel/thread.h82
-rw-r--r--src/core/hle/kernel/timer.cpp18
-rw-r--r--src/core/hle/kernel/timer.h23
-rw-r--r--src/core/hle/kernel/vm_manager.cpp38
-rw-r--r--src/core/hle/kernel/vm_manager.h23
-rw-r--r--src/core/hle/result.h98
-rw-r--r--src/core/hle/service/ac_u.cpp39
-rw-r--r--src/core/hle/service/am/am.cpp58
-rw-r--r--src/core/hle/service/am/am_app.cpp16
-rw-r--r--src/core/hle/service/am/am_net.cpp110
-rw-r--r--src/core/hle/service/am/am_sys.cpp42
-rw-r--r--src/core/hle/service/am/am_u.cpp68
-rw-r--r--src/core/hle/service/apt/apt.cpp158
-rw-r--r--src/core/hle/service/apt/apt.h96
-rw-r--r--src/core/hle/service/apt/apt_a.cpp56
-rw-r--r--src/core/hle/service/apt/apt_s.cpp170
-rw-r--r--src/core/hle/service/apt/apt_u.cpp176
-rw-r--r--src/core/hle/service/apt/bcfnt/bcfnt.h1
-rw-r--r--src/core/hle/service/boss/boss.cpp5
-rw-r--r--src/core/hle/service/boss/boss_p.cpp2
-rw-r--r--src/core/hle/service/boss/boss_u.cpp8
-rw-r--r--src/core/hle/service/cam/cam.cpp76
-rw-r--r--src/core/hle/service/cam/cam.h52
-rw-r--r--src/core/hle/service/cam/cam_c.cpp4
-rw-r--r--src/core/hle/service/cam/cam_q.cpp4
-rw-r--r--src/core/hle/service/cam/cam_s.cpp4
-rw-r--r--src/core/hle/service/cam/cam_u.cpp124
-rw-r--r--src/core/hle/service/cecd/cecd.cpp10
-rw-r--r--src/core/hle/service/cecd/cecd.h10
-rw-r--r--src/core/hle/service/cecd/cecd_s.cpp4
-rw-r--r--src/core/hle/service/cecd/cecd_u.cpp6
-rw-r--r--src/core/hle/service/cfg/cfg.cpp196
-rw-r--r--src/core/hle/service/cfg/cfg.h26
-rw-r--r--src/core/hle/service/cfg/cfg_i.cpp84
-rw-r--r--src/core/hle/service/cfg/cfg_s.cpp38
-rw-r--r--src/core/hle/service/cfg/cfg_u.cpp20
-rw-r--r--src/core/hle/service/csnd_snd.cpp32
-rw-r--r--src/core/hle/service/csnd_snd.h2
-rw-r--r--src/core/hle/service/dlp/dlp.cpp5
-rw-r--r--src/core/hle/service/dlp/dlp_clnt.cpp3
-rw-r--r--src/core/hle/service/dlp/dlp_fkcl.cpp3
-rw-r--r--src/core/hle/service/dlp/dlp_srvr.cpp8
-rw-r--r--src/core/hle/service/dsp_dsp.cpp156
-rw-r--r--src/core/hle/service/dsp_dsp.h1
-rw-r--r--src/core/hle/service/err_f.cpp128
-rw-r--r--src/core/hle/service/frd/frd.cpp24
-rw-r--r--src/core/hle/service/frd/frd_a.cpp2
-rw-r--r--src/core/hle/service/frd/frd_u.cpp104
-rw-r--r--src/core/hle/service/fs/archive.cpp380
-rw-r--r--src/core/hle/service/fs/archive.h67
-rw-r--r--src/core/hle/service/fs/fs_user.cpp386
-rw-r--r--src/core/hle/service/gsp_gpu.cpp251
-rw-r--r--src/core/hle/service/gsp_gpu.h42
-rw-r--r--src/core/hle/service/gsp_lcd.cpp4
-rw-r--r--src/core/hle/service/hid/hid.cpp56
-rw-r--r--src/core/hle/service/hid/hid.h70
-rw-r--r--src/core/hle/service/hid/hid_spvr.cpp18
-rw-r--r--src/core/hle/service/hid/hid_user.cpp18
-rw-r--r--src/core/hle/service/http_c.cpp100
-rw-r--r--src/core/hle/service/ir/ir.cpp29
-rw-r--r--src/core/hle/service/ir/ir_rst.cpp8
-rw-r--r--src/core/hle/service/ir/ir_u.cpp38
-rw-r--r--src/core/hle/service/ir/ir_user.cpp50
-rw-r--r--src/core/hle/service/ldr_ro/cro_helper.cpp357
-rw-r--r--src/core/hle/service/ldr_ro/cro_helper.h146
-rw-r--r--src/core/hle/service/ldr_ro/ldr_ro.cpp215
-rw-r--r--src/core/hle/service/ldr_ro/memory_synchronizer.cpp7
-rw-r--r--src/core/hle/service/ldr_ro/memory_synchronizer.h1
-rw-r--r--src/core/hle/service/mic_u.cpp32
-rw-r--r--src/core/hle/service/ndm/ndm.cpp19
-rw-r--r--src/core/hle/service/ndm/ndm.h43
-rw-r--r--src/core/hle/service/ndm/ndm_u.cpp44
-rw-r--r--src/core/hle/service/news/news.cpp6
-rw-r--r--src/core/hle/service/news/news_s.cpp26
-rw-r--r--src/core/hle/service/news/news_u.cpp2
-rw-r--r--src/core/hle/service/nim/nim.cpp6
-rw-r--r--src/core/hle/service/nim/nim_aoc.cpp16
-rw-r--r--src/core/hle/service/nim/nim_s.cpp9
-rw-r--r--src/core/hle/service/nim/nim_u.cpp13
-rw-r--r--src/core/hle/service/nim/nim_u.h2
-rw-r--r--src/core/hle/service/ns_s.cpp30
-rw-r--r--src/core/hle/service/nwm_uds.cpp83
-rw-r--r--src/core/hle/service/pm_app.cpp24
-rw-r--r--src/core/hle/service/ptm/ptm.cpp32
-rw-r--r--src/core/hle/service/ptm/ptm.h21
-rw-r--r--src/core/hle/service/ptm/ptm_play.cpp8
-rw-r--r--src/core/hle/service/ptm/ptm_play.h6
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.cpp62
-rw-r--r--src/core/hle/service/ptm/ptm_u.cpp28
-rw-r--r--src/core/hle/service/service.cpp53
-rw-r--r--src/core/hle/service/service.h13
-rw-r--r--src/core/hle/service/soc_u.cpp380
-rw-r--r--src/core/hle/service/soc_u.h1
-rw-r--r--src/core/hle/service/srv.cpp51
-rw-r--r--src/core/hle/service/ssl_c.cpp44
-rw-r--r--src/core/hle/service/y2r_u.cpp157
-rw-r--r--src/core/hle/service/y2r_u.h2
-rw-r--r--src/core/hle/shared_page.cpp8
-rw-r--r--src/core/hle/shared_page.h24
-rw-r--r--src/core/hle/svc.cpp518
137 files changed, 3997 insertions, 3568 deletions
diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp
index ccf35fa07..4311d9897 100644
--- a/src/core/hle/applets/applet.cpp
+++ b/src/core/hle/applets/applet.cpp
@@ -6,10 +6,8 @@
6#include <memory> 6#include <memory>
7#include <type_traits> 7#include <type_traits>
8#include <unordered_map> 8#include <unordered_map>
9
10#include "common/assert.h" 9#include "common/assert.h"
11#include "common/common_types.h" 10#include "common/common_types.h"
12
13#include "core/core_timing.h" 11#include "core/core_timing.h"
14#include "core/hle/applets/applet.h" 12#include "core/hle/applets/applet.h"
15#include "core/hle/applets/erreula.h" 13#include "core/hle/applets/erreula.h"
@@ -23,23 +21,24 @@
23// Specializes std::hash for AppletId, so that we can use it in std::unordered_map. 21// Specializes std::hash for AppletId, so that we can use it in std::unordered_map.
24// Workaround for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 22// Workaround for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970
25namespace std { 23namespace std {
26 template <> 24template <>
27 struct hash<Service::APT::AppletId> { 25struct hash<Service::APT::AppletId> {
28 typedef Service::APT::AppletId argument_type; 26 typedef Service::APT::AppletId argument_type;
29 typedef std::size_t result_type; 27 typedef std::size_t result_type;
30 28
31 result_type operator()(const argument_type& id_code) const { 29 result_type operator()(const argument_type& id_code) const {
32 typedef std::underlying_type<argument_type>::type Type; 30 typedef std::underlying_type<argument_type>::type Type;
33 return std::hash<Type>()(static_cast<Type>(id_code)); 31 return std::hash<Type>()(static_cast<Type>(id_code));
34 } 32 }
35 }; 33};
36} 34}
37 35
38namespace HLE { 36namespace HLE {
39namespace Applets { 37namespace Applets {
40 38
41static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets; 39static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets;
42static u32 applet_update_event = -1; ///< The CoreTiming event identifier for the Applet update callback. 40static u32 applet_update_event =
41 -1; ///< The CoreTiming event identifier for the Applet update callback.
43/// The interval at which the Applet update callback will be called, 16.6ms 42/// The interval at which the Applet update callback will be called, 16.6ms
44static const u64 applet_update_interval_us = 16666; 43static const u64 applet_update_interval_us = 16666;
45 44
@@ -60,7 +59,8 @@ ResultCode Applet::Create(Service::APT::AppletId id) {
60 default: 59 default:
61 LOG_ERROR(Service_APT, "Could not create applet %u", id); 60 LOG_ERROR(Service_APT, "Could not create applet %u", id);
62 // TODO(Subv): Find the right error code 61 // TODO(Subv): Find the right error code
63 return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent); 62 return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet,
63 ErrorSummary::NotSupported, ErrorLevel::Permanent);
64 } 64 }
65 65
66 return RESULT_SUCCESS; 66 return RESULT_SUCCESS;
@@ -84,7 +84,7 @@ static void AppletUpdateEvent(u64 applet_id, int cycles_late) {
84 // If the applet is still running after the last update, reschedule the event 84 // If the applet is still running after the last update, reschedule the event
85 if (applet->IsRunning()) { 85 if (applet->IsRunning()) {
86 CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us) - cycles_late, 86 CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us) - cycles_late,
87 applet_update_event, applet_id); 87 applet_update_event, applet_id);
88 } else { 88 } else {
89 // Otherwise the applet has terminated, in which case we should clean it up 89 // Otherwise the applet has terminated, in which case we should clean it up
90 applets[id] = nullptr; 90 applets[id] = nullptr;
@@ -96,7 +96,8 @@ ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter)
96 if (result.IsError()) 96 if (result.IsError())
97 return result; 97 return result;
98 // Schedule the update event 98 // Schedule the update event
99 CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id)); 99 CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event,
100 static_cast<u64>(id));
100 return result; 101 return result;
101} 102}
102 103
@@ -116,6 +117,5 @@ void Init() {
116void Shutdown() { 117void Shutdown() {
117 CoreTiming::RemoveEvent(applet_update_event); 118 CoreTiming::RemoveEvent(applet_update_event);
118} 119}
119
120} 120}
121} // namespace 121} // namespace
diff --git a/src/core/hle/applets/applet.h b/src/core/hle/applets/applet.h
index 754c6f7db..bfdcad126 100644
--- a/src/core/hle/applets/applet.h
+++ b/src/core/hle/applets/applet.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8
9#include "core/hle/result.h" 8#include "core/hle/result.h"
10#include "core/hle/service/apt/apt.h" 9#include "core/hle/service/apt/apt.h"
11 10
@@ -14,8 +13,8 @@ namespace Applets {
14 13
15class Applet { 14class Applet {
16public: 15public:
17 virtual ~Applet() { } 16 virtual ~Applet() {}
18 Applet(Service::APT::AppletId id) : id(id) { } 17 Applet(Service::APT::AppletId id) : id(id) {}
19 18
20 /** 19 /**
21 * Creates an instance of the Applet subclass identified by the parameter. 20 * Creates an instance of the Applet subclass identified by the parameter.
@@ -64,7 +63,7 @@ protected:
64 */ 63 */
65 virtual ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) = 0; 64 virtual ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) = 0;
66 65
67 Service::APT::AppletId id; ///< Id of this Applet 66 Service::APT::AppletId id; ///< Id of this Applet
68 std::shared_ptr<std::vector<u8>> heap_memory; ///< Heap memory for this Applet 67 std::shared_ptr<std::vector<u8>> heap_memory; ///< Heap memory for this Applet
69}; 68};
70 69
@@ -76,6 +75,5 @@ void Init();
76 75
77/// Shuts down the HLE applets 76/// Shuts down the HLE applets
78void Shutdown(); 77void Shutdown();
79
80} 78}
81} // namespace 79} // namespace
diff --git a/src/core/hle/applets/erreula.cpp b/src/core/hle/applets/erreula.cpp
index 92a4b2323..14964427b 100644
--- a/src/core/hle/applets/erreula.cpp
+++ b/src/core/hle/applets/erreula.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/string_util.h" 5#include "common/string_util.h"
6
7#include "core/hle/applets/erreula.h" 6#include "core/hle/applets/erreula.h"
8#include "core/hle/service/apt/apt.h" 7#include "core/hle/service/apt/apt.h"
9 8
@@ -18,7 +17,8 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param
18 return ResultCode(-1); 17 return ResultCode(-1);
19 } 18 }
20 19
21 // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. 20 // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared
21 // memory.
22 // Create the SharedMemory that will hold the framebuffer data 22 // Create the SharedMemory that will hold the framebuffer data
23 Service::APT::CaptureBufferInfo capture_info; 23 Service::APT::CaptureBufferInfo capture_info;
24 ASSERT(sizeof(capture_info) == parameter.buffer.size()); 24 ASSERT(sizeof(capture_info) == parameter.buffer.size());
@@ -30,9 +30,9 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param
30 // Allocate a heap block of the required size for this applet. 30 // Allocate a heap block of the required size for this applet.
31 heap_memory = std::make_shared<std::vector<u8>>(capture_info.size); 31 heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
32 // Create a SharedMemory that directly points to this heap block. 32 // Create a SharedMemory that directly points to this heap block.
33 framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), 33 framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
34 MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 34 heap_memory, 0, heap_memory->size(), MemoryPermission::ReadWrite,
35 "ErrEula Memory"); 35 MemoryPermission::ReadWrite, "ErrEula Memory");
36 36
37 // Send the response message with the newly created SharedMemory 37 // Send the response message with the newly created SharedMemory
38 Service::APT::MessageParameter result; 38 Service::APT::MessageParameter result;
@@ -49,7 +49,8 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param
49ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parameter) { 49ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parameter) {
50 started = true; 50 started = true;
51 51
52 // TODO(Subv): Set the expected fields in the response buffer before resending it to the application. 52 // TODO(Subv): Set the expected fields in the response buffer before resending it to the
53 // application.
53 // TODO(Subv): Reverse the parameter format for the ErrEula applet 54 // TODO(Subv): Reverse the parameter format for the ErrEula applet
54 55
55 // Let the application know that we're closing 56 // Let the application know that we're closing
@@ -65,8 +66,7 @@ ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parame
65 return RESULT_SUCCESS; 66 return RESULT_SUCCESS;
66} 67}
67 68
68void ErrEula::Update() { 69void ErrEula::Update() {}
69}
70 70
71} // namespace Applets 71} // namespace Applets
72} // namespace HLE 72} // namespace HLE
diff --git a/src/core/hle/applets/erreula.h b/src/core/hle/applets/erreula.h
index 9fe72ae07..a7ec7ec01 100644
--- a/src/core/hle/applets/erreula.h
+++ b/src/core/hle/applets/erreula.h
@@ -12,16 +12,20 @@ namespace Applets {
12 12
13class ErrEula final : public Applet { 13class ErrEula final : public Applet {
14public: 14public:
15 explicit ErrEula(Service::APT::AppletId id): Applet(id) { } 15 explicit ErrEula(Service::APT::AppletId id) : Applet(id) {}
16 16
17 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; 17 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override;
18 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; 18 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override;
19 void Update() override; 19 void Update() override;
20 bool IsRunning() const override { return started; } 20 bool IsRunning() const override {
21 return started;
22 }
21 23
22 /// This SharedMemory will be created when we receive the LibAppJustStarted message. 24 /// This SharedMemory will be created when we receive the LibAppJustStarted message.
23 /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo 25 /// It holds the framebuffer info retrieved by the application with
26 /// GSPGPU::ImportDisplayCaptureInfo
24 Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; 27 Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory;
28
25private: 29private:
26 /// Whether this applet is currently running instead of the host application or not. 30 /// Whether this applet is currently running instead of the host application or not.
27 bool started = false; 31 bool started = false;
diff --git a/src/core/hle/applets/mii_selector.cpp b/src/core/hle/applets/mii_selector.cpp
index 77f01d208..53a8683a4 100644
--- a/src/core/hle/applets/mii_selector.cpp
+++ b/src/core/hle/applets/mii_selector.cpp
@@ -4,16 +4,13 @@
4 4
5#include <cstring> 5#include <cstring>
6#include <string> 6#include <string>
7
8#include "common/assert.h" 7#include "common/assert.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10#include "common/string_util.h" 9#include "common/string_util.h"
11
12#include "core/hle/applets/mii_selector.h" 10#include "core/hle/applets/mii_selector.h"
13#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/kernel.h"
14#include "core/hle/kernel/shared_memory.h" 12#include "core/hle/kernel/shared_memory.h"
15#include "core/hle/result.h" 13#include "core/hle/result.h"
16
17#include "video_core/video_core.h" 14#include "video_core/video_core.h"
18 15
19//////////////////////////////////////////////////////////////////////////////////////////////////// 16////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -29,7 +26,8 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p
29 return ResultCode(-1); 26 return ResultCode(-1);
30 } 27 }
31 28
32 // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. 29 // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared
30 // memory.
33 // Create the SharedMemory that will hold the framebuffer data 31 // Create the SharedMemory that will hold the framebuffer data
34 Service::APT::CaptureBufferInfo capture_info; 32 Service::APT::CaptureBufferInfo capture_info;
35 ASSERT(sizeof(capture_info) == parameter.buffer.size()); 33 ASSERT(sizeof(capture_info) == parameter.buffer.size());
@@ -40,9 +38,9 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p
40 // Allocate a heap block of the required size for this applet. 38 // Allocate a heap block of the required size for this applet.
41 heap_memory = std::make_shared<std::vector<u8>>(capture_info.size); 39 heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
42 // Create a SharedMemory that directly points to this heap block. 40 // Create a SharedMemory that directly points to this heap block.
43 framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), 41 framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
44 MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 42 heap_memory, 0, heap_memory->size(), MemoryPermission::ReadWrite,
45 "MiiSelector Memory"); 43 MemoryPermission::ReadWrite, "MiiSelector Memory");
46 44
47 // Send the response message with the newly created SharedMemory 45 // Send the response message with the newly created SharedMemory
48 Service::APT::MessageParameter result; 46 Service::APT::MessageParameter result;
@@ -59,12 +57,14 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p
59ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& parameter) { 57ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& parameter) {
60 started = true; 58 started = true;
61 59
62 // TODO(Subv): Set the expected fields in the response buffer before resending it to the application. 60 // TODO(Subv): Set the expected fields in the response buffer before resending it to the
61 // application.
63 // TODO(Subv): Reverse the parameter format for the Mii Selector 62 // TODO(Subv): Reverse the parameter format for the Mii Selector
64 63
65 memcpy(&config, parameter.buffer.data(), parameter.buffer.size()); 64 memcpy(&config, parameter.buffer.data(), parameter.buffer.size());
66 65
67 // TODO(Subv): Find more about this structure, result code 0 is enough to let most games continue. 66 // TODO(Subv): Find more about this structure, result code 0 is enough to let most games
67 // continue.
68 MiiResult result; 68 MiiResult result;
69 memset(&result, 0, sizeof(result)); 69 memset(&result, 0, sizeof(result));
70 result.result_code = 0; 70 result.result_code = 0;
@@ -82,8 +82,6 @@ ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& pa
82 return RESULT_SUCCESS; 82 return RESULT_SUCCESS;
83} 83}
84 84
85void MiiSelector::Update() { 85void MiiSelector::Update() {}
86}
87
88} 86}
89} // namespace 87} // namespace
diff --git a/src/core/hle/applets/mii_selector.h b/src/core/hle/applets/mii_selector.h
index 24e8e721d..e3ab9f0cd 100644
--- a/src/core/hle/applets/mii_selector.h
+++ b/src/core/hle/applets/mii_selector.h
@@ -4,9 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h"
8#include "common/common_funcs.h" 7#include "common/common_funcs.h"
9 8#include "common/common_types.h"
10#include "core/hle/applets/applet.h" 9#include "core/hle/applets/applet.h"
11#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/shared_memory.h" 11#include "core/hle/kernel/shared_memory.h"
@@ -17,28 +16,30 @@ namespace HLE {
17namespace Applets { 16namespace Applets {
18 17
19struct MiiConfig { 18struct MiiConfig {
20 u8 unk_000; 19 u8 unk_000;
21 u8 unk_001; 20 u8 unk_001;
22 u8 unk_002; 21 u8 unk_002;
23 u8 unk_003; 22 u8 unk_003;
24 u8 unk_004; 23 u8 unk_004;
25 INSERT_PADDING_BYTES(3); 24 INSERT_PADDING_BYTES(3);
26 u16 unk_008; 25 u16 unk_008;
27 INSERT_PADDING_BYTES(0x82); 26 INSERT_PADDING_BYTES(0x82);
28 u8 unk_08C; 27 u8 unk_08C;
29 INSERT_PADDING_BYTES(3); 28 INSERT_PADDING_BYTES(3);
30 u16 unk_090; 29 u16 unk_090;
31 INSERT_PADDING_BYTES(2); 30 INSERT_PADDING_BYTES(2);
32 u32 unk_094; 31 u32 unk_094;
33 u16 unk_098; 32 u16 unk_098;
34 u8 unk_09A[0x64]; 33 u8 unk_09A[0x64];
35 u8 unk_0FE; 34 u8 unk_0FE;
36 u8 unk_0FF; 35 u8 unk_0FF;
37 u32 unk_100; 36 u32 unk_100;
38}; 37};
39 38
40static_assert(sizeof(MiiConfig) == 0x104, "MiiConfig structure has incorrect size"); 39static_assert(sizeof(MiiConfig) == 0x104, "MiiConfig structure has incorrect size");
41#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(MiiConfig, field_name) == position, "Field "#field_name" has invalid position") 40#define ASSERT_REG_POSITION(field_name, position) \
41 static_assert(offsetof(MiiConfig, field_name) == position, \
42 "Field " #field_name " has invalid position")
42ASSERT_REG_POSITION(unk_008, 0x08); 43ASSERT_REG_POSITION(unk_008, 0x08);
43ASSERT_REG_POSITION(unk_08C, 0x8C); 44ASSERT_REG_POSITION(unk_08C, 0x8C);
44ASSERT_REG_POSITION(unk_090, 0x90); 45ASSERT_REG_POSITION(unk_090, 0x90);
@@ -55,22 +56,27 @@ struct MiiResult {
55 INSERT_PADDING_BYTES(2); 56 INSERT_PADDING_BYTES(2);
56}; 57};
57static_assert(sizeof(MiiResult) == 0x84, "MiiResult structure has incorrect size"); 58static_assert(sizeof(MiiResult) == 0x84, "MiiResult structure has incorrect size");
58#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(MiiResult, field_name) == position, "Field "#field_name" has invalid position") 59#define ASSERT_REG_POSITION(field_name, position) \
60 static_assert(offsetof(MiiResult, field_name) == position, \
61 "Field " #field_name " has invalid position")
59ASSERT_REG_POSITION(unk_0C, 0x0C); 62ASSERT_REG_POSITION(unk_0C, 0x0C);
60ASSERT_REG_POSITION(unk_6C, 0x6C); 63ASSERT_REG_POSITION(unk_6C, 0x6C);
61#undef ASSERT_REG_POSITION 64#undef ASSERT_REG_POSITION
62 65
63class MiiSelector final : public Applet { 66class MiiSelector final : public Applet {
64public: 67public:
65 MiiSelector(Service::APT::AppletId id) : Applet(id), started(false) { } 68 MiiSelector(Service::APT::AppletId id) : Applet(id), started(false) {}
66 69
67 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; 70 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override;
68 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; 71 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override;
69 void Update() override; 72 void Update() override;
70 bool IsRunning() const override { return started; } 73 bool IsRunning() const override {
74 return started;
75 }
71 76
72 /// This SharedMemory will be created when we receive the LibAppJustStarted message. 77 /// This SharedMemory will be created when we receive the LibAppJustStarted message.
73 /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo 78 /// It holds the framebuffer info retrieved by the application with
79 /// GSPGPU::ImportDisplayCaptureInfo
74 Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; 80 Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory;
75 81
76 /// Whether this applet is currently running instead of the host application or not. 82 /// Whether this applet is currently running instead of the host application or not.
@@ -78,6 +84,5 @@ public:
78 84
79 MiiConfig config; 85 MiiConfig config;
80}; 86};
81
82} 87}
83} // namespace 88} // namespace
diff --git a/src/core/hle/applets/swkbd.cpp b/src/core/hle/applets/swkbd.cpp
index d87bf3d57..06ddf538b 100644
--- a/src/core/hle/applets/swkbd.cpp
+++ b/src/core/hle/applets/swkbd.cpp
@@ -4,19 +4,16 @@
4 4
5#include <cstring> 5#include <cstring>
6#include <string> 6#include <string>
7
8#include "common/assert.h" 7#include "common/assert.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10#include "common/string_util.h" 9#include "common/string_util.h"
11
12#include "core/hle/applets/swkbd.h" 10#include "core/hle/applets/swkbd.h"
13#include "core/hle/kernel/kernel.h" 11#include "core/hle/kernel/kernel.h"
14#include "core/hle/kernel/shared_memory.h" 12#include "core/hle/kernel/shared_memory.h"
15#include "core/hle/service/hid/hid.h"
16#include "core/hle/service/gsp_gpu.h"
17#include "core/hle/result.h" 13#include "core/hle/result.h"
14#include "core/hle/service/gsp_gpu.h"
15#include "core/hle/service/hid/hid.h"
18#include "core/memory.h" 16#include "core/memory.h"
19
20#include "video_core/video_core.h" 17#include "video_core/video_core.h"
21 18
22//////////////////////////////////////////////////////////////////////////////////////////////////// 19////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,7 +29,8 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con
32 return ResultCode(-1); 29 return ResultCode(-1);
33 } 30 }
34 31
35 // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. 32 // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared
33 // memory.
36 // Create the SharedMemory that will hold the framebuffer data 34 // Create the SharedMemory that will hold the framebuffer data
37 Service::APT::CaptureBufferInfo capture_info; 35 Service::APT::CaptureBufferInfo capture_info;
38 ASSERT(sizeof(capture_info) == parameter.buffer.size()); 36 ASSERT(sizeof(capture_info) == parameter.buffer.size());
@@ -43,9 +41,9 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con
43 // Allocate a heap block of the required size for this applet. 41 // Allocate a heap block of the required size for this applet.
44 heap_memory = std::make_shared<std::vector<u8>>(capture_info.size); 42 heap_memory = std::make_shared<std::vector<u8>>(capture_info.size);
45 // Create a SharedMemory that directly points to this heap block. 43 // Create a SharedMemory that directly points to this heap block.
46 framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), 44 framebuffer_memory = Kernel::SharedMemory::CreateForApplet(
47 MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 45 heap_memory, 0, heap_memory->size(), MemoryPermission::ReadWrite,
48 "SoftwareKeyboard Memory"); 46 MemoryPermission::ReadWrite, "SoftwareKeyboard Memory");
49 47
50 // Send the response message with the newly created SharedMemory 48 // Send the response message with the newly created SharedMemory
51 Service::APT::MessageParameter result; 49 Service::APT::MessageParameter result;
@@ -60,10 +58,12 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con
60} 58}
61 59
62ResultCode SoftwareKeyboard::StartImpl(Service::APT::AppletStartupParameter const& parameter) { 60ResultCode SoftwareKeyboard::StartImpl(Service::APT::AppletStartupParameter const& parameter) {
63 ASSERT_MSG(parameter.buffer.size() == sizeof(config), "The size of the parameter (SoftwareKeyboardConfig) is wrong"); 61 ASSERT_MSG(parameter.buffer.size() == sizeof(config),
62 "The size of the parameter (SoftwareKeyboardConfig) is wrong");
64 63
65 memcpy(&config, parameter.buffer.data(), parameter.buffer.size()); 64 memcpy(&config, parameter.buffer.data(), parameter.buffer.size());
66 text_memory = boost::static_pointer_cast<Kernel::SharedMemory, Kernel::Object>(parameter.object); 65 text_memory =
66 boost::static_pointer_cast<Kernel::SharedMemory, Kernel::Object>(parameter.object);
67 67
68 // TODO(Subv): Verify if this is the correct behavior 68 // TODO(Subv): Verify if this is the correct behavior
69 memset(text_memory->GetPointer(), 0, text_memory->size); 69 memset(text_memory->GetPointer(), 0, text_memory->size);
@@ -115,6 +115,5 @@ void SoftwareKeyboard::Finalize() {
115 115
116 started = false; 116 started = false;
117} 117}
118
119} 118}
120} // namespace 119} // namespace
diff --git a/src/core/hle/applets/swkbd.h b/src/core/hle/applets/swkbd.h
index cf26a8fb7..ea0b1fba9 100644
--- a/src/core/hle/applets/swkbd.h
+++ b/src/core/hle/applets/swkbd.h
@@ -4,9 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h"
8#include "common/common_funcs.h" 7#include "common/common_funcs.h"
9 8#include "common/common_types.h"
10#include "core/hle/applets/applet.h" 9#include "core/hle/applets/applet.h"
11#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/shared_memory.h" 11#include "core/hle/kernel/shared_memory.h"
@@ -53,12 +52,14 @@ static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software Keyboard Config
53 52
54class SoftwareKeyboard final : public Applet { 53class SoftwareKeyboard final : public Applet {
55public: 54public:
56 SoftwareKeyboard(Service::APT::AppletId id) : Applet(id), started(false) { } 55 SoftwareKeyboard(Service::APT::AppletId id) : Applet(id), started(false) {}
57 56
58 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; 57 ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override;
59 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; 58 ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override;
60 void Update() override; 59 void Update() override;
61 bool IsRunning() const override { return started; } 60 bool IsRunning() const override {
61 return started;
62 }
62 63
63 /** 64 /**
64 * Draws a keyboard to the current bottom screen framebuffer. 65 * Draws a keyboard to the current bottom screen framebuffer.
@@ -72,7 +73,8 @@ public:
72 void Finalize(); 73 void Finalize();
73 74
74 /// This SharedMemory will be created when we receive the LibAppJustStarted message. 75 /// This SharedMemory will be created when we receive the LibAppJustStarted message.
75 /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo 76 /// It holds the framebuffer info retrieved by the application with
77 /// GSPGPU::ImportDisplayCaptureInfo
76 Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; 78 Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory;
77 79
78 /// SharedMemory where the output text will be stored 80 /// SharedMemory where the output text will be stored
@@ -84,6 +86,5 @@ public:
84 /// Whether this applet is currently running instead of the host application or not. 86 /// Whether this applet is currently running instead of the host application or not.
85 bool started; 87 bool started;
86}; 88};
87
88} 89}
89} // namespace 90} // namespace
diff --git a/src/core/hle/config_mem.h b/src/core/hle/config_mem.h
index 24a1254f2..42fa6d789 100644
--- a/src/core/hle/config_mem.h
+++ b/src/core/hle/config_mem.h
@@ -12,7 +12,6 @@
12#include "common/common_funcs.h" 12#include "common/common_funcs.h"
13#include "common/common_types.h" 13#include "common/common_types.h"
14#include "common/swap.h" 14#include "common/swap.h"
15
16#include "core/memory.h" 15#include "core/memory.h"
17 16
18//////////////////////////////////////////////////////////////////////////////////////////////////// 17////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -20,16 +19,16 @@
20namespace ConfigMem { 19namespace ConfigMem {
21 20
22struct ConfigMemDef { 21struct ConfigMemDef {
23 u8 kernel_unk; // 0 22 u8 kernel_unk; // 0
24 u8 kernel_version_rev; // 1 23 u8 kernel_version_rev; // 1
25 u8 kernel_version_min; // 2 24 u8 kernel_version_min; // 2
26 u8 kernel_version_maj; // 3 25 u8 kernel_version_maj; // 3
27 u32_le update_flag; // 4 26 u32_le update_flag; // 4
28 u64_le ns_tid; // 8 27 u64_le ns_tid; // 8
29 u32_le sys_core_ver; // 10 28 u32_le sys_core_ver; // 10
30 u8 unit_info; // 14 29 u8 unit_info; // 14
31 u8 boot_firm; // 15 30 u8 boot_firm; // 15
32 u8 prev_firm; // 16 31 u8 prev_firm; // 16
33 INSERT_PADDING_BYTES(0x1); // 17 32 INSERT_PADDING_BYTES(0x1); // 17
34 u32_le ctr_sdk_ver; // 18 33 u32_le ctr_sdk_ver; // 18
35 INSERT_PADDING_BYTES(0x30 - 0x1C); // 1C 34 INSERT_PADDING_BYTES(0x30 - 0x1C); // 1C
@@ -39,15 +38,16 @@ struct ConfigMemDef {
39 u32_le sys_mem_alloc; // 44 38 u32_le sys_mem_alloc; // 44
40 u32_le base_mem_alloc; // 48 39 u32_le base_mem_alloc; // 48
41 INSERT_PADDING_BYTES(0x60 - 0x4C); // 4C 40 INSERT_PADDING_BYTES(0x60 - 0x4C); // 4C
42 u8 firm_unk; // 60 41 u8 firm_unk; // 60
43 u8 firm_version_rev; // 61 42 u8 firm_version_rev; // 61
44 u8 firm_version_min; // 62 43 u8 firm_version_min; // 62
45 u8 firm_version_maj; // 63 44 u8 firm_version_maj; // 63
46 u32_le firm_sys_core_ver; // 64 45 u32_le firm_sys_core_ver; // 64
47 u32_le firm_ctr_sdk_ver; // 68 46 u32_le firm_ctr_sdk_ver; // 68
48 INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C 47 INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C
49}; 48};
50static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong"); 49static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE,
50 "Config Memory structure size is wrong");
51 51
52extern ConfigMemDef config_mem; 52extern ConfigMemDef config_mem;
53 53
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 8839ce482..8ce0f6d2b 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -5,16 +5,16 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8
9#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
10#include "core/memory.h" 9#include "core/core.h"
11#include "core/hle/hle.h" 10#include "core/hle/hle.h"
12#include "core/hle/result.h" 11#include "core/hle/result.h"
13#include "core/hle/svc.h" 12#include "core/hle/svc.h"
13#include "core/memory.h"
14 14
15namespace HLE { 15namespace HLE {
16 16
17#define PARAM(n) Core::g_app_core->GetReg(n) 17#define PARAM(n) Core::g_app_core->GetReg(n)
18 18
19/// An invalid result code that is meant to be overwritten when a thread resumes from waiting 19/// An invalid result code that is meant to be overwritten when a thread resumes from waiting
20static const ResultCode RESULT_INVALID(0xDEADC0DE); 20static const ResultCode RESULT_INVALID(0xDEADC0DE);
@@ -40,28 +40,33 @@ static inline void FuncReturn64(u64 res) {
40//////////////////////////////////////////////////////////////////////////////////////////////////// 40////////////////////////////////////////////////////////////////////////////////////////////////////
41// Function wrappers that return type ResultCode 41// Function wrappers that return type ResultCode
42 42
43template<ResultCode func(u32, u32, u32, u32)> void Wrap() { 43template <ResultCode func(u32, u32, u32, u32)>
44void Wrap() {
44 FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)).raw); 45 FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)).raw);
45} 46}
46 47
47template<ResultCode func(u32*, u32, u32, u32, u32, u32)> void Wrap(){ 48template <ResultCode func(u32*, u32, u32, u32, u32, u32)>
49void Wrap() {
48 u32 param_1 = 0; 50 u32 param_1 = 0;
49 u32 retval = func(&param_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; 51 u32 retval = func(&param_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
50 Core::g_app_core->SetReg(1, param_1); 52 Core::g_app_core->SetReg(1, param_1);
51 FuncReturn(retval); 53 FuncReturn(retval);
52} 54}
53 55
54template<ResultCode func(u32*, s32, u32, u32, u32, s32)> void Wrap() { 56template <ResultCode func(u32*, s32, u32, u32, u32, s32)>
57void Wrap() {
55 u32 param_1 = 0; 58 u32 param_1 = 0;
56 u32 retval = func(&param_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; 59 u32 retval = func(&param_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw;
57 Core::g_app_core->SetReg(1, param_1); 60 Core::g_app_core->SetReg(1, param_1);
58 FuncReturn(retval); 61 FuncReturn(retval);
59} 62}
60 63
61template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() { 64template <ResultCode func(s32*, u32*, s32, bool, s64)>
65void Wrap() {
62 s32 param_1 = 0; 66 s32 param_1 = 0;
63 s32 retval = func(&param_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), 67 s32 retval = func(&param_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2),
64 (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))).raw; 68 (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0)))
69 .raw;
65 70
66 if (retval != RESULT_INVALID.raw) { 71 if (retval != RESULT_INVALID.raw) {
67 Core::g_app_core->SetReg(1, (u32)param_1); 72 Core::g_app_core->SetReg(1, (u32)param_1);
@@ -69,18 +74,22 @@ template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() {
69 } 74 }
70} 75}
71 76
72template<ResultCode func(u32, u32, u32, u32, s64)> void Wrap() { 77template <ResultCode func(u32, u32, u32, u32, s64)>
73 FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))).raw); 78void Wrap() {
79 FuncReturn(
80 func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))).raw);
74} 81}
75 82
76template<ResultCode func(u32*)> void Wrap(){ 83template <ResultCode func(u32*)>
84void Wrap() {
77 u32 param_1 = 0; 85 u32 param_1 = 0;
78 u32 retval = func(&param_1).raw; 86 u32 retval = func(&param_1).raw;
79 Core::g_app_core->SetReg(1, param_1); 87 Core::g_app_core->SetReg(1, param_1);
80 FuncReturn(retval); 88 FuncReturn(retval);
81} 89}
82 90
83template<ResultCode func(u32, s64)> void Wrap() { 91template <ResultCode func(u32, s64)>
92void Wrap() {
84 s32 retval = func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))).raw; 93 s32 retval = func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))).raw;
85 94
86 if (retval != RESULT_INVALID.raw) { 95 if (retval != RESULT_INVALID.raw) {
@@ -88,7 +97,8 @@ template<ResultCode func(u32, s64)> void Wrap() {
88 } 97 }
89} 98}
90 99
91template<ResultCode func(MemoryInfo*, PageInfo*, u32)> void Wrap() { 100template <ResultCode func(MemoryInfo*, PageInfo*, u32)>
101void Wrap() {
92 MemoryInfo memory_info = {}; 102 MemoryInfo memory_info = {};
93 PageInfo page_info = {}; 103 PageInfo page_info = {};
94 u32 retval = func(&memory_info, &page_info, PARAM(2)).raw; 104 u32 retval = func(&memory_info, &page_info, PARAM(2)).raw;
@@ -100,7 +110,8 @@ template<ResultCode func(MemoryInfo*, PageInfo*, u32)> void Wrap() {
100 FuncReturn(retval); 110 FuncReturn(retval);
101} 111}
102 112
103template<ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> void Wrap() { 113template <ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)>
114void Wrap() {
104 MemoryInfo memory_info = {}; 115 MemoryInfo memory_info = {};
105 PageInfo page_info = {}; 116 PageInfo page_info = {};
106 u32 retval = func(&memory_info, &page_info, PARAM(2), PARAM(3)).raw; 117 u32 retval = func(&memory_info, &page_info, PARAM(2), PARAM(3)).raw;
@@ -112,55 +123,65 @@ template<ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> void Wrap() {
112 FuncReturn(retval); 123 FuncReturn(retval);
113} 124}
114 125
115template<ResultCode func(s32*, u32)> void Wrap(){ 126template <ResultCode func(s32*, u32)>
127void Wrap() {
116 s32 param_1 = 0; 128 s32 param_1 = 0;
117 u32 retval = func(&param_1, PARAM(1)).raw; 129 u32 retval = func(&param_1, PARAM(1)).raw;
118 Core::g_app_core->SetReg(1, param_1); 130 Core::g_app_core->SetReg(1, param_1);
119 FuncReturn(retval); 131 FuncReturn(retval);
120} 132}
121 133
122template<ResultCode func(u32, s32)> void Wrap() { 134template <ResultCode func(u32, s32)>
135void Wrap() {
123 FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw); 136 FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw);
124} 137}
125 138
126template<ResultCode func(u32*, u32)> void Wrap(){ 139template <ResultCode func(u32*, u32)>
140void Wrap() {
127 u32 param_1 = 0; 141 u32 param_1 = 0;
128 u32 retval = func(&param_1, PARAM(1)).raw; 142 u32 retval = func(&param_1, PARAM(1)).raw;
129 Core::g_app_core->SetReg(1, param_1); 143 Core::g_app_core->SetReg(1, param_1);
130 FuncReturn(retval); 144 FuncReturn(retval);
131} 145}
132 146
133template<ResultCode func(u32)> void Wrap() { 147template <ResultCode func(u32)>
148void Wrap() {
134 FuncReturn(func(PARAM(0)).raw); 149 FuncReturn(func(PARAM(0)).raw);
135} 150}
136 151
137template<ResultCode func(s64*, u32, u32*, u32)> void Wrap(){ 152template <ResultCode func(s64*, u32, u32*, u32)>
138 FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), 153void Wrap() {
139 (s32)PARAM(3)).raw); 154 FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1),
155 (u32*)Memory::GetPointer(PARAM(2)), (s32)PARAM(3))
156 .raw);
140} 157}
141 158
142template<ResultCode func(u32*, const char*)> void Wrap() { 159template <ResultCode func(u32*, const char*)>
160void Wrap() {
143 u32 param_1 = 0; 161 u32 param_1 = 0;
144 u32 retval = func(&param_1, (char*)Memory::GetPointer(PARAM(1))).raw; 162 u32 retval = func(&param_1, (char*)Memory::GetPointer(PARAM(1))).raw;
145 Core::g_app_core->SetReg(1, param_1); 163 Core::g_app_core->SetReg(1, param_1);
146 FuncReturn(retval); 164 FuncReturn(retval);
147} 165}
148 166
149template<ResultCode func(u32*, s32, s32)> void Wrap() { 167template <ResultCode func(u32*, s32, s32)>
168void Wrap() {
150 u32 param_1 = 0; 169 u32 param_1 = 0;
151 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw; 170 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
152 Core::g_app_core->SetReg(1, param_1); 171 Core::g_app_core->SetReg(1, param_1);
153 FuncReturn(retval); 172 FuncReturn(retval);
154} 173}
155 174
156template<ResultCode func(s32*, u32, s32)> void Wrap() { 175template <ResultCode func(s32*, u32, s32)>
176void Wrap() {
157 s32 param_1 = 0; 177 s32 param_1 = 0;
158 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw; 178 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
159 Core::g_app_core->SetReg(1, param_1); 179 Core::g_app_core->SetReg(1, param_1);
160 FuncReturn(retval); 180 FuncReturn(retval);
161} 181}
162 182
163template<ResultCode func(s64*, u32, s32)> void Wrap() { 183template <ResultCode func(s64*, u32, s32)>
184void Wrap() {
164 s64 param_1 = 0; 185 s64 param_1 = 0;
165 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw; 186 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
166 Core::g_app_core->SetReg(1, (u32)param_1); 187 Core::g_app_core->SetReg(1, (u32)param_1);
@@ -168,7 +189,8 @@ template<ResultCode func(s64*, u32, s32)> void Wrap() {
168 FuncReturn(retval); 189 FuncReturn(retval);
169} 190}
170 191
171template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() { 192template <ResultCode func(u32*, u32, u32, u32, u32)>
193void Wrap() {
172 u32 param_1 = 0; 194 u32 param_1 = 0;
173 // The last parameter is passed in R0 instead of R4 195 // The last parameter is passed in R0 instead of R4
174 u32 retval = func(&param_1, PARAM(1), PARAM(2), PARAM(3), PARAM(0)).raw; 196 u32 retval = func(&param_1, PARAM(1), PARAM(2), PARAM(3), PARAM(0)).raw;
@@ -176,13 +198,15 @@ template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() {
176 FuncReturn(retval); 198 FuncReturn(retval);
177} 199}
178 200
179template<ResultCode func(u32, s64, s64)> void Wrap() { 201template <ResultCode func(u32, s64, s64)>
202void Wrap() {
180 s64 param1 = ((u64)PARAM(3) << 32) | PARAM(2); 203 s64 param1 = ((u64)PARAM(3) << 32) | PARAM(2);
181 s64 param2 = ((u64)PARAM(4) << 32) | PARAM(1); 204 s64 param2 = ((u64)PARAM(4) << 32) | PARAM(1);
182 FuncReturn(func(PARAM(0), param1, param2).raw); 205 FuncReturn(func(PARAM(0), param1, param2).raw);
183} 206}
184 207
185template<ResultCode func(s64*, Handle, u32)> void Wrap() { 208template <ResultCode func(s64*, Handle, u32)>
209void Wrap() {
186 s64 param_1 = 0; 210 s64 param_1 = 0;
187 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw; 211 u32 retval = func(&param_1, PARAM(1), PARAM(2)).raw;
188 Core::g_app_core->SetReg(1, (u32)param_1); 212 Core::g_app_core->SetReg(1, (u32)param_1);
@@ -190,14 +214,18 @@ template<ResultCode func(s64*, Handle, u32)> void Wrap() {
190 FuncReturn(retval); 214 FuncReturn(retval);
191} 215}
192 216
193template<ResultCode func(Handle, u32)> void Wrap() { 217template <ResultCode func(Handle, u32)>
218void Wrap() {
194 FuncReturn(func(PARAM(0), PARAM(1)).raw); 219 FuncReturn(func(PARAM(0), PARAM(1)).raw);
195} 220}
196 221
197template<ResultCode func(Handle*, Handle*, const char*, u32)> void Wrap() { 222template <ResultCode func(Handle*, Handle*, const char*, u32)>
223void Wrap() {
198 Handle param_1 = 0; 224 Handle param_1 = 0;
199 Handle param_2 = 0; 225 Handle param_2 = 0;
200 u32 retval = func(&param_1, &param_2, reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3)).raw; 226 u32 retval = func(&param_1, &param_2,
227 reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3))
228 .raw;
201 // The first out parameter is moved into R2 and the second is moved into R1. 229 // The first out parameter is moved into R2 and the second is moved into R1.
202 Core::g_app_core->SetReg(1, param_2); 230 Core::g_app_core->SetReg(1, param_2);
203 Core::g_app_core->SetReg(2, param_1); 231 Core::g_app_core->SetReg(2, param_1);
@@ -207,29 +235,34 @@ template<ResultCode func(Handle*, Handle*, const char*, u32)> void Wrap() {
207//////////////////////////////////////////////////////////////////////////////////////////////////// 235////////////////////////////////////////////////////////////////////////////////////////////////////
208// Function wrappers that return type u32 236// Function wrappers that return type u32
209 237
210template<u32 func()> void Wrap() { 238template <u32 func()>
239void Wrap() {
211 FuncReturn(func()); 240 FuncReturn(func());
212} 241}
213 242
214//////////////////////////////////////////////////////////////////////////////////////////////////// 243////////////////////////////////////////////////////////////////////////////////////////////////////
215// Function wrappers that return type s64 244// Function wrappers that return type s64
216 245
217template<s64 func()> void Wrap() { 246template <s64 func()>
247void Wrap() {
218 FuncReturn64(func()); 248 FuncReturn64(func());
219} 249}
220 250
221//////////////////////////////////////////////////////////////////////////////////////////////////// 251////////////////////////////////////////////////////////////////////////////////////////////////////
222/// Function wrappers that return type void 252/// Function wrappers that return type void
223 253
224template<void func(s64)> void Wrap() { 254template <void func(s64)>
255void Wrap() {
225 func(((s64)PARAM(1) << 32) | PARAM(0)); 256 func(((s64)PARAM(1) << 32) | PARAM(0));
226} 257}
227 258
228template<void func(const char*)> void Wrap() { 259template <void func(const char*)>
260void Wrap() {
229 func((char*)Memory::GetPointer(PARAM(0))); 261 func((char*)Memory::GetPointer(PARAM(0)));
230} 262}
231 263
232template<void func(u8)> void Wrap() { 264template <void func(u8)>
265void Wrap() {
233 func((u8)PARAM(0)); 266 func((u8)PARAM(0));
234} 267}
235 268
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index 5c5373517..41b772163 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -4,7 +4,6 @@
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7
8#include "core/arm/arm_interface.h" 7#include "core/arm/arm_interface.h"
9#include "core/core.h" 8#include "core/core.h"
10#include "core/hle/hle.h" 9#include "core/hle/hle.h"
@@ -15,13 +14,13 @@
15namespace { 14namespace {
16 15
17bool reschedule; ///< If true, immediately reschedules the CPU to a new thread 16bool reschedule; ///< If true, immediately reschedules the CPU to a new thread
18
19} 17}
20 18
21namespace HLE { 19namespace HLE {
22 20
23void Reschedule(const char *reason) { 21void Reschedule(const char* reason) {
24 DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, "Reschedule: Invalid or too long reason."); 22 DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256,
23 "Reschedule: Invalid or too long reason.");
25 24
26 // TODO(bunnei): It seems that games depend on some CPU execution time elapsing during HLE 25 // TODO(bunnei): It seems that games depend on some CPU execution time elapsing during HLE
27 // routines. This simulates that time by artificially advancing the number of CPU "ticks". 26 // routines. This simulates that time by artificially advancing the number of CPU "ticks".
diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h
index 69ac0ade6..23859e129 100644
--- a/src/core/hle/hle.h
+++ b/src/core/hle/hle.h
@@ -13,7 +13,7 @@ const Handle INVALID_HANDLE = 0;
13 13
14namespace HLE { 14namespace HLE {
15 15
16void Reschedule(const char *reason); 16void Reschedule(const char* reason);
17bool IsReschedulePending(); 17bool IsReschedulePending();
18void DoneRescheduling(); 18void DoneRescheduling();
19 19
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 5c3c47acf..37eec4c84 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -4,12 +4,10 @@
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7
8#include "core/memory.h"
9
10#include "core/hle/hle.h" 7#include "core/hle/hle.h"
11#include "core/hle/kernel/address_arbiter.h" 8#include "core/hle/kernel/address_arbiter.h"
12#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
10#include "core/memory.h"
13 11
14//////////////////////////////////////////////////////////////////////////////////////////////////// 12////////////////////////////////////////////////////////////////////////////////////////////////////
15// Kernel namespace 13// Kernel namespace
@@ -28,7 +26,7 @@ SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) {
28} 26}
29 27
30ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, 28ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value,
31 u64 nanoseconds) { 29 u64 nanoseconds) {
32 switch (type) { 30 switch (type) {
33 31
34 // Signal thread(s) waiting for arbitrate address... 32 // Signal thread(s) waiting for arbitrate address...
@@ -38,7 +36,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
38 ArbitrateAllThreads(address); 36 ArbitrateAllThreads(address);
39 } else { 37 } else {
40 // Resume first N threads 38 // Resume first N threads
41 for(int i = 0; i < value; i++) 39 for (int i = 0; i < value; i++)
42 ArbitrateHighestPriorityThread(address); 40 ArbitrateHighestPriorityThread(address);
43 } 41 }
44 break; 42 break;
@@ -55,8 +53,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
55 GetCurrentThread()->WakeAfterDelay(nanoseconds); 53 GetCurrentThread()->WakeAfterDelay(nanoseconds);
56 } 54 }
57 break; 55 break;
58 case ArbitrationType::DecrementAndWaitIfLessThan: 56 case ArbitrationType::DecrementAndWaitIfLessThan: {
59 {
60 s32 memory_value = Memory::Read32(address); 57 s32 memory_value = Memory::Read32(address);
61 if (memory_value < value) { 58 if (memory_value < value) {
62 // Only change the memory value if the thread should wait 59 // Only change the memory value if the thread should wait
@@ -65,8 +62,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
65 } 62 }
66 break; 63 break;
67 } 64 }
68 case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: 65 case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: {
69 {
70 s32 memory_value = Memory::Read32(address); 66 s32 memory_value = Memory::Read32(address);
71 if (memory_value < value) { 67 if (memory_value < value) {
72 // Only change the memory value if the thread should wait 68 // Only change the memory value if the thread should wait
@@ -79,17 +75,19 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address,
79 75
80 default: 76 default:
81 LOG_ERROR(Kernel, "unknown type=%d", type); 77 LOG_ERROR(Kernel, "unknown type=%d", type);
82 return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, ErrorSummary::WrongArgument, ErrorLevel::Usage); 78 return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel,
79 ErrorSummary::WrongArgument, ErrorLevel::Usage);
83 } 80 }
84 81
85 HLE::Reschedule(__func__); 82 HLE::Reschedule(__func__);
86 83
87 // The calls that use a timeout seem to always return a Timeout error even if they did not put the thread to sleep 84 // The calls that use a timeout seem to always return a Timeout error even if they did not put
85 // the thread to sleep
88 if (type == ArbitrationType::WaitIfLessThanWithTimeout || 86 if (type == ArbitrationType::WaitIfLessThanWithTimeout ||
89 type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) { 87 type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) {
90 88
91 return ResultCode(ErrorDescription::Timeout, ErrorModule::OS, 89 return ResultCode(ErrorDescription::Timeout, ErrorModule::OS, ErrorSummary::StatusChanged,
92 ErrorSummary::StatusChanged, ErrorLevel::Info); 90 ErrorLevel::Info);
93 } 91 }
94 return RESULT_SUCCESS; 92 return RESULT_SUCCESS;
95} 93}
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
index 8f6a1a8df..6a7af93a9 100644
--- a/src/core/hle/kernel/address_arbiter.h
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8
9#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/kernel.h"
10 9
11// Address arbiters are an underlying kernel synchronization object that can be created/used via 10// Address arbiters are an underlying kernel synchronization object that can be created/used via
@@ -36,13 +35,19 @@ public:
36 */ 35 */
37 static SharedPtr<AddressArbiter> Create(std::string name = "Unknown"); 36 static SharedPtr<AddressArbiter> Create(std::string name = "Unknown");
38 37
39 std::string GetTypeName() const override { return "Arbiter"; } 38 std::string GetTypeName() const override {
40 std::string GetName() const override { return name; } 39 return "Arbiter";
40 }
41 std::string GetName() const override {
42 return name;
43 }
41 44
42 static const HandleType HANDLE_TYPE = HandleType::AddressArbiter; 45 static const HandleType HANDLE_TYPE = HandleType::AddressArbiter;
43 HandleType GetHandleType() const override { return HANDLE_TYPE; } 46 HandleType GetHandleType() const override {
47 return HANDLE_TYPE;
48 }
44 49
45 std::string name; ///< Name of address arbiter object (optional) 50 std::string name; ///< Name of address arbiter object (optional)
46 51
47 ResultCode ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); 52 ResultCode ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, u64 nanoseconds);
48 53
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
index 444ce8d45..aedc6f989 100644
--- a/src/core/hle/kernel/client_port.cpp
+++ b/src/core/hle/kernel/client_port.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6
7#include "core/hle/kernel/client_port.h" 6#include "core/hle/kernel/client_port.h"
8#include "core/hle/kernel/kernel.h" 7#include "core/hle/kernel/kernel.h"
9#include "core/hle/kernel/server_port.h" 8#include "core/hle/kernel/server_port.h"
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index 480b6ddae..d28147718 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -5,9 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10
11#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
12 10
13namespace Kernel { 11namespace Kernel {
@@ -17,16 +15,22 @@ class ServerPort;
17class ClientPort : public Object { 15class ClientPort : public Object {
18public: 16public:
19 friend class ServerPort; 17 friend class ServerPort;
20 std::string GetTypeName() const override { return "ClientPort"; } 18 std::string GetTypeName() const override {
21 std::string GetName() const override { return name; } 19 return "ClientPort";
20 }
21 std::string GetName() const override {
22 return name;
23 }
22 24
23 static const HandleType HANDLE_TYPE = HandleType::ClientPort; 25 static const HandleType HANDLE_TYPE = HandleType::ClientPort;
24 HandleType GetHandleType() const override { return HANDLE_TYPE; } 26 HandleType GetHandleType() const override {
25 27 return HANDLE_TYPE;
26 SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. 28 }
27 u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have 29
28 u32 active_sessions; ///< Number of currently open sessions to this port 30 SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
29 std::string name; ///< Name of client port (optional) 31 u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have
32 u32 active_sessions; ///< Number of currently open sessions to this port
33 std::string name; ///< Name of client port (optional)
30 34
31protected: 35protected:
32 ClientPort(); 36 ClientPort();
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 2b7c6992a..1489c7002 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -2,14 +2,12 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map>
6#include <algorithm> 5#include <algorithm>
6#include <map>
7#include <vector> 7#include <vector>
8
9#include "common/assert.h" 8#include "common/assert.h"
10
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/thread.h" 11#include "core/hle/kernel/thread.h"
14 12
15namespace Kernel { 13namespace Kernel {
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h
index 73d0da419..6fe74065d 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/event.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8
9#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/kernel.h"
10 9
11namespace Kernel { 10namespace Kernel {
@@ -16,7 +15,6 @@ enum class ResetType {
16 Pulse, 15 Pulse,
17}; 16};
18 17
19
20class Event final : public WaitObject { 18class Event final : public WaitObject {
21public: 19public:
22 /** 20 /**
@@ -26,16 +24,22 @@ public:
26 */ 24 */
27 static SharedPtr<Event> Create(ResetType reset_type, std::string name = "Unknown"); 25 static SharedPtr<Event> Create(ResetType reset_type, std::string name = "Unknown");
28 26
29 std::string GetTypeName() const override { return "Event"; } 27 std::string GetTypeName() const override {
30 std::string GetName() const override { return name; } 28 return "Event";
29 }
30 std::string GetName() const override {
31 return name;
32 }
31 33
32 static const HandleType HANDLE_TYPE = HandleType::Event; 34 static const HandleType HANDLE_TYPE = HandleType::Event;
33 HandleType GetHandleType() const override { return HANDLE_TYPE; } 35 HandleType GetHandleType() const override {
36 return HANDLE_TYPE;
37 }
34 38
35 ResetType reset_type; ///< Current ResetType 39 ResetType reset_type; ///< Current ResetType
36 40
37 bool signaled; ///< Whether the event has already been signaled 41 bool signaled; ///< Whether the event has already been signaled
38 std::string name; ///< Name of event (optional) 42 std::string name; ///< Name of event (optional)
39 43
40 bool ShouldWait() override; 44 bool ShouldWait() override;
41 void Acquire() override; 45 void Acquire() override;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7a401a965..9a2c8ce05 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -3,10 +3,8 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6
7#include "common/assert.h" 6#include "common/assert.h"
8#include "common/logging/log.h" 7#include "common/logging/log.h"
9
10#include "core/hle/config_mem.h" 8#include "core/hle/config_mem.h"
11#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/memory.h" 10#include "core/hle/kernel/memory.h"
@@ -61,7 +59,8 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
61 59
62 // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. 60 // Overflow count so it fits in the 15 bits dedicated to the generation in the handle.
63 // CTR-OS doesn't use generation 0, so skip straight to 1. 61 // CTR-OS doesn't use generation 0, so skip straight to 1.
64 if (next_generation >= (1 << 15)) next_generation = 1; 62 if (next_generation >= (1 << 15))
63 next_generation = 1;
65 64
66 generations[slot] = generation; 65 generations[slot] = generation;
67 objects[slot] = std::move(obj); 66 objects[slot] = std::move(obj);
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 27ba3f912..0e95f7ff0 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,16 +4,13 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <boost/smart_ptr/intrusive_ptr.hpp>
8
9#include <algorithm> 7#include <algorithm>
10#include <array> 8#include <array>
11#include <cstddef> 9#include <cstddef>
12#include <string> 10#include <string>
13#include <vector> 11#include <vector>
14 12#include <boost/smart_ptr/intrusive_ptr.hpp>
15#include "common/common_types.h" 13#include "common/common_types.h"
16
17#include "core/hle/hle.h" 14#include "core/hle/hle.h"
18#include "core/hle/result.h" 15#include "core/hle/result.h"
19 16
@@ -23,37 +20,37 @@ class Thread;
23 20
24// TODO: Verify code 21// TODO: Verify code
25const ResultCode ERR_OUT_OF_HANDLES(ErrorDescription::OutOfMemory, ErrorModule::Kernel, 22const ResultCode ERR_OUT_OF_HANDLES(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
26 ErrorSummary::OutOfResource, ErrorLevel::Temporary); 23 ErrorSummary::OutOfResource, ErrorLevel::Temporary);
27// TOOD: Verify code 24// TOOD: Verify code
28const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel, 25const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel,
29 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 26 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
30 27
31enum KernelHandle : Handle { 28enum KernelHandle : Handle {
32 CurrentThread = 0xFFFF8000, 29 CurrentThread = 0xFFFF8000,
33 CurrentProcess = 0xFFFF8001, 30 CurrentProcess = 0xFFFF8001,
34}; 31};
35 32
36enum class HandleType : u32 { 33enum class HandleType : u32 {
37 Unknown = 0, 34 Unknown = 0,
38 35
39 Session = 2, 36 Session = 2,
40 Event = 3, 37 Event = 3,
41 Mutex = 4, 38 Mutex = 4,
42 SharedMemory = 5, 39 SharedMemory = 5,
43 Redirection = 6, 40 Redirection = 6,
44 Thread = 7, 41 Thread = 7,
45 Process = 8, 42 Process = 8,
46 AddressArbiter = 9, 43 AddressArbiter = 9,
47 Semaphore = 10, 44 Semaphore = 10,
48 Timer = 11, 45 Timer = 11,
49 ResourceLimit = 12, 46 ResourceLimit = 12,
50 CodeSet = 13, 47 CodeSet = 13,
51 ClientPort = 14, 48 ClientPort = 14,
52 ServerPort = 15, 49 ServerPort = 15,
53}; 50};
54 51
55enum { 52enum {
56 DEFAULT_STACK_SIZE = 0x4000, 53 DEFAULT_STACK_SIZE = 0x4000,
57}; 54};
58 55
59class Object : NonCopyable { 56class Object : NonCopyable {
@@ -61,10 +58,16 @@ public:
61 virtual ~Object() {} 58 virtual ~Object() {}
62 59
63 /// Returns a unique identifier for the object. For debugging purposes only. 60 /// Returns a unique identifier for the object. For debugging purposes only.
64 unsigned int GetObjectId() const { return object_id; } 61 unsigned int GetObjectId() const {
62 return object_id;
63 }
65 64
66 virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } 65 virtual std::string GetTypeName() const {
67 virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } 66 return "[BAD KERNEL OBJECT TYPE]";
67 }
68 virtual std::string GetName() const {
69 return "[UNKNOWN KERNEL OBJECT]";
70 }
68 virtual Kernel::HandleType GetHandleType() const = 0; 71 virtual Kernel::HandleType GetHandleType() const = 0;
69 72
70 /** 73 /**
@@ -122,7 +125,6 @@ using SharedPtr = boost::intrusive_ptr<T>;
122/// Class that represents a Kernel object that a thread can be waiting on 125/// Class that represents a Kernel object that a thread can be waiting on
123class WaitObject : public Object { 126class WaitObject : public Object {
124public: 127public:
125
126 /** 128 /**
127 * Check if the current thread should wait until the object is available 129 * Check if the current thread should wait until the object is available
128 * @return True if the current thread should wait due to this object being unavailable 130 * @return True if the current thread should wait due to this object being unavailable
@@ -247,8 +249,12 @@ private:
247 */ 249 */
248 static const size_t MAX_COUNT = 4096; 250 static const size_t MAX_COUNT = 4096;
249 251
250 static u16 GetSlot(Handle handle) { return handle >> 15; } 252 static u16 GetSlot(Handle handle) {
251 static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } 253 return handle >> 15;
254 }
255 static u16 GetGeneration(Handle handle) {
256 return handle & 0x7FFF;
257 }
252 258
253 /// Stores the Object referenced by the handle or null if the slot is empty. 259 /// Stores the Object referenced by the handle or null if the slot is empty.
254 std::array<SharedPtr<Object>, MAX_COUNT> objects; 260 std::array<SharedPtr<Object>, MAX_COUNT> objects;
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp
index 17ae87aef..e65fd5c41 100644
--- a/src/core/hle/kernel/memory.cpp
+++ b/src/core/hle/kernel/memory.cpp
@@ -6,12 +6,9 @@
6#include <memory> 6#include <memory>
7#include <utility> 7#include <utility>
8#include <vector> 8#include <vector>
9
10#include "audio_core/audio_core.h" 9#include "audio_core/audio_core.h"
11
12#include "common/common_types.h" 10#include "common/common_types.h"
13#include "common/logging/log.h" 11#include "common/logging/log.h"
14
15#include "core/hle/config_mem.h" 12#include "core/hle/config_mem.h"
16#include "core/hle/kernel/memory.h" 13#include "core/hle/kernel/memory.h"
17#include "core/hle/kernel/vm_manager.h" 14#include "core/hle/kernel/vm_manager.h"
@@ -31,7 +28,7 @@ static MemoryRegionInfo memory_regions[3];
31static const u32 memory_region_sizes[8][3] = { 28static const u32 memory_region_sizes[8][3] = {
32 // Old 3DS layouts 29 // Old 3DS layouts
33 {0x04000000, 0x02C00000, 0x01400000}, // 0 30 {0x04000000, 0x02C00000, 0x01400000}, // 0
34 { /* This appears to be unused. */ }, // 1 31 {/* This appears to be unused. */}, // 1
35 {0x06000000, 0x00C00000, 0x01400000}, // 2 32 {0x06000000, 0x00C00000, 0x01400000}, // 2
36 {0x05000000, 0x01C00000, 0x01400000}, // 3 33 {0x05000000, 0x01C00000, 0x01400000}, // 3
37 {0x04800000, 0x02400000, 0x01400000}, // 4 34 {0x04800000, 0x02400000, 0x01400000}, // 4
@@ -95,7 +92,6 @@ MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
95 UNREACHABLE(); 92 UNREACHABLE();
96 } 93 }
97} 94}
98
99} 95}
100 96
101namespace Memory { 97namespace Memory {
@@ -110,9 +106,8 @@ struct MemoryArea {
110 106
111// We don't declare the IO regions in here since its handled by other means. 107// We don't declare the IO regions in here since its handled by other means.
112static MemoryArea memory_areas[] = { 108static MemoryArea memory_areas[] = {
113 {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM) 109 {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM)
114}; 110};
115
116} 111}
117 112
118void Init() { 113void Init() {
@@ -125,15 +120,21 @@ void InitLegacyAddressSpace(Kernel::VMManager& address_space) {
125 120
126 for (MemoryArea& area : memory_areas) { 121 for (MemoryArea& area : memory_areas) {
127 auto block = std::make_shared<std::vector<u8>>(area.size); 122 auto block = std::make_shared<std::vector<u8>>(area.size);
128 address_space.MapMemoryBlock(area.base, std::move(block), 0, area.size, MemoryState::Private).Unwrap(); 123 address_space
124 .MapMemoryBlock(area.base, std::move(block), 0, area.size, MemoryState::Private)
125 .Unwrap();
129 } 126 }
130 127
131 auto cfg_mem_vma = address_space.MapBackingMemory(CONFIG_MEMORY_VADDR, 128 auto cfg_mem_vma = address_space
132 (u8*)&ConfigMem::config_mem, CONFIG_MEMORY_SIZE, MemoryState::Shared).MoveFrom(); 129 .MapBackingMemory(CONFIG_MEMORY_VADDR, (u8*)&ConfigMem::config_mem,
130 CONFIG_MEMORY_SIZE, MemoryState::Shared)
131 .MoveFrom();
133 address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); 132 address_space.Reprotect(cfg_mem_vma, VMAPermission::Read);
134 133
135 auto shared_page_vma = address_space.MapBackingMemory(SHARED_PAGE_VADDR, 134 auto shared_page_vma = address_space
136 (u8*)&SharedPage::shared_page, SHARED_PAGE_SIZE, MemoryState::Shared).MoveFrom(); 135 .MapBackingMemory(SHARED_PAGE_VADDR, (u8*)&SharedPage::shared_page,
136 SHARED_PAGE_SIZE, MemoryState::Shared)
137 .MoveFrom();
137 address_space.Reprotect(shared_page_vma, VMAPermission::Read); 138 address_space.Reprotect(shared_page_vma, VMAPermission::Read);
138 139
139 AudioCore::AddAddressSpace(address_space); 140 AudioCore::AddAddressSpace(address_space);
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h
index 091c1f89f..4e1856a41 100644
--- a/src/core/hle/kernel/memory.h
+++ b/src/core/hle/kernel/memory.h
@@ -5,9 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10
11#include "core/hle/kernel/process.h" 9#include "core/hle/kernel/process.h"
12 10
13namespace Kernel { 11namespace Kernel {
@@ -25,7 +23,6 @@ struct MemoryRegionInfo {
25void MemoryInit(u32 mem_type); 23void MemoryInit(u32 mem_type);
26void MemoryShutdown(); 24void MemoryShutdown();
27MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); 25MemoryRegionInfo* GetMemoryRegion(MemoryRegion region);
28
29} 26}
30 27
31namespace Memory { 28namespace Memory {
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index edb97d324..736944bae 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -4,11 +4,8 @@
4 4
5#include <map> 5#include <map>
6#include <vector> 6#include <vector>
7
8#include <boost/range/algorithm_ext/erase.hpp> 7#include <boost/range/algorithm_ext/erase.hpp>
9
10#include "common/assert.h" 8#include "common/assert.h"
11
12#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/mutex.h" 10#include "core/hle/kernel/mutex.h"
14#include "core/hle/kernel/thread.h" 11#include "core/hle/kernel/thread.h"
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
index 1746360e4..53c3dc1f1 100644
--- a/src/core/hle/kernel/mutex.h
+++ b/src/core/hle/kernel/mutex.h
@@ -5,9 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10
11#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
12 10
13namespace Kernel { 11namespace Kernel {
@@ -24,15 +22,21 @@ public:
24 */ 22 */
25 static SharedPtr<Mutex> Create(bool initial_locked, std::string name = "Unknown"); 23 static SharedPtr<Mutex> Create(bool initial_locked, std::string name = "Unknown");
26 24
27 std::string GetTypeName() const override { return "Mutex"; } 25 std::string GetTypeName() const override {
28 std::string GetName() const override { return name; } 26 return "Mutex";
27 }
28 std::string GetName() const override {
29 return name;
30 }
29 31
30 static const HandleType HANDLE_TYPE = HandleType::Mutex; 32 static const HandleType HANDLE_TYPE = HandleType::Mutex;
31 HandleType GetHandleType() const override { return HANDLE_TYPE; } 33 HandleType GetHandleType() const override {
34 return HANDLE_TYPE;
35 }
32 36
33 int lock_count; ///< Number of times the mutex has been acquired 37 int lock_count; ///< Number of times the mutex has been acquired
34 std::string name; ///< Name of mutex (optional) 38 std::string name; ///< Name of mutex (optional)
35 SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex 39 SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex
36 40
37 bool ShouldWait() override; 41 bool ShouldWait() override;
38 void Acquire() override; 42 void Acquire() override;
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 69302cc82..ba80fe7f8 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -3,11 +3,9 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <memory> 5#include <memory>
6
7#include "common/assert.h" 6#include "common/assert.h"
8#include "common/common_funcs.h" 7#include "common/common_funcs.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10
11#include "core/hle/kernel/memory.h" 9#include "core/hle/kernel/memory.h"
12#include "core/hle/kernel/process.h" 10#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 11#include "core/hle/kernel/resource_limit.h"
@@ -60,7 +58,8 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
60 58
61 while (bits && index < svc_access_mask.size()) { 59 while (bits && index < svc_access_mask.size()) {
62 svc_access_mask.set(index, bits & 1); 60 svc_access_mask.set(index, bits & 1);
63 ++index; bits >>= 1; 61 ++index;
62 bits >>= 1;
64 } 63 }
65 } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF 64 } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF
66 // Handle table size 65 // Handle table size
@@ -70,11 +69,11 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
70 flags.raw = descriptor & 0xFFFF; 69 flags.raw = descriptor & 0xFFFF;
71 } else if ((type & 0xFFE) == 0xFF8) { // 0x001F 70 } else if ((type & 0xFFE) == 0xFF8) { // 0x001F
72 // Mapped memory range 71 // Mapped memory range
73 if (i+1 >= len || ((kernel_caps[i+1] >> 20) & 0xFFE) != 0xFF8) { 72 if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) {
74 LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); 73 LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
75 continue; 74 continue;
76 } 75 }
77 u32 end_desc = kernel_caps[i+1]; 76 u32 end_desc = kernel_caps[i + 1];
78 ++i; // Skip over the second descriptor on the next iteration 77 ++i; // Skip over the second descriptor on the next iteration
79 78
80 AddressMapping mapping; 79 AddressMapping mapping;
@@ -107,23 +106,28 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
107void Process::Run(s32 main_thread_priority, u32 stack_size) { 106void Process::Run(s32 main_thread_priority, u32 stack_size) {
108 memory_region = GetMemoryRegion(flags.memory_region); 107 memory_region = GetMemoryRegion(flags.memory_region);
109 108
110 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, MemoryState memory_state) { 109 auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions,
111 auto vma = vm_manager.MapMemoryBlock(segment.addr, codeset->memory, 110 MemoryState memory_state) {
112 segment.offset, segment.size, memory_state).Unwrap(); 111 auto vma = vm_manager
112 .MapMemoryBlock(segment.addr, codeset->memory, segment.offset, segment.size,
113 memory_state)
114 .Unwrap();
113 vm_manager.Reprotect(vma, permissions); 115 vm_manager.Reprotect(vma, permissions);
114 misc_memory_used += segment.size; 116 misc_memory_used += segment.size;
115 memory_region->used += segment.size; 117 memory_region->used += segment.size;
116 }; 118 };
117 119
118 // Map CodeSet segments 120 // Map CodeSet segments
119 MapSegment(codeset->code, VMAPermission::ReadExecute, MemoryState::Code); 121 MapSegment(codeset->code, VMAPermission::ReadExecute, MemoryState::Code);
120 MapSegment(codeset->rodata, VMAPermission::Read, MemoryState::Code); 122 MapSegment(codeset->rodata, VMAPermission::Read, MemoryState::Code);
121 MapSegment(codeset->data, VMAPermission::ReadWrite, MemoryState::Private); 123 MapSegment(codeset->data, VMAPermission::ReadWrite, MemoryState::Private);
122 124
123 // Allocate and map stack 125 // Allocate and map stack
124 vm_manager.MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size, 126 vm_manager
125 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, MemoryState::Locked 127 .MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size,
126 ).Unwrap(); 128 std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
129 MemoryState::Locked)
130 .Unwrap();
127 misc_memory_used += stack_size; 131 misc_memory_used += stack_size;
128 memory_region->used += stack_size; 132 memory_region->used += stack_size;
129 133
@@ -143,7 +147,8 @@ VAddr Process::GetLinearHeapLimit() const {
143} 147}
144 148
145ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission perms) { 149ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission perms) {
146 if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || target + size < target) { 150 if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
151 target + size < target) {
147 return ERR_INVALID_ADDRESS; 152 return ERR_INVALID_ADDRESS;
148 } 153 }
149 154
@@ -166,7 +171,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
166 } 171 }
167 ASSERT(heap_end - heap_start == heap_memory->size()); 172 ASSERT(heap_end - heap_start == heap_memory->size());
168 173
169 CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, heap_memory, target - heap_start, size, MemoryState::Private)); 174 CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, heap_memory, target - heap_start,
175 size, MemoryState::Private));
170 vm_manager.Reprotect(vma, perms); 176 vm_manager.Reprotect(vma, perms);
171 177
172 heap_used += size; 178 heap_used += size;
@@ -176,7 +182,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per
176} 182}
177 183
178ResultCode Process::HeapFree(VAddr target, u32 size) { 184ResultCode Process::HeapFree(VAddr target, u32 size) {
179 if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || target + size < target) { 185 if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END ||
186 target + size < target) {
180 return ERR_INVALID_ADDRESS; 187 return ERR_INVALID_ADDRESS;
181 } 188 }
182 189
@@ -185,7 +192,8 @@ ResultCode Process::HeapFree(VAddr target, u32 size) {
185 } 192 }
186 193
187 ResultCode result = vm_manager.UnmapRange(target, size); 194 ResultCode result = vm_manager.UnmapRange(target, size);
188 if (result.IsError()) return result; 195 if (result.IsError())
196 return result;
189 197
190 heap_used -= size; 198 heap_used -= size;
191 memory_region->used -= size; 199 memory_region->used -= size;
@@ -203,8 +211,8 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
203 target = heap_end; 211 target = heap_end;
204 } 212 }
205 213
206 if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || 214 if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || target > heap_end ||
207 target > heap_end || target + size < target) { 215 target + size < target) {
208 216
209 return ERR_INVALID_ADDRESS; 217 return ERR_INVALID_ADDRESS;
210 } 218 }
@@ -220,7 +228,8 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p
220 // TODO(yuriks): As is, this lets processes map memory allocated by other processes from the 228 // TODO(yuriks): As is, this lets processes map memory allocated by other processes from the
221 // same region. It is unknown if or how the 3DS kernel checks against this. 229 // same region. It is unknown if or how the 3DS kernel checks against this.
222 size_t offset = target - GetLinearHeapBase(); 230 size_t offset = target - GetLinearHeapBase();
223 CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, linheap_memory, offset, size, MemoryState::Continuous)); 231 CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, linheap_memory, offset, size,
232 MemoryState::Continuous));
224 vm_manager.Reprotect(vma, perms); 233 vm_manager.Reprotect(vma, perms);
225 234
226 linear_heap_used += size; 235 linear_heap_used += size;
@@ -248,7 +257,8 @@ ResultCode Process::LinearFree(VAddr target, u32 size) {
248 } 257 }
249 258
250 ResultCode result = vm_manager.UnmapRange(target, size); 259 ResultCode result = vm_manager.UnmapRange(target, size);
251 if (result.IsError()) return result; 260 if (result.IsError())
261 return result;
252 262
253 linear_heap_used -= size; 263 linear_heap_used -= size;
254 memory_region->used -= size; 264 memory_region->used -= size;
@@ -272,5 +282,4 @@ Kernel::Process::Process() {}
272Kernel::Process::~Process() {} 282Kernel::Process::~Process() {}
273 283
274SharedPtr<Process> g_current_process; 284SharedPtr<Process> g_current_process;
275
276} 285}
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index d781ef32c..b566950b0 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -8,12 +8,9 @@
8#include <cstddef> 8#include <cstddef>
9#include <memory> 9#include <memory>
10#include <string> 10#include <string>
11
12#include <boost/container/static_vector.hpp> 11#include <boost/container/static_vector.hpp>
13
14#include "common/bit_field.h" 12#include "common/bit_field.h"
15#include "common/common_types.h" 13#include "common/common_types.h"
16
17#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/kernel.h"
18#include "core/hle/kernel/vm_manager.h" 15#include "core/hle/kernel/vm_manager.h"
19 16
@@ -36,15 +33,18 @@ enum class MemoryRegion : u16 {
36union ProcessFlags { 33union ProcessFlags {
37 u16 raw; 34 u16 raw;
38 35
39 BitField< 0, 1, u16> allow_debug; ///< Allows other processes to attach to and debug this process. 36 BitField<0, 1, u16>
40 BitField< 1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they don't have allow_debug set. 37 allow_debug; ///< Allows other processes to attach to and debug this process.
41 BitField< 2, 1, u16> allow_nonalphanum; 38 BitField<1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they
42 BitField< 3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions. 39 /// don't have allow_debug set.
43 BitField< 4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24. 40 BitField<2, 1, u16> allow_nonalphanum;
44 BitField< 5, 1, u16> allow_main_args; 41 BitField<3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions.
45 BitField< 6, 1, u16> shared_device_mem; 42 BitField<4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24.
46 BitField< 7, 1, u16> runnable_on_sleep; 43 BitField<5, 1, u16> allow_main_args;
47 BitField< 8, 4, MemoryRegion> memory_region; ///< Default region for memory allocations for this process 44 BitField<6, 1, u16> shared_device_mem;
45 BitField<7, 1, u16> runnable_on_sleep;
46 BitField<8, 4, MemoryRegion>
47 memory_region; ///< Default region for memory allocations for this process
48 BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). 48 BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
49}; 49};
50 50
@@ -54,11 +54,17 @@ struct MemoryRegionInfo;
54struct CodeSet final : public Object { 54struct CodeSet final : public Object {
55 static SharedPtr<CodeSet> Create(std::string name, u64 program_id); 55 static SharedPtr<CodeSet> Create(std::string name, u64 program_id);
56 56
57 std::string GetTypeName() const override { return "CodeSet"; } 57 std::string GetTypeName() const override {
58 std::string GetName() const override { return name; } 58 return "CodeSet";
59 }
60 std::string GetName() const override {
61 return name;
62 }
59 63
60 static const HandleType HANDLE_TYPE = HandleType::CodeSet; 64 static const HandleType HANDLE_TYPE = HandleType::CodeSet;
61 HandleType GetHandleType() const override { return HANDLE_TYPE; } 65 HandleType GetHandleType() const override {
66 return HANDLE_TYPE;
67 }
62 68
63 /// Name of the process 69 /// Name of the process
64 std::string name; 70 std::string name;
@@ -85,11 +91,17 @@ class Process final : public Object {
85public: 91public:
86 static SharedPtr<Process> Create(SharedPtr<CodeSet> code_set); 92 static SharedPtr<Process> Create(SharedPtr<CodeSet> code_set);
87 93
88 std::string GetTypeName() const override { return "Process"; } 94 std::string GetTypeName() const override {
89 std::string GetName() const override { return codeset->name; } 95 return "Process";
96 }
97 std::string GetName() const override {
98 return codeset->name;
99 }
90 100
91 static const HandleType HANDLE_TYPE = HandleType::Process; 101 static const HandleType HANDLE_TYPE = HandleType::Process;
92 HandleType GetHandleType() const override { return HANDLE_TYPE; } 102 HandleType GetHandleType() const override {
103 return HANDLE_TYPE;
104 }
93 105
94 static u32 next_process_id; 106 static u32 next_process_id;
95 107
@@ -124,7 +136,6 @@ public:
124 */ 136 */
125 void Run(s32 main_thread_priority, u32 stack_size); 137 void Run(s32 main_thread_priority, u32 stack_size);
126 138
127
128 /////////////////////////////////////////////////////////////////////////////////////////////// 139 ///////////////////////////////////////////////////////////////////////////////////////////////
129 // Memory Management 140 // Memory Management
130 141
@@ -144,7 +155,8 @@ public:
144 155
145 /// The Thread Local Storage area is allocated as processes create threads, 156 /// The Thread Local Storage area is allocated as processes create threads,
146 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part 157 /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part
147 /// holds the TLS for a specific thread. This vector contains which parts are in use for each page as a bitmask. 158 /// holds the TLS for a specific thread. This vector contains which parts are in use for each
159 /// page as a bitmask.
148 /// This vector will grow as more pages are allocated for new threads. 160 /// This vector will grow as more pages are allocated for new threads.
149 std::vector<std::bitset<8>> tls_slots; 161 std::vector<std::bitset<8>> tls_slots;
150 162
@@ -164,5 +176,4 @@ private:
164}; 176};
165 177
166extern SharedPtr<Process> g_current_process; 178extern SharedPtr<Process> g_current_process;
167
168} 179}
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
index 67dde08c2..253ab7045 100644
--- a/src/core/hle/kernel/resource_limit.cpp
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -3,9 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring> 5#include <cstring>
6
7#include "common/logging/log.h" 6#include "common/logging/log.h"
8
9#include "core/hle/kernel/resource_limit.h" 7#include "core/hle/kernel/resource_limit.h"
10 8
11namespace Kernel { 9namespace Kernel {
@@ -23,70 +21,69 @@ SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) {
23} 21}
24 22
25SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { 23SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) {
26 switch (category) 24 switch (category) {
27 { 25 case ResourceLimitCategory::APPLICATION:
28 case ResourceLimitCategory::APPLICATION: 26 case ResourceLimitCategory::SYS_APPLET:
29 case ResourceLimitCategory::SYS_APPLET: 27 case ResourceLimitCategory::LIB_APPLET:
30 case ResourceLimitCategory::LIB_APPLET: 28 case ResourceLimitCategory::OTHER:
31 case ResourceLimitCategory::OTHER: 29 return resource_limits[static_cast<u8>(category)];
32 return resource_limits[static_cast<u8>(category)]; 30 default:
33 default: 31 LOG_CRITICAL(Kernel, "Unknown resource limit category");
34 LOG_CRITICAL(Kernel, "Unknown resource limit category"); 32 UNREACHABLE();
35 UNREACHABLE();
36 } 33 }
37} 34}
38 35
39s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { 36s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const {
40 switch (resource) { 37 switch (resource) {
41 case COMMIT: 38 case COMMIT:
42 return current_commit; 39 return current_commit;
43 case THREAD: 40 case THREAD:
44 return current_threads; 41 return current_threads;
45 case EVENT: 42 case EVENT:
46 return current_events; 43 return current_events;
47 case MUTEX: 44 case MUTEX:
48 return current_mutexes; 45 return current_mutexes;
49 case SEMAPHORE: 46 case SEMAPHORE:
50 return current_semaphores; 47 return current_semaphores;
51 case TIMER: 48 case TIMER:
52 return current_timers; 49 return current_timers;
53 case SHARED_MEMORY: 50 case SHARED_MEMORY:
54 return current_shared_mems; 51 return current_shared_mems;
55 case ADDRESS_ARBITER: 52 case ADDRESS_ARBITER:
56 return current_address_arbiters; 53 return current_address_arbiters;
57 case CPU_TIME: 54 case CPU_TIME:
58 return current_cpu_time; 55 return current_cpu_time;
59 default: 56 default:
60 LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); 57 LOG_ERROR(Kernel, "Unknown resource type=%08X", resource);
61 UNIMPLEMENTED(); 58 UNIMPLEMENTED();
62 return 0; 59 return 0;
63 } 60 }
64} 61}
65 62
66s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { 63s32 ResourceLimit::GetMaxResourceValue(u32 resource) const {
67 switch (resource) { 64 switch (resource) {
68 case COMMIT: 65 case COMMIT:
69 return max_commit; 66 return max_commit;
70 case THREAD: 67 case THREAD:
71 return max_threads; 68 return max_threads;
72 case EVENT: 69 case EVENT:
73 return max_events; 70 return max_events;
74 case MUTEX: 71 case MUTEX:
75 return max_mutexes; 72 return max_mutexes;
76 case SEMAPHORE: 73 case SEMAPHORE:
77 return max_semaphores; 74 return max_semaphores;
78 case TIMER: 75 case TIMER:
79 return max_timers; 76 return max_timers;
80 case SHARED_MEMORY: 77 case SHARED_MEMORY:
81 return max_shared_mems; 78 return max_shared_mems;
82 case ADDRESS_ARBITER: 79 case ADDRESS_ARBITER:
83 return max_address_arbiters; 80 return max_address_arbiters;
84 case CPU_TIME: 81 case CPU_TIME:
85 return max_cpu_time; 82 return max_cpu_time;
86 default: 83 default:
87 LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); 84 LOG_ERROR(Kernel, "Unknown resource type=%08X", resource);
88 UNIMPLEMENTED(); 85 UNIMPLEMENTED();
89 return 0; 86 return 0;
90 } 87 }
91} 88}
92 89
@@ -149,8 +146,6 @@ void ResourceLimitsInit() {
149 resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit; 146 resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
150} 147}
151 148
152void ResourceLimitsShutdown() { 149void ResourceLimitsShutdown() {}
153
154}
155 150
156} // namespace 151} // namespace
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 1b8249c74..6cdfbcf8d 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -5,29 +5,28 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8
9#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/kernel.h"
10 9
11namespace Kernel { 10namespace Kernel {
12 11
13enum class ResourceLimitCategory : u8 { 12enum class ResourceLimitCategory : u8 {
14 APPLICATION = 0, 13 APPLICATION = 0,
15 SYS_APPLET = 1, 14 SYS_APPLET = 1,
16 LIB_APPLET = 2, 15 LIB_APPLET = 2,
17 OTHER = 3 16 OTHER = 3
18}; 17};
19 18
20enum ResourceTypes { 19enum ResourceTypes {
21 PRIORITY = 0, 20 PRIORITY = 0,
22 COMMIT = 1, 21 COMMIT = 1,
23 THREAD = 2, 22 THREAD = 2,
24 EVENT = 3, 23 EVENT = 3,
25 MUTEX = 4, 24 MUTEX = 4,
26 SEMAPHORE = 5, 25 SEMAPHORE = 5,
27 TIMER = 6, 26 TIMER = 6,
28 SHARED_MEMORY = 7, 27 SHARED_MEMORY = 7,
29 ADDRESS_ARBITER = 8, 28 ADDRESS_ARBITER = 8,
30 CPU_TIME = 9, 29 CPU_TIME = 9,
31}; 30};
32 31
33class ResourceLimit final : public Object { 32class ResourceLimit final : public Object {
@@ -44,11 +43,17 @@ public:
44 */ 43 */
45 static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category); 44 static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
46 45
47 std::string GetTypeName() const override { return "ResourceLimit"; } 46 std::string GetTypeName() const override {
48 std::string GetName() const override { return name; } 47 return "ResourceLimit";
48 }
49 std::string GetName() const override {
50 return name;
51 }
49 52
50 static const HandleType HANDLE_TYPE = HandleType::ResourceLimit; 53 static const HandleType HANDLE_TYPE = HandleType::ResourceLimit;
51 HandleType GetHandleType() const override { return HANDLE_TYPE; } 54 HandleType GetHandleType() const override {
55 return HANDLE_TYPE;
56 }
52 57
53 /** 58 /**
54 * Gets the current value for the specified resource. 59 * Gets the current value for the specified resource.
@@ -85,10 +90,12 @@ public:
85 /// Max CPU time that the processes in this category can utilize 90 /// Max CPU time that the processes in this category can utilize
86 s32 max_cpu_time = 0; 91 s32 max_cpu_time = 0;
87 92
88 // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that 93 // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind
89 // APPLICATION resource limits should not be affected by the objects created by service modules. 94 // that APPLICATION resource limits should not be affected by the objects created by service
95 // modules.
90 // Currently we have no way of distinguishing if a Create was called by the running application, 96 // Currently we have no way of distinguishing if a Create was called by the running application,
91 // or by a service module. Approach this once we have separated the service modules into their own processes 97 // or by a service module. Approach this once we have separated the service modules into their
98 // own processes
92 99
93 /// Current memory that the processes in this category are using 100 /// Current memory that the processes in this category are using
94 s32 current_commit = 0; 101 s32 current_commit = 0;
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index 4b359ed07..bf7600780 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6
7#include "core/hle/kernel/kernel.h" 6#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/semaphore.h" 7#include "core/hle/kernel/semaphore.h"
9#include "core/hle/kernel/thread.h" 8#include "core/hle/kernel/thread.h"
@@ -14,7 +13,7 @@ Semaphore::Semaphore() {}
14Semaphore::~Semaphore() {} 13Semaphore::~Semaphore() {}
15 14
16ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, 15ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count,
17 std::string name) { 16 std::string name) {
18 17
19 if (initial_count > max_count) 18 if (initial_count > max_count)
20 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, 19 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel,
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h
index 390f5e495..e01908a25 100644
--- a/src/core/hle/kernel/semaphore.h
+++ b/src/core/hle/kernel/semaphore.h
@@ -6,9 +6,7 @@
6 6
7#include <queue> 7#include <queue>
8#include <string> 8#include <string>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
13 11
14namespace Kernel { 12namespace Kernel {
@@ -23,17 +21,23 @@ public:
23 * @return The created semaphore 21 * @return The created semaphore
24 */ 22 */
25 static ResultVal<SharedPtr<Semaphore>> Create(s32 initial_count, s32 max_count, 23 static ResultVal<SharedPtr<Semaphore>> Create(s32 initial_count, s32 max_count,
26 std::string name = "Unknown"); 24 std::string name = "Unknown");
27 25
28 std::string GetTypeName() const override { return "Semaphore"; } 26 std::string GetTypeName() const override {
29 std::string GetName() const override { return name; } 27 return "Semaphore";
28 }
29 std::string GetName() const override {
30 return name;
31 }
30 32
31 static const HandleType HANDLE_TYPE = HandleType::Semaphore; 33 static const HandleType HANDLE_TYPE = HandleType::Semaphore;
32 HandleType GetHandleType() const override { return HANDLE_TYPE; } 34 HandleType GetHandleType() const override {
35 return HANDLE_TYPE;
36 }
33 37
34 s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have 38 s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have
35 s32 available_count; ///< Number of free slots left in the semaphore 39 s32 available_count; ///< Number of free slots left in the semaphore
36 std::string name; ///< Name of semaphore (optional) 40 std::string name; ///< Name of semaphore (optional)
37 41
38 bool ShouldWait() override; 42 bool ShouldWait() override;
39 void Acquire() override; 43 void Acquire() override;
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
index fcc684a20..8e3ec8a14 100644
--- a/src/core/hle/kernel/server_port.cpp
+++ b/src/core/hle/kernel/server_port.cpp
@@ -3,9 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <tuple> 5#include <tuple>
6
7#include "common/assert.h" 6#include "common/assert.h"
8
9#include "core/hle/kernel/client_port.h" 7#include "core/hle/kernel/client_port.h"
10#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/server_port.h" 9#include "core/hle/kernel/server_port.h"
@@ -25,7 +23,9 @@ void ServerPort::Acquire() {
25 ASSERT_MSG(!ShouldWait(), "object unavailable!"); 23 ASSERT_MSG(!ShouldWait(), "object unavailable!");
26} 24}
27 25
28std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(u32 max_sessions, std::string name) { 26std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(
27 u32 max_sessions, std::string name) {
28
29 SharedPtr<ServerPort> server_port(new ServerPort); 29 SharedPtr<ServerPort> server_port(new ServerPort);
30 SharedPtr<ClientPort> client_port(new ClientPort); 30 SharedPtr<ClientPort> client_port(new ClientPort);
31 31
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index e9c972ce6..fa9448ca0 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -6,9 +6,7 @@
6 6
7#include <string> 7#include <string>
8#include <tuple> 8#include <tuple>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
13 11
14namespace Kernel { 12namespace Kernel {
@@ -23,17 +21,25 @@ public:
23 * @param name Optional name of the ports 21 * @param name Optional name of the ports
24 * @return The created port tuple 22 * @return The created port tuple
25 */ 23 */
26 static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(u32 max_sessions, std::string name = "UnknownPort"); 24 static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(
25 u32 max_sessions, std::string name = "UnknownPort");
27 26
28 std::string GetTypeName() const override { return "ServerPort"; } 27 std::string GetTypeName() const override {
29 std::string GetName() const override { return name; } 28 return "ServerPort";
29 }
30 std::string GetName() const override {
31 return name;
32 }
30 33
31 static const HandleType HANDLE_TYPE = HandleType::ServerPort; 34 static const HandleType HANDLE_TYPE = HandleType::ServerPort;
32 HandleType GetHandleType() const override { return HANDLE_TYPE; } 35 HandleType GetHandleType() const override {
36 return HANDLE_TYPE;
37 }
33 38
34 std::string name; ///< Name of port (optional) 39 std::string name; ///< Name of port (optional)
35 40
36 std::vector<SharedPtr<WaitObject>> pending_sessions; ///< ServerSessions waiting to be accepted by the port 41 std::vector<SharedPtr<WaitObject>>
42 pending_sessions; ///< ServerSessions waiting to be accepted by the port
37 43
38 bool ShouldWait() override; 44 bool ShouldWait() override;
39 void Acquire() override; 45 void Acquire() override;
diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp
index 0594967f8..8a2a7e3fd 100644
--- a/src/core/hle/kernel/session.cpp
+++ b/src/core/hle/kernel/session.cpp
@@ -9,5 +9,4 @@ namespace Kernel {
9 9
10Session::Session() {} 10Session::Session() {}
11Session::~Session() {} 11Session::~Session() {}
12
13} 12}
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index 8ec889967..ec025f732 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -5,10 +5,8 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8
9#include "common/assert.h" 8#include "common/assert.h"
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/thread.h" 11#include "core/hle/kernel/thread.h"
14#include "core/hle/result.h" 12#include "core/hle/result.h"
@@ -19,12 +17,13 @@ namespace IPC {
19enum DescriptorType : u32 { 17enum DescriptorType : u32 {
20 // Buffer related desciptors types (mask : 0x0F) 18 // Buffer related desciptors types (mask : 0x0F)
21 StaticBuffer = 0x02, 19 StaticBuffer = 0x02,
22 PXIBuffer = 0x04, 20 PXIBuffer = 0x04,
23 MappedBuffer = 0x08, 21 MappedBuffer = 0x08,
24 // Handle related descriptors types (mask : 0x30, but need to check for buffer related descriptors first ) 22 // Handle related descriptors types (mask : 0x30, but need to check for buffer related
25 CopyHandle = 0x00, 23 // descriptors first )
26 MoveHandle = 0x10, 24 CopyHandle = 0x00,
27 CallingPid = 0x20, 25 MoveHandle = 0x10,
26 CallingPid = 0x20,
28}; 27};
29 28
30/** 29/**
@@ -34,24 +33,28 @@ enum DescriptorType : u32 {
34 * @param translate_params_size Size of the translate parameters in words. Up to 63. 33 * @param translate_params_size Size of the translate parameters in words. Up to 63.
35 * @return The created IPC header. 34 * @return The created IPC header.
36 * 35 *
37 * Normal parameters are sent directly to the process while the translate parameters might go through modifications and checks by the kernel. 36 * Normal parameters are sent directly to the process while the translate parameters might go
37 * through modifications and checks by the kernel.
38 * The translate parameters are described by headers generated with the IPC::*Desc functions. 38 * The translate parameters are described by headers generated with the IPC::*Desc functions.
39 * 39 *
40 * @note While #normal_params is equivalent to the number of normal parameters, #translate_params_size includes the size occupied by the translate parameters headers. 40 * @note While #normal_params is equivalent to the number of normal parameters,
41 * #translate_params_size includes the size occupied by the translate parameters headers.
41 */ 42 */
42constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, unsigned int translate_params_size) { 43constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params,
43 return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | (u32(translate_params_size) & 0x3F); 44 unsigned int translate_params_size) {
45 return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) |
46 (u32(translate_params_size) & 0x3F);
44} 47}
45 48
46union Header { 49union Header {
47 u32 raw; 50 u32 raw;
48 BitField< 0, 6, u32> translate_params_size; 51 BitField<0, 6, u32> translate_params_size;
49 BitField< 6, 6, u32> normal_params; 52 BitField<6, 6, u32> normal_params;
50 BitField<16, 16, u32> command_id; 53 BitField<16, 16, u32> command_id;
51}; 54};
52 55
53inline Header ParseHeader(u32 header) { 56inline Header ParseHeader(u32 header) {
54 return{ header }; 57 return {header};
55} 58}
56 59
57constexpr u32 MoveHandleDesc(u32 num_handles = 1) { 60constexpr u32 MoveHandleDesc(u32 num_handles = 1) {
@@ -80,27 +83,29 @@ constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) {
80 83
81union StaticBufferDescInfo { 84union StaticBufferDescInfo {
82 u32 raw; 85 u32 raw;
83 BitField< 10, 4, u32> buffer_id; 86 BitField<10, 4, u32> buffer_id;
84 BitField< 14, 18, u32> size; 87 BitField<14, 18, u32> size;
85}; 88};
86 89
87inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { 90inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) {
88 return{ desc }; 91 return {desc};
89} 92}
90 93
91/** 94/**
92 * @brief Creates a header describing a buffer to be sent over PXI. 95 * @brief Creates a header describing a buffer to be sent over PXI.
93 * @param size Size of the buffer. Max 0x00FFFFFF. 96 * @param size Size of the buffer. Max 0x00FFFFFF.
94 * @param buffer_id The Id of the buffer. Max 0xF. 97 * @param buffer_id The Id of the buffer. Max 0xF.
95 * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have read-write access. 98 * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have
99 * read-write access.
96 * @return The created PXI buffer header. 100 * @return The created PXI buffer header.
97 * 101 *
98 * The next value is a phys-address of a table located in the BASE memregion. 102 * The next value is a phys-address of a table located in the BASE memregion.
99 */ 103 */
100inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { 104inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) {
101 u32 type = PXIBuffer; 105 u32 type = PXIBuffer;
102 if (is_read_only) type |= 0x2; 106 if (is_read_only)
103 return type | (size << 8) | ((buffer_id & 0xF) << 4); 107 type |= 0x2;
108 return type | (size << 8) | ((buffer_id & 0xF) << 4);
104} 109}
105 110
106enum MappedBufferPermissions { 111enum MappedBufferPermissions {
@@ -115,12 +120,12 @@ constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) {
115 120
116union MappedBufferDescInfo { 121union MappedBufferDescInfo {
117 u32 raw; 122 u32 raw;
118 BitField< 4, 28, u32> size; 123 BitField<4, 28, u32> size;
119 BitField< 1, 2, MappedBufferPermissions> perms; 124 BitField<1, 2, MappedBufferPermissions> perms;
120}; 125};
121 126
122inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { 127inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) {
123 return{ desc }; 128 return {desc};
124} 129}
125 130
126inline DescriptorType GetDescriptorType(u32 descriptor) { 131inline DescriptorType GetDescriptorType(u32 descriptor) {
@@ -153,7 +158,8 @@ static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of
153 * @return Pointer to command buffer 158 * @return Pointer to command buffer
154 */ 159 */
155inline u32* GetCommandBuffer(const int offset = 0) { 160inline u32* GetCommandBuffer(const int offset = 0) {
156 return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + offset); 161 return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset +
162 offset);
157} 163}
158 164
159/** 165/**
@@ -183,10 +189,14 @@ public:
183 Session(); 189 Session();
184 ~Session() override; 190 ~Session() override;
185 191
186 std::string GetTypeName() const override { return "Session"; } 192 std::string GetTypeName() const override {
193 return "Session";
194 }
187 195
188 static const HandleType HANDLE_TYPE = HandleType::Session; 196 static const HandleType HANDLE_TYPE = HandleType::Session;
189 HandleType GetHandleType() const override { return HANDLE_TYPE; } 197 HandleType GetHandleType() const override {
198 return HANDLE_TYPE;
199 }
190 200
191 /** 201 /**
192 * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls 202 * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
@@ -205,5 +215,4 @@ public:
205 ASSERT_MSG(!ShouldWait(), "object unavailable!"); 215 ASSERT_MSG(!ShouldWait(), "object unavailable!");
206 } 216 }
207}; 217};
208
209} 218}
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 6a22c8986..bc1560d12 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -3,20 +3,20 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring> 5#include <cstring>
6
7#include "common/logging/log.h" 6#include "common/logging/log.h"
8
9#include "core/memory.h"
10#include "core/hle/kernel/memory.h" 7#include "core/hle/kernel/memory.h"
11#include "core/hle/kernel/shared_memory.h" 8#include "core/hle/kernel/shared_memory.h"
9#include "core/memory.h"
12 10
13namespace Kernel { 11namespace Kernel {
14 12
15SharedMemory::SharedMemory() {} 13SharedMemory::SharedMemory() {}
16SharedMemory::~SharedMemory() {} 14SharedMemory::~SharedMemory() {}
17 15
18SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, MemoryPermission permissions, 16SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size,
19 MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { 17 MemoryPermission permissions,
18 MemoryPermission other_permissions, VAddr address,
19 MemoryRegion region, std::string name) {
20 SharedPtr<SharedMemory> shared_memory(new SharedMemory); 20 SharedPtr<SharedMemory> shared_memory(new SharedMemory);
21 21
22 shared_memory->owner_process = owner_process; 22 shared_memory->owner_process = owner_process;
@@ -31,7 +31,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
31 MemoryRegionInfo* memory_region = GetMemoryRegion(region); 31 MemoryRegionInfo* memory_region = GetMemoryRegion(region);
32 auto& linheap_memory = memory_region->linear_heap_memory; 32 auto& linheap_memory = memory_region->linear_heap_memory;
33 33
34 ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, "Not enough space in region to allocate shared memory!"); 34 ASSERT_MSG(linheap_memory->size() + size <= memory_region->size,
35 "Not enough space in region to allocate shared memory!");
35 36
36 shared_memory->backing_block = linheap_memory; 37 shared_memory->backing_block = linheap_memory;
37 shared_memory->backing_block_offset = linheap_memory->size(); 38 shared_memory->backing_block_offset = linheap_memory->size();
@@ -39,7 +40,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
39 linheap_memory->insert(linheap_memory->end(), size, 0); 40 linheap_memory->insert(linheap_memory->end(), size, 0);
40 memory_region->used += size; 41 memory_region->used += size;
41 42
42 shared_memory->linear_heap_phys_address = Memory::FCRAM_PADDR + memory_region->base + shared_memory->backing_block_offset; 43 shared_memory->linear_heap_phys_address =
44 Memory::FCRAM_PADDR + memory_region->base + shared_memory->backing_block_offset;
43 45
44 // Increase the amount of used linear heap memory for the owner process. 46 // Increase the amount of used linear heap memory for the owner process.
45 if (shared_memory->owner_process != nullptr) { 47 if (shared_memory->owner_process != nullptr) {
@@ -51,18 +53,20 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
51 Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); 53 Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get());
52 } 54 }
53 } else { 55 } else {
54 // TODO(Subv): What happens if an application tries to create multiple memory blocks pointing to the same address? 56 // TODO(Subv): What happens if an application tries to create multiple memory blocks
57 // pointing to the same address?
55 auto& vm_manager = shared_memory->owner_process->vm_manager; 58 auto& vm_manager = shared_memory->owner_process->vm_manager;
56 // The memory is already available and mapped in the owner process. 59 // The memory is already available and mapped in the owner process.
57 auto vma = vm_manager.FindVMA(address)->second; 60 auto vma = vm_manager.FindVMA(address)->second;
58 // Copy it over to our own storage 61 // Copy it over to our own storage
59 shared_memory->backing_block = std::make_shared<std::vector<u8>>(vma.backing_block->data() + vma.offset, 62 shared_memory->backing_block = std::make_shared<std::vector<u8>>(
60 vma.backing_block->data() + vma.offset + size); 63 vma.backing_block->data() + vma.offset, vma.backing_block->data() + vma.offset + size);
61 shared_memory->backing_block_offset = 0; 64 shared_memory->backing_block_offset = 0;
62 // Unmap the existing pages 65 // Unmap the existing pages
63 vm_manager.UnmapRange(address, size); 66 vm_manager.UnmapRange(address, size);
64 // Map our own block into the address space 67 // Map our own block into the address space
65 vm_manager.MapMemoryBlock(address, shared_memory->backing_block, 0, size, MemoryState::Shared); 68 vm_manager.MapMemoryBlock(address, shared_memory->backing_block, 0, size,
69 MemoryState::Shared);
66 // Reprotect the block with the new permissions 70 // Reprotect the block with the new permissions
67 vm_manager.ReprotectRange(address, size, ConvertPermissions(permissions)); 71 vm_manager.ReprotectRange(address, size, ConvertPermissions(permissions));
68 } 72 }
@@ -71,8 +75,11 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
71 return shared_memory; 75 return shared_memory;
72} 76}
73 77
74SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, 78SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block,
75 MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { 79 u32 offset, u32 size,
80 MemoryPermission permissions,
81 MemoryPermission other_permissions,
82 std::string name) {
76 SharedPtr<SharedMemory> shared_memory(new SharedMemory); 83 SharedPtr<SharedMemory> shared_memory(new SharedMemory);
77 84
78 shared_memory->owner_process = nullptr; 85 shared_memory->owner_process = nullptr;
@@ -88,27 +95,31 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vecto
88} 95}
89 96
90ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermission permissions, 97ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermission permissions,
91 MemoryPermission other_permissions) { 98 MemoryPermission other_permissions) {
92 99
93 MemoryPermission own_other_permissions = target_process == owner_process ? this->permissions : this->other_permissions; 100 MemoryPermission own_other_permissions =
101 target_process == owner_process ? this->permissions : this->other_permissions;
94 102
95 // Automatically allocated memory blocks can only be mapped with other_permissions = DontCare 103 // Automatically allocated memory blocks can only be mapped with other_permissions = DontCare
96 if (base_address == 0 && other_permissions != MemoryPermission::DontCare) { 104 if (base_address == 0 && other_permissions != MemoryPermission::DontCare) {
97 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 105 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
106 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
98 } 107 }
99 108
100 // Error out if the requested permissions don't match what the creator process allows. 109 // Error out if the requested permissions don't match what the creator process allows.
101 if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) { 110 if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
102 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match", 111 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
103 GetObjectId(), address, name.c_str()); 112 GetObjectId(), address, name.c_str());
104 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 113 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
114 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
105 } 115 }
106 116
107 // Heap-backed memory blocks can not be mapped with other_permissions = DontCare 117 // Heap-backed memory blocks can not be mapped with other_permissions = DontCare
108 if (base_address != 0 && other_permissions == MemoryPermission::DontCare) { 118 if (base_address != 0 && other_permissions == MemoryPermission::DontCare) {
109 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match", 119 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
110 GetObjectId(), address, name.c_str()); 120 GetObjectId(), address, name.c_str());
111 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 121 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
122 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
112 } 123 }
113 124
114 // Error out if the provided permissions are not compatible with what the creator process needs. 125 // Error out if the provided permissions are not compatible with what the creator process needs.
@@ -116,12 +127,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
116 static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) { 127 static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
117 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match", 128 LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
118 GetObjectId(), address, name.c_str()); 129 GetObjectId(), address, name.c_str());
119 return ResultCode(ErrorDescription::WrongPermission, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 130 return ResultCode(ErrorDescription::WrongPermission, ErrorModule::OS,
131 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
120 } 132 }
121 133
122 // TODO(Subv): Check for the Shared Device Mem flag in the creator process. 134 // TODO(Subv): Check for the Shared Device Mem flag in the creator process.
123 /*if (was_created_with_shared_device_mem && address != 0) { 135 /*if (was_created_with_shared_device_mem && address != 0) {
124 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 136 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
137 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
125 }*/ 138 }*/
126 139
127 // TODO(Subv): The same process that created a SharedMemory object 140 // TODO(Subv): The same process that created a SharedMemory object
@@ -144,23 +157,29 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
144 } 157 }
145 158
146 // Map the memory block into the target process 159 // Map the memory block into the target process
147 auto result = target_process->vm_manager.MapMemoryBlock(target_address, backing_block, backing_block_offset, size, MemoryState::Shared); 160 auto result = target_process->vm_manager.MapMemoryBlock(
161 target_address, backing_block, backing_block_offset, size, MemoryState::Shared);
148 if (result.Failed()) { 162 if (result.Failed()) {
149 LOG_ERROR(Kernel, "cannot map id=%u, target_address=0x%08X name=%s, error mapping to virtual memory", 163 LOG_ERROR(
150 GetObjectId(), target_address, name.c_str()); 164 Kernel,
165 "cannot map id=%u, target_address=0x%08X name=%s, error mapping to virtual memory",
166 GetObjectId(), target_address, name.c_str());
151 return result.Code(); 167 return result.Code();
152 } 168 }
153 169
154 return target_process->vm_manager.ReprotectRange(target_address, size, ConvertPermissions(permissions)); 170 return target_process->vm_manager.ReprotectRange(target_address, size,
171 ConvertPermissions(permissions));
155} 172}
156 173
157ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) { 174ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) {
158 // TODO(Subv): Verify what happens if the application tries to unmap an address that is not mapped to a SharedMemory. 175 // TODO(Subv): Verify what happens if the application tries to unmap an address that is not
176 // mapped to a SharedMemory.
159 return target_process->vm_manager.UnmapRange(address, size); 177 return target_process->vm_manager.UnmapRange(address, size);
160} 178}
161 179
162VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { 180VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) {
163 u32 masked_permissions = static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute); 181 u32 masked_permissions =
182 static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute);
164 return static_cast<VMAPermission>(masked_permissions); 183 return static_cast<VMAPermission>(masked_permissions);
165}; 184};
166 185
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 0c404a9f8..94b335ed1 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -5,9 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8
9#include "common/common_types.h" 8#include "common/common_types.h"
10
11#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/process.h" 10#include "core/hle/kernel/process.h"
13#include "core/hle/result.h" 11#include "core/hle/result.h"
@@ -16,15 +14,15 @@ namespace Kernel {
16 14
17/// Permissions for mapped shared memory blocks 15/// Permissions for mapped shared memory blocks
18enum class MemoryPermission : u32 { 16enum class MemoryPermission : u32 {
19 None = 0, 17 None = 0,
20 Read = (1u << 0), 18 Read = (1u << 0),
21 Write = (1u << 1), 19 Write = (1u << 1),
22 ReadWrite = (Read | Write), 20 ReadWrite = (Read | Write),
23 Execute = (1u << 2), 21 Execute = (1u << 2),
24 ReadExecute = (Read | Execute), 22 ReadExecute = (Read | Execute),
25 WriteExecute = (Write | Execute), 23 WriteExecute = (Write | Execute),
26 ReadWriteExecute = (Read | Write | Execute), 24 ReadWriteExecute = (Read | Write | Execute),
27 DontCare = (1u << 28) 25 DontCare = (1u << 28)
28}; 26};
29 27
30class SharedMemory final : public Object { 28class SharedMemory final : public Object {
@@ -34,13 +32,18 @@ public:
34 * @param owner_process Process that created this shared memory object. 32 * @param owner_process Process that created this shared memory object.
35 * @param size Size of the memory block. Must be page-aligned. 33 * @param size Size of the memory block. Must be page-aligned.
36 * @param permissions Permission restrictions applied to the process which created the block. 34 * @param permissions Permission restrictions applied to the process which created the block.
37 * @param other_permissions Permission restrictions applied to other processes mapping the block. 35 * @param other_permissions Permission restrictions applied to other processes mapping the
36 * block.
38 * @param address The address from which to map the Shared Memory. 37 * @param address The address from which to map the Shared Memory.
39 * @param region If the address is 0, the shared memory will be allocated in this region of the linear heap. 38 * @param region If the address is 0, the shared memory will be allocated in this region of the
39 * linear heap.
40 * @param name Optional object name, used for debugging purposes. 40 * @param name Optional object name, used for debugging purposes.
41 */ 41 */
42 static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size, MemoryPermission permissions, 42 static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size,
43 MemoryPermission other_permissions, VAddr address = 0, MemoryRegion region = MemoryRegion::BASE, std::string name = "Unknown"); 43 MemoryPermission permissions,
44 MemoryPermission other_permissions, VAddr address = 0,
45 MemoryRegion region = MemoryRegion::BASE,
46 std::string name = "Unknown");
44 47
45 /** 48 /**
46 * Creates a shared memory object from a block of memory managed by an HLE applet. 49 * Creates a shared memory object from a block of memory managed by an HLE applet.
@@ -48,17 +51,27 @@ public:
48 * @param offset The offset into the heap block that the SharedMemory will map. 51 * @param offset The offset into the heap block that the SharedMemory will map.
49 * @param size Size of the memory block. Must be page-aligned. 52 * @param size Size of the memory block. Must be page-aligned.
50 * @param permissions Permission restrictions applied to the process which created the block. 53 * @param permissions Permission restrictions applied to the process which created the block.
51 * @param other_permissions Permission restrictions applied to other processes mapping the block. 54 * @param other_permissions Permission restrictions applied to other processes mapping the
55 * block.
52 * @param name Optional object name, used for debugging purposes. 56 * @param name Optional object name, used for debugging purposes.
53 */ 57 */
54 static SharedPtr<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, 58 static SharedPtr<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block,
55 MemoryPermission permissions, MemoryPermission other_permissions, std::string name = "Unknown Applet"); 59 u32 offset, u32 size,
56 60 MemoryPermission permissions,
57 std::string GetTypeName() const override { return "SharedMemory"; } 61 MemoryPermission other_permissions,
58 std::string GetName() const override { return name; } 62 std::string name = "Unknown Applet");
63
64 std::string GetTypeName() const override {
65 return "SharedMemory";
66 }
67 std::string GetName() const override {
68 return name;
69 }
59 70
60 static const HandleType HANDLE_TYPE = HandleType::SharedMemory; 71 static const HandleType HANDLE_TYPE = HandleType::SharedMemory;
61 HandleType GetHandleType() const override { return HANDLE_TYPE; } 72 HandleType GetHandleType() const override {
73 return HANDLE_TYPE;
74 }
62 75
63 /** 76 /**
64 * Converts the specified MemoryPermission into the equivalent VMAPermission. 77 * Converts the specified MemoryPermission into the equivalent VMAPermission.
@@ -73,7 +86,8 @@ public:
73 * @param permissions Memory block map permissions (specified by SVC field) 86 * @param permissions Memory block map permissions (specified by SVC field)
74 * @param other_permissions Memory block map other permissions (specified by SVC field) 87 * @param other_permissions Memory block map other permissions (specified by SVC field)
75 */ 88 */
76 ResultCode Map(Process* target_process, VAddr address, MemoryPermission permissions, MemoryPermission other_permissions); 89 ResultCode Map(Process* target_process, VAddr address, MemoryPermission permissions,
90 MemoryPermission other_permissions);
77 91
78 /** 92 /**
79 * Unmaps a shared memory block from the specified address in system memory 93 * Unmaps a shared memory block from the specified address in system memory
@@ -94,7 +108,8 @@ public:
94 SharedPtr<Process> owner_process; 108 SharedPtr<Process> owner_process;
95 /// Address of shared memory block in the owner process if specified. 109 /// Address of shared memory block in the owner process if specified.
96 VAddr base_address; 110 VAddr base_address;
97 /// Physical address of the shared memory block in the linear heap if no address was specified during creation. 111 /// Physical address of the shared memory block in the linear heap if no address was specified
112 /// during creation.
98 PAddr linear_heap_phys_address; 113 PAddr linear_heap_phys_address;
99 /// Backing memory for this shared memory block. 114 /// Backing memory for this shared memory block.
100 std::shared_ptr<std::vector<u8>> backing_block; 115 std::shared_ptr<std::vector<u8>> backing_block;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index f1e5cf3cb..4486a812c 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -5,23 +5,21 @@
5#include <algorithm> 5#include <algorithm>
6#include <list> 6#include <list>
7#include <vector> 7#include <vector>
8
9#include "common/assert.h" 8#include "common/assert.h"
10#include "common/common_types.h" 9#include "common/common_types.h"
11#include "common/logging/log.h" 10#include "common/logging/log.h"
12#include "common/math_util.h" 11#include "common/math_util.h"
13#include "common/thread_queue_list.h" 12#include "common/thread_queue_list.h"
14
15#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
16#include "core/arm/skyeye_common/armstate.h" 14#include "core/arm/skyeye_common/armstate.h"
17#include "core/core.h" 15#include "core/core.h"
18#include "core/core_timing.h" 16#include "core/core_timing.h"
19#include "core/hle/hle.h" 17#include "core/hle/hle.h"
20#include "core/hle/kernel/kernel.h" 18#include "core/hle/kernel/kernel.h"
21#include "core/hle/kernel/process.h"
22#include "core/hle/kernel/thread.h"
23#include "core/hle/kernel/memory.h" 19#include "core/hle/kernel/memory.h"
24#include "core/hle/kernel/mutex.h" 20#include "core/hle/kernel/mutex.h"
21#include "core/hle/kernel/process.h"
22#include "core/hle/kernel/thread.h"
25#include "core/hle/result.h" 23#include "core/hle/result.h"
26#include "core/memory.h" 24#include "core/memory.h"
27 25
@@ -46,7 +44,7 @@ static Kernel::HandleTable wakeup_callback_handle_table;
46static std::vector<SharedPtr<Thread>> thread_list; 44static std::vector<SharedPtr<Thread>> thread_list;
47 45
48// Lists only ready thread ids. 46// Lists only ready thread ids.
49static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> ready_queue; 47static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST + 1> ready_queue;
50 48
51static Thread* current_thread; 49static Thread* current_thread;
52 50
@@ -103,7 +101,7 @@ void Thread::Stop() {
103 101
104 // Clean up thread from ready queue 102 // Clean up thread from ready queue
105 // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) 103 // This is only needed when the thread is termintated forcefully (SVC TerminateProcess)
106 if (status == THREADSTATUS_READY){ 104 if (status == THREADSTATUS_READY) {
107 ready_queue.remove(current_priority, this); 105 ready_queue.remove(current_priority, this);
108 } 106 }
109 107
@@ -119,7 +117,8 @@ void Thread::Stop() {
119 117
120 // Mark the TLS slot in the thread's page as free. 118 // Mark the TLS slot in the thread's page as free.
121 u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; 119 u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE;
122 u32 tls_slot = ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; 120 u32 tls_slot =
121 ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE;
123 Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot); 122 Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot);
124 123
125 HLE::Reschedule(__func__); 124 HLE::Reschedule(__func__);
@@ -137,7 +136,7 @@ Thread* ArbitrateHighestPriorityThread(u32 address) {
137 if (thread == nullptr) 136 if (thread == nullptr)
138 continue; 137 continue;
139 138
140 if(thread->current_priority <= priority) { 139 if (thread->current_priority <= priority) {
141 highest_priority_thread = thread.get(); 140 highest_priority_thread = thread.get();
142 priority = thread->current_priority; 141 priority = thread->current_priority;
143 } 142 }
@@ -170,7 +169,7 @@ static void PriorityBoostStarvedThreads() {
170 // on hardware. However, this is almost certainly not perfect, and the real CTR OS scheduler 169 // on hardware. However, this is almost certainly not perfect, and the real CTR OS scheduler
171 // should probably be reversed to verify this. 170 // should probably be reversed to verify this.
172 171
173 const u64 boost_timeout = 2000000; // Boost threads that have been ready for > this long 172 const u64 boost_timeout = 2000000; // Boost threads that have been ready for > this long
174 173
175 u64 delta = current_ticks - thread->last_running_ticks; 174 u64 delta = current_ticks - thread->last_running_ticks;
176 175
@@ -193,10 +192,12 @@ static std::tuple<u32*, u32*> GetWaitSynchTimeoutParameterRegister(Thread* threa
193 192
194 if ((thumb_mode && thumb_inst == 0xDF24) || (!thumb_mode && inst == 0x0F000024)) { 193 if ((thumb_mode && thumb_inst == 0xDF24) || (!thumb_mode && inst == 0x0F000024)) {
195 // svc #0x24 (WaitSynchronization1) 194 // svc #0x24 (WaitSynchronization1)
196 return std::make_tuple(&thread->context.cpu_registers[2], &thread->context.cpu_registers[3]); 195 return std::make_tuple(&thread->context.cpu_registers[2],
196 &thread->context.cpu_registers[3]);
197 } else if ((thumb_mode && thumb_inst == 0xDF25) || (!thumb_mode && inst == 0x0F000025)) { 197 } else if ((thumb_mode && thumb_inst == 0xDF25) || (!thumb_mode && inst == 0x0F000025)) {
198 // svc #0x25 (WaitSynchronizationN) 198 // svc #0x25 (WaitSynchronizationN)
199 return std::make_tuple(&thread->context.cpu_registers[0], &thread->context.cpu_registers[4]); 199 return std::make_tuple(&thread->context.cpu_registers[0],
200 &thread->context.cpu_registers[4]);
200 } 201 }
201 202
202 UNREACHABLE(); 203 UNREACHABLE();
@@ -245,7 +246,8 @@ static void SwitchContext(Thread* new_thread) {
245 246
246 // Load context of new thread 247 // Load context of new thread
247 if (new_thread) { 248 if (new_thread) {
248 DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); 249 DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY,
250 "Thread must be ready to become running.");
249 251
250 // Cancel any outstanding wakeup events for this thread 252 // Cancel any outstanding wakeup events for this thread
251 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle); 253 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle);
@@ -263,7 +265,7 @@ static void SwitchContext(Thread* new_thread) {
263 new_thread->context.pc -= thumb_mode ? 2 : 4; 265 new_thread->context.pc -= thumb_mode ? 2 : 4;
264 266
265 // Get the register for timeout parameter 267 // Get the register for timeout parameter
266 u32* timeout_low, *timeout_high; 268 u32 *timeout_low, *timeout_high;
267 std::tie(timeout_low, timeout_high) = GetWaitSynchTimeoutParameterRegister(new_thread); 269 std::tie(timeout_low, timeout_high) = GetWaitSynchTimeoutParameterRegister(new_thread);
268 270
269 // Update the timeout parameter 271 // Update the timeout parameter
@@ -307,7 +309,7 @@ static Thread* PopNextReadyThread() {
307 // Otherwise just keep going with the current thread 309 // Otherwise just keep going with the current thread
308 next = thread; 310 next = thread;
309 } 311 }
310 } else { 312 } else {
311 next = ready_queue.pop_first(); 313 next = ready_queue.pop_first();
312 } 314 }
313 315
@@ -321,7 +323,8 @@ void WaitCurrentThread_Sleep() {
321 HLE::Reschedule(__func__); 323 HLE::Reschedule(__func__);
322} 324}
323 325
324void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, bool wait_set_output, bool wait_all) { 326void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects,
327 bool wait_set_output, bool wait_all) {
325 Thread* thread = GetCurrentThread(); 328 Thread* thread = GetCurrentThread();
326 thread->wait_set_output = wait_set_output; 329 thread->wait_set_output = wait_set_output;
327 thread->wait_all = wait_all; 330 thread->wait_all = wait_all;
@@ -352,7 +355,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
352 355
353 if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) { 356 if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) {
354 thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS, 357 thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS,
355 ErrorSummary::StatusChanged, ErrorLevel::Info)); 358 ErrorSummary::StatusChanged,
359 ErrorLevel::Info));
356 360
357 if (thread->wait_set_output) 361 if (thread->wait_set_output)
358 thread->SetWaitSynchronizationOutput(-1); 362 thread->SetWaitSynchronizationOutput(-1);
@@ -372,25 +376,25 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
372 376
373void Thread::ResumeFromWait() { 377void Thread::ResumeFromWait() {
374 switch (status) { 378 switch (status) {
375 case THREADSTATUS_WAIT_SYNCH: 379 case THREADSTATUS_WAIT_SYNCH:
376 case THREADSTATUS_WAIT_ARB: 380 case THREADSTATUS_WAIT_ARB:
377 case THREADSTATUS_WAIT_SLEEP: 381 case THREADSTATUS_WAIT_SLEEP:
378 break; 382 break;
379 383
380 case THREADSTATUS_READY: 384 case THREADSTATUS_READY:
381 // If the thread is waiting on multiple wait objects, it might be awoken more than once 385 // If the thread is waiting on multiple wait objects, it might be awoken more than once
382 // before actually resuming. We can ignore subsequent wakeups if the thread status has 386 // before actually resuming. We can ignore subsequent wakeups if the thread status has
383 // already been set to THREADSTATUS_READY. 387 // already been set to THREADSTATUS_READY.
384 return; 388 return;
385 389
386 case THREADSTATUS_RUNNING: 390 case THREADSTATUS_RUNNING:
387 DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId()); 391 DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId());
388 return; 392 return;
389 case THREADSTATUS_DEAD: 393 case THREADSTATUS_DEAD:
390 // This should never happen, as threads must complete before being stopped. 394 // This should never happen, as threads must complete before being stopped.
391 DEBUG_ASSERT_MSG(false, "Thread with object id %u cannot be resumed because it's DEAD.", 395 DEBUG_ASSERT_MSG(false, "Thread with object id %u cannot be resumed because it's DEAD.",
392 GetObjectId()); 396 GetObjectId());
393 return; 397 return;
394 } 398 }
395 399
396 ready_queue.push_back(current_priority, this); 400 ready_queue.push_back(current_priority, this);
@@ -405,7 +409,8 @@ static void DebugThreadQueue() {
405 if (!thread) { 409 if (!thread) {
406 LOG_DEBUG(Kernel, "Current: NO CURRENT THREAD"); 410 LOG_DEBUG(Kernel, "Current: NO CURRENT THREAD");
407 } else { 411 } else {
408 LOG_DEBUG(Kernel, "0x%02X %u (current)", thread->current_priority, GetCurrentThread()->GetObjectId()); 412 LOG_DEBUG(Kernel, "0x%02X %u (current)", thread->current_priority,
413 GetCurrentThread()->GetObjectId());
409 } 414 }
410 415
411 for (auto& t : thread_list) { 416 for (auto& t : thread_list) {
@@ -448,7 +453,8 @@ std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& t
448 * @param entry_point Address of entry point for execution 453 * @param entry_point Address of entry point for execution
449 * @param arg User argument for thread 454 * @param arg User argument for thread
450 */ 455 */
451static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point, u32 arg) { 456static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point,
457 u32 arg) {
452 memset(&context, 0, sizeof(Core::ThreadContext)); 458 memset(&context, 0, sizeof(Core::ThreadContext));
453 459
454 context.cpu_registers[0] = arg; 460 context.cpu_registers[0] = arg;
@@ -458,11 +464,11 @@ static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32
458} 464}
459 465
460ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority, 466ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority,
461 u32 arg, s32 processor_id, VAddr stack_top) { 467 u32 arg, s32 processor_id, VAddr stack_top) {
462 if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { 468 if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) {
463 s32 new_priority = MathUtil::Clamp<s32>(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); 469 s32 new_priority = MathUtil::Clamp<s32>(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST);
464 LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", 470 LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", name.c_str(),
465 name.c_str(), priority, new_priority); 471 priority, new_priority);
466 // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm 472 // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm
467 // validity of this 473 // validity of this
468 priority = new_priority; 474 priority = new_priority;
@@ -472,7 +478,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
472 LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point); 478 LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point);
473 // TODO: Verify error 479 // TODO: Verify error
474 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, 480 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
475 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 481 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
476 } 482 }
477 483
478 SharedPtr<Thread> thread(new Thread); 484 SharedPtr<Thread> thread(new Thread);
@@ -511,8 +517,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
511 auto& linheap_memory = memory_region->linear_heap_memory; 517 auto& linheap_memory = memory_region->linear_heap_memory;
512 518
513 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { 519 if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) {
514 LOG_ERROR(Kernel_SVC, "Not enough space in region to allocate a new TLS page for thread"); 520 LOG_ERROR(Kernel_SVC,
515 return ResultCode(ErrorDescription::OutOfMemory, ErrorModule::Kernel, ErrorSummary::OutOfResource, ErrorLevel::Permanent); 521 "Not enough space in region to allocate a new TLS page for thread");
522 return ResultCode(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
523 ErrorSummary::OutOfResource, ErrorLevel::Permanent);
516 } 524 }
517 525
518 u32 offset = linheap_memory->size(); 526 u32 offset = linheap_memory->size();
@@ -537,7 +545,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
537 545
538 // Mark the slot as used 546 // Mark the slot as used
539 tls_slots[available_page].set(available_slot); 547 tls_slots[available_page].set(available_slot);
540 thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + available_slot * Memory::TLS_ENTRY_SIZE; 548 thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE +
549 available_slot * Memory::TLS_ENTRY_SIZE;
541 550
542 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used 551 // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used
543 // to initialize the context 552 // to initialize the context
@@ -551,10 +560,12 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
551 return MakeResult<SharedPtr<Thread>>(std::move(thread)); 560 return MakeResult<SharedPtr<Thread>>(std::move(thread));
552} 561}
553 562
554// TODO(peachum): Remove this. Range checking should be done, and an appropriate error should be returned. 563// TODO(peachum): Remove this. Range checking should be done, and an appropriate error should be
564// returned.
555static void ClampPriority(const Thread* thread, s32* priority) { 565static void ClampPriority(const Thread* thread, s32* priority) {
556 if (*priority < THREADPRIO_HIGHEST || *priority > THREADPRIO_LOWEST) { 566 if (*priority < THREADPRIO_HIGHEST || *priority > THREADPRIO_LOWEST) {
557 DEBUG_ASSERT_MSG(false, "Application passed an out of range priority. An error should be returned."); 567 DEBUG_ASSERT_MSG(
568 false, "Application passed an out of range priority. An error should be returned.");
558 569
559 s32 new_priority = MathUtil::Clamp<s32>(*priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); 570 s32 new_priority = MathUtil::Clamp<s32>(*priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST);
560 LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", 571 LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d",
@@ -586,12 +597,13 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) {
586 DEBUG_ASSERT(!GetCurrentThread()); 597 DEBUG_ASSERT(!GetCurrentThread());
587 598
588 // Initialize new "main" thread 599 // Initialize new "main" thread
589 auto thread_res = Thread::Create("main", entry_point, priority, 0, 600 auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
590 THREADPROCESSORID_0, Memory::HEAP_VADDR_END); 601 Memory::HEAP_VADDR_END);
591 602
592 SharedPtr<Thread> thread = thread_res.MoveFrom(); 603 SharedPtr<Thread> thread = thread_res.MoveFrom();
593 604
594 thread->context.fpscr = FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010 605 thread->context.fpscr =
606 FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010
595 607
596 // Run new "main" thread 608 // Run new "main" thread
597 SwitchContext(thread.get()); 609 SwitchContext(thread.get());
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index deab5d5a6..f63131716 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -6,40 +6,36 @@
6 6
7#include <string> 7#include <string>
8#include <vector> 8#include <vector>
9
10#include <boost/container/flat_set.hpp> 9#include <boost/container/flat_set.hpp>
11
12#include "common/common_types.h" 10#include "common/common_types.h"
13
14#include "core/core.h" 11#include "core/core.h"
15
16#include "core/hle/hle.h" 12#include "core/hle/hle.h"
17#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
18#include "core/hle/result.h" 14#include "core/hle/result.h"
19 15
20enum ThreadPriority : s32{ 16enum ThreadPriority : s32 {
21 THREADPRIO_HIGHEST = 0, ///< Highest thread priority 17 THREADPRIO_HIGHEST = 0, ///< Highest thread priority
22 THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps 18 THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps
23 THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps 19 THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps
24 THREADPRIO_LOWEST = 63, ///< Lowest thread priority 20 THREADPRIO_LOWEST = 63, ///< Lowest thread priority
25}; 21};
26 22
27enum ThreadProcessorId : s32 { 23enum ThreadProcessorId : s32 {
28 THREADPROCESSORID_DEFAULT = -2, ///< Run thread on default core specified by exheader 24 THREADPROCESSORID_DEFAULT = -2, ///< Run thread on default core specified by exheader
29 THREADPROCESSORID_ALL = -1, ///< Run thread on either core 25 THREADPROCESSORID_ALL = -1, ///< Run thread on either core
30 THREADPROCESSORID_0 = 0, ///< Run thread on core 0 (AppCore) 26 THREADPROCESSORID_0 = 0, ///< Run thread on core 0 (AppCore)
31 THREADPROCESSORID_1 = 1, ///< Run thread on core 1 (SysCore) 27 THREADPROCESSORID_1 = 1, ///< Run thread on core 1 (SysCore)
32 THREADPROCESSORID_MAX = 2, ///< Processor ID must be less than this 28 THREADPROCESSORID_MAX = 2, ///< Processor ID must be less than this
33}; 29};
34 30
35enum ThreadStatus { 31enum ThreadStatus {
36 THREADSTATUS_RUNNING, ///< Currently running 32 THREADSTATUS_RUNNING, ///< Currently running
37 THREADSTATUS_READY, ///< Ready to run 33 THREADSTATUS_READY, ///< Ready to run
38 THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter 34 THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter
39 THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC 35 THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC
40 THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC 36 THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC
41 THREADSTATUS_DORMANT, ///< Created but not yet made ready 37 THREADSTATUS_DORMANT, ///< Created but not yet made ready
42 THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated 38 THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated
43}; 39};
44 40
45namespace Kernel { 41namespace Kernel {
@@ -60,13 +56,19 @@ public:
60 * @return A shared pointer to the newly created thread 56 * @return A shared pointer to the newly created thread
61 */ 57 */
62 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, 58 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority,
63 u32 arg, s32 processor_id, VAddr stack_top); 59 u32 arg, s32 processor_id, VAddr stack_top);
64 60
65 std::string GetName() const override { return name; } 61 std::string GetName() const override {
66 std::string GetTypeName() const override { return "Thread"; } 62 return name;
63 }
64 std::string GetTypeName() const override {
65 return "Thread";
66 }
67 67
68 static const HandleType HANDLE_TYPE = HandleType::Thread; 68 static const HandleType HANDLE_TYPE = HandleType::Thread;
69 HandleType GetHandleType() const override { return HANDLE_TYPE; } 69 HandleType GetHandleType() const override {
70 return HANDLE_TYPE;
71 }
70 72
71 bool ShouldWait() override; 73 bool ShouldWait() override;
72 void Acquire() override; 74 void Acquire() override;
@@ -75,7 +77,9 @@ public:
75 * Gets the thread's current priority 77 * Gets the thread's current priority
76 * @return The current thread's priority 78 * @return The current thread's priority
77 */ 79 */
78 s32 GetPriority() const { return current_priority; } 80 s32 GetPriority() const {
81 return current_priority;
82 }
79 83
80 /** 84 /**
81 * Sets the thread's current priority 85 * Sets the thread's current priority
@@ -93,7 +97,9 @@ public:
93 * Gets the thread's thread ID 97 * Gets the thread's thread ID
94 * @return The thread's ID 98 * @return The thread's ID
95 */ 99 */
96 u32 GetThreadId() const { return thread_id; } 100 u32 GetThreadId() const {
101 return thread_id;
102 }
97 103
98 /** 104 /**
99 * Resumes a thread from waiting 105 * Resumes a thread from waiting
@@ -127,7 +133,9 @@ public:
127 * Returns the Thread Local Storage address of the current thread 133 * Returns the Thread Local Storage address of the current thread
128 * @returns VAddr of the thread's TLS 134 * @returns VAddr of the thread's TLS
129 */ 135 */
130 VAddr GetTLSAddress() const { return tls_address; } 136 VAddr GetTLSAddress() const {
137 return tls_address;
138 }
131 139
132 Core::ThreadContext context; 140 Core::ThreadContext context;
133 141
@@ -137,8 +145,8 @@ public:
137 u32 entry_point; 145 u32 entry_point;
138 u32 stack_top; 146 u32 stack_top;
139 147
140 s32 nominal_priority; ///< Nominal thread priority, as set by the emulated application 148 s32 nominal_priority; ///< Nominal thread priority, as set by the emulated application
141 s32 current_priority; ///< Current thread priority, can be temporarily changed 149 s32 current_priority; ///< Current thread priority, can be temporarily changed
142 150
143 u64 last_running_ticks; ///< CPU tick when thread was last running 151 u64 last_running_ticks; ///< CPU tick when thread was last running
144 152
@@ -151,11 +159,11 @@ public:
151 /// Mutexes currently held by this thread, which will be released when it exits. 159 /// Mutexes currently held by this thread, which will be released when it exits.
152 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; 160 boost::container::flat_set<SharedPtr<Mutex>> held_mutexes;
153 161
154 SharedPtr<Process> owner_process; ///< Process that owns this thread 162 SharedPtr<Process> owner_process; ///< Process that owns this thread
155 std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on 163 std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on
156 VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address 164 VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address
157 bool wait_all; ///< True if the thread is waiting on all objects before resuming 165 bool wait_all; ///< True if the thread is waiting on all objects before resuming
158 bool wait_set_output; ///< True if the output parameter should be set on thread wakeup 166 bool wait_set_output; ///< True if the output parameter should be set on thread wakeup
159 167
160 std::string name; 168 std::string name;
161 169
@@ -205,10 +213,12 @@ void WaitCurrentThread_Sleep();
205/** 213/**
206 * Waits the current thread from a WaitSynchronization call 214 * Waits the current thread from a WaitSynchronization call
207 * @param wait_objects Kernel objects that we are waiting on 215 * @param wait_objects Kernel objects that we are waiting on
208 * @param wait_set_output If true, set the output parameter on thread wakeup (for WaitSynchronizationN only) 216 * @param wait_set_output If true, set the output parameter on thread wakeup (for
217 * WaitSynchronizationN only)
209 * @param wait_all If true, wait on all objects before resuming (for WaitSynchronizationN only) 218 * @param wait_all If true, wait on all objects before resuming (for WaitSynchronizationN only)
210 */ 219 */
211void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, bool wait_set_output, bool wait_all); 220void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects,
221 bool wait_set_output, bool wait_all);
212 222
213/** 223/**
214 * Waits the current thread from an ArbitrateAddress call 224 * Waits the current thread from an ArbitrateAddress call
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index b8daaeede..a9f98223c 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -3,14 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes> 5#include <cinttypes>
6
7#include "common/assert.h" 6#include "common/assert.h"
8#include "common/logging/log.h" 7#include "common/logging/log.h"
9
10#include "core/core_timing.h" 8#include "core/core_timing.h"
11#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
12#include "core/hle/kernel/timer.h"
13#include "core/hle/kernel/thread.h" 10#include "core/hle/kernel/thread.h"
11#include "core/hle/kernel/timer.h"
14 12
15namespace Kernel { 13namespace Kernel {
16 14
@@ -41,7 +39,7 @@ bool Timer::ShouldWait() {
41} 39}
42 40
43void Timer::Acquire() { 41void Timer::Acquire() {
44 ASSERT_MSG( !ShouldWait(), "object unavailable!"); 42 ASSERT_MSG(!ShouldWait(), "object unavailable!");
45 43
46 if (reset_type == ResetType::OneShot) 44 if (reset_type == ResetType::OneShot)
47 signaled = false; 45 signaled = false;
@@ -55,8 +53,8 @@ void Timer::Set(s64 initial, s64 interval) {
55 interval_delay = interval; 53 interval_delay = interval;
56 54
57 u64 initial_microseconds = initial / 1000; 55 u64 initial_microseconds = initial / 1000;
58 CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), 56 CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type,
59 timer_callback_event_type, callback_handle); 57 callback_handle);
60 58
61 HLE::Reschedule(__func__); 59 HLE::Reschedule(__func__);
62} 60}
@@ -73,7 +71,8 @@ void Timer::Clear() {
73 71
74/// The timer callback event, called when a timer is fired 72/// The timer callback event, called when a timer is fired
75static void TimerCallback(u64 timer_handle, int cycles_late) { 73static void TimerCallback(u64 timer_handle, int cycles_late) {
76 SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); 74 SharedPtr<Timer> timer =
75 timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
77 76
78 if (timer == nullptr) { 77 if (timer == nullptr) {
79 LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle); 78 LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle);
@@ -91,7 +90,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
91 // Reschedule the timer with the interval delay 90 // Reschedule the timer with the interval delay
92 u64 interval_microseconds = timer->interval_delay / 1000; 91 u64 interval_microseconds = timer->interval_delay / 1000;
93 CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, 92 CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late,
94 timer_callback_event_type, timer_handle); 93 timer_callback_event_type, timer_handle);
95 } 94 }
96} 95}
97 96
@@ -100,7 +99,6 @@ void TimersInit() {
100 timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); 99 timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
101} 100}
102 101
103void TimersShutdown() { 102void TimersShutdown() {}
104}
105 103
106} // namespace 104} // namespace
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index b1db60e8f..59a77aad3 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8
9#include "core/hle/kernel/event.h" 8#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
11 10
@@ -21,19 +20,25 @@ public:
21 */ 20 */
22 static SharedPtr<Timer> Create(ResetType reset_type, std::string name = "Unknown"); 21 static SharedPtr<Timer> Create(ResetType reset_type, std::string name = "Unknown");
23 22
24 std::string GetTypeName() const override { return "Timer"; } 23 std::string GetTypeName() const override {
25 std::string GetName() const override { return name; } 24 return "Timer";
25 }
26 std::string GetName() const override {
27 return name;
28 }
26 29
27 static const HandleType HANDLE_TYPE = HandleType::Timer; 30 static const HandleType HANDLE_TYPE = HandleType::Timer;
28 HandleType GetHandleType() const override { return HANDLE_TYPE; } 31 HandleType GetHandleType() const override {
32 return HANDLE_TYPE;
33 }
29 34
30 ResetType reset_type; ///< The ResetType of this timer 35 ResetType reset_type; ///< The ResetType of this timer
31 36
32 bool signaled; ///< Whether the timer has been signaled or not 37 bool signaled; ///< Whether the timer has been signaled or not
33 std::string name; ///< Name of timer (optional) 38 std::string name; ///< Name of timer (optional)
34 39
35 u64 initial_delay; ///< The delay until the timer fires for the first time 40 u64 initial_delay; ///< The delay until the timer fires for the first time
36 u64 interval_delay; ///< The delay until the timer fires after the first time 41 u64 interval_delay; ///< The delay until the timer fires after the first time
37 42
38 bool ShouldWait() override; 43 bool ShouldWait() override;
39 void Acquire() override; 44 void Acquire() override;
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index 066146cff..6dd24f846 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -3,9 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <iterator> 5#include <iterator>
6
7#include "common/assert.h" 6#include "common/assert.h"
8
9#include "core/hle/kernel/vm_manager.h" 7#include "core/hle/kernel/vm_manager.h"
10#include "core/memory.h" 8#include "core/memory.h"
11#include "core/memory_setup.h" 9#include "core/memory_setup.h"
@@ -15,8 +13,8 @@ namespace Kernel {
15 13
16static const char* GetMemoryStateName(MemoryState state) { 14static const char* GetMemoryStateName(MemoryState state) {
17 static const char* names[] = { 15 static const char* names[] = {
18 "Free", "Reserved", "IO", "Static", "Code", "Private", "Shared", "Continuous", "Aliased", 16 "Free", "Reserved", "IO", "Static", "Code", "Private",
19 "Alias", "AliasCode", "Locked", 17 "Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked",
20 }; 18 };
21 19
22 return names[(int)state]; 20 return names[(int)state];
@@ -24,13 +22,12 @@ static const char* GetMemoryStateName(MemoryState state) {
24 22
25bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { 23bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
26 ASSERT(base + size == next.base); 24 ASSERT(base + size == next.base);
27 if (permissions != next.permissions || 25 if (permissions != next.permissions || meminfo_state != next.meminfo_state ||
28 meminfo_state != next.meminfo_state || 26 type != next.type) {
29 type != next.type) {
30 return false; 27 return false;
31 } 28 }
32 if (type == VMAType::AllocatedMemoryBlock && 29 if (type == VMAType::AllocatedMemoryBlock &&
33 (backing_block != next.backing_block || offset + size != next.offset)) { 30 (backing_block != next.backing_block || offset + size != next.offset)) {
34 return false; 31 return false;
35 } 32 }
36 if (type == VMAType::BackingMemory && backing_memory + size != next.backing_memory) { 33 if (type == VMAType::BackingMemory && backing_memory + size != next.backing_memory) {
@@ -70,7 +67,9 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const {
70} 67}
71 68
72ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, 69ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
73 std::shared_ptr<std::vector<u8>> block, size_t offset, u32 size, MemoryState state) { 70 std::shared_ptr<std::vector<u8>> block,
71 size_t offset, u32 size,
72 MemoryState state) {
74 ASSERT(block != nullptr); 73 ASSERT(block != nullptr);
75 ASSERT(offset + size <= block->size()); 74 ASSERT(offset + size <= block->size());
76 75
@@ -89,7 +88,8 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
89 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); 88 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
90} 89}
91 90
92ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * memory, u32 size, MemoryState state) { 91ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8* memory, u32 size,
92 MemoryState state) {
93 ASSERT(memory != nullptr); 93 ASSERT(memory != nullptr);
94 94
95 // This is the appropriately sized VMA that will turn into our allocation. 95 // This is the appropriately sized VMA that will turn into our allocation.
@@ -106,7 +106,9 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * m
106 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); 106 return MakeResult<VMAHandle>(MergeAdjacent(vma_handle));
107} 107}
108 108
109ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler) { 109ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size,
110 MemoryState state,
111 Memory::MMIORegionPointer mmio_handler) {
110 // This is the appropriately sized VMA that will turn into our allocation. 112 // This is the appropriately sized VMA that will turn into our allocation.
111 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size)); 113 CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size));
112 VirtualMemoryArea& final_vma = vma_handle->second; 114 VirtualMemoryArea& final_vma = vma_handle->second;
@@ -191,15 +193,16 @@ void VMManager::RefreshMemoryBlockMappings(const std::vector<u8>* block) {
191void VMManager::LogLayout(Log::Level log_level) const { 193void VMManager::LogLayout(Log::Level log_level) const {
192 for (const auto& p : vma_map) { 194 for (const auto& p : vma_map) {
193 const VirtualMemoryArea& vma = p.second; 195 const VirtualMemoryArea& vma = p.second;
194 LOG_GENERIC(Log::Class::Kernel, log_level, "%08X - %08X size: %8X %c%c%c %s", 196 LOG_GENERIC(Log::Class::Kernel, log_level, "%08X - %08X size: %8X %c%c%c %s", vma.base,
195 vma.base, vma.base + vma.size, vma.size, 197 vma.base + vma.size, vma.size,
196 (u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-', 198 (u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-',
197 (u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-', 199 (u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-',
198 (u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-', GetMemoryStateName(vma.meminfo_state)); 200 (u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-',
201 GetMemoryStateName(vma.meminfo_state));
199 } 202 }
200} 203}
201 204
202VMManager::VMAIter VMManager::StripIterConstness(const VMAHandle & iter) { 205VMManager::VMAIter VMManager::StripIterConstness(const VMAHandle& iter) {
203 // This uses a neat C++ trick to convert a const_iterator to a regular iterator, given 206 // This uses a neat C++ trick to convert a const_iterator to a regular iterator, given
204 // non-const access to its container. 207 // non-const access to its container.
205 return vma_map.erase(iter, iter); // Erases an empty range of elements 208 return vma_map.erase(iter, iter); // Erases an empty range of elements
@@ -337,5 +340,4 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
337 break; 340 break;
338 } 341 }
339} 342}
340
341} 343}
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 91d40655b..9055664b2 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -7,21 +7,19 @@
7#include <map> 7#include <map>
8#include <memory> 8#include <memory>
9#include <vector> 9#include <vector>
10
11#include "common/common_types.h" 10#include "common/common_types.h"
12
13#include "core/hle/result.h" 11#include "core/hle/result.h"
14#include "core/mmio.h" 12#include "core/mmio.h"
15 13
16namespace Kernel { 14namespace Kernel {
17 15
18const ResultCode ERR_INVALID_ADDRESS{ // 0xE0E01BF5 16const ResultCode ERR_INVALID_ADDRESS{// 0xE0E01BF5
19 ErrorDescription::InvalidAddress, ErrorModule::OS, 17 ErrorDescription::InvalidAddress, ErrorModule::OS,
20 ErrorSummary::InvalidArgument, ErrorLevel::Usage}; 18 ErrorSummary::InvalidArgument, ErrorLevel::Usage};
21 19
22const ResultCode ERR_INVALID_ADDRESS_STATE{ // 0xE0A01BF5 20const ResultCode ERR_INVALID_ADDRESS_STATE{// 0xE0A01BF5
23 ErrorDescription::InvalidAddress, ErrorModule::OS, 21 ErrorDescription::InvalidAddress, ErrorModule::OS,
24 ErrorSummary::InvalidState, ErrorLevel::Usage}; 22 ErrorSummary::InvalidState, ErrorLevel::Usage};
25 23
26enum class VMAType : u8 { 24enum class VMAType : u8 {
27 /// VMA represents an unmapped region of the address space. 25 /// VMA represents an unmapped region of the address space.
@@ -115,7 +113,8 @@ class VMManager final {
115 // TODO(yuriks): Make page tables switchable to support multiple VMManagers 113 // TODO(yuriks): Make page tables switchable to support multiple VMManagers
116public: 114public:
117 /** 115 /**
118 * The maximum amount of address space managed by the kernel. Addresses above this are never used. 116 * The maximum amount of address space managed by the kernel. Addresses above this are never
117 * used.
119 * @note This is the limit used by the New 3DS kernel. Old 3DS used 0x20000000. 118 * @note This is the limit used by the New 3DS kernel. Old 3DS used 0x20000000.
120 */ 119 */
121 static const u32 MAX_ADDRESS = 0x40000000; 120 static const u32 MAX_ADDRESS = 0x40000000;
@@ -151,7 +150,7 @@ public:
151 * @param state MemoryState tag to attach to the VMA. 150 * @param state MemoryState tag to attach to the VMA.
152 */ 151 */
153 ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block, 152 ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block,
154 size_t offset, u32 size, MemoryState state); 153 size_t offset, u32 size, MemoryState state);
155 154
156 /** 155 /**
157 * Maps an unmanaged host memory pointer at a given address. 156 * Maps an unmanaged host memory pointer at a given address.
@@ -172,7 +171,8 @@ public:
172 * @param state MemoryState tag to attach to the VMA. 171 * @param state MemoryState tag to attach to the VMA.
173 * @param mmio_handler The handler that will implement read and write for this MMIO region. 172 * @param mmio_handler The handler that will implement read and write for this MMIO region.
174 */ 173 */
175 ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler); 174 ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state,
175 Memory::MMIORegionPointer mmio_handler);
176 176
177 /// Unmaps a range of addresses, splitting VMAs as necessary. 177 /// Unmaps a range of addresses, splitting VMAs as necessary.
178 ResultCode UnmapRange(VAddr target, u32 size); 178 ResultCode UnmapRange(VAddr target, u32 size);
@@ -228,5 +228,4 @@ private:
228 /// Updates the pages corresponding to this VMA so they match the VMA's attributes. 228 /// Updates the pages corresponding to this VMA so they match the VMA's attributes.
229 void UpdatePageTableForVMA(const VirtualMemoryArea& vma); 229 void UpdatePageTableForVMA(const VirtualMemoryArea& vma);
230}; 230};
231
232} 231}
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 268a8dad2..7f8d8e00d 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -6,7 +6,6 @@
6 6
7#include <new> 7#include <new>
8#include <utility> 8#include <utility>
9
10#include "common/assert.h" 9#include "common/assert.h"
11#include "common/bit_field.h" 10#include "common/bit_field.h"
12#include "common/common_funcs.h" 11#include "common/common_funcs.h"
@@ -26,7 +25,8 @@ enum class ErrorDescription : u32 {
26 FS_InvalidOpenFlags = 230, 25 FS_InvalidOpenFlags = 230,
27 FS_NotAFile = 250, 26 FS_NotAFile = 250,
28 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive 27 FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
29 OutofRangeOrMisalignedAddress = 513, // TODO(purpasmart): Check if this name fits its actual usage 28 OutofRangeOrMisalignedAddress =
29 513, // TODO(purpasmart): Check if this name fits its actual usage
30 GPU_FirstInitialization = 519, 30 GPU_FirstInitialization = 519,
31 FS_InvalidPath = 702, 31 FS_InvalidPath = 702,
32 InvalidSection = 1000, 32 InvalidSection = 1000,
@@ -168,15 +168,15 @@ enum class ErrorSummary : u32 {
168 Success = 0, 168 Success = 0,
169 NothingHappened = 1, 169 NothingHappened = 1,
170 WouldBlock = 2, 170 WouldBlock = 2,
171 OutOfResource = 3, ///< There are no more kernel resources (memory, table slots) to 171 OutOfResource = 3, ///< There are no more kernel resources (memory, table slots) to
172 ///< execute the operation. 172 ///< execute the operation.
173 NotFound = 4, ///< A file or resource was not found. 173 NotFound = 4, ///< A file or resource was not found.
174 InvalidState = 5, 174 InvalidState = 5,
175 NotSupported = 6, ///< The operation is not supported or not implemented. 175 NotSupported = 6, ///< The operation is not supported or not implemented.
176 InvalidArgument = 7, ///< Returned when a passed argument is invalid in the current runtime 176 InvalidArgument = 7, ///< Returned when a passed argument is invalid in the current runtime
177 ///< context. (Invalid handle, out-of-bounds pointer or size, etc.) 177 ///< context. (Invalid handle, out-of-bounds pointer or size, etc.)
178 WrongArgument = 8, ///< Returned when a passed argument is in an incorrect format for use 178 WrongArgument = 8, ///< Returned when a passed argument is in an incorrect format for use
179 ///< with the function. (E.g. Invalid enum value) 179 ///< with the function. (E.g. Invalid enum value)
180 Canceled = 9, 180 Canceled = 9,
181 StatusChanged = 10, 181 StatusChanged = 10,
182 Internal = 11, 182 Internal = 11,
@@ -208,19 +208,24 @@ union ResultCode {
208 BitField<21, 6, ErrorSummary> summary; 208 BitField<21, 6, ErrorSummary> summary;
209 BitField<27, 5, ErrorLevel> level; 209 BitField<27, 5, ErrorLevel> level;
210 210
211 // The last bit of `level` is checked by apps and the kernel to determine if a result code is an error 211 // The last bit of `level` is checked by apps and the kernel to determine if a result code is an
212 // error
212 BitField<31, 1, u32> is_error; 213 BitField<31, 1, u32> is_error;
213 214
214 explicit ResultCode(u32 raw) : raw(raw) {} 215 explicit ResultCode(u32 raw) : raw(raw) {}
215 ResultCode(ErrorDescription description_, ErrorModule module_, 216 ResultCode(ErrorDescription description_, ErrorModule module_, ErrorSummary summary_,
216 ErrorSummary summary_, ErrorLevel level_) : raw(0) { 217 ErrorLevel level_)
218 : raw(0) {
217 description.Assign(description_); 219 description.Assign(description_);
218 module.Assign(module_); 220 module.Assign(module_);
219 summary.Assign(summary_); 221 summary.Assign(summary_);
220 level.Assign(level_); 222 level.Assign(level_);
221 } 223 }
222 224
223 ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; } 225 ResultCode& operator=(const ResultCode& o) {
226 raw = o.raw;
227 return *this;
228 }
224 229
225 bool IsSuccess() const { 230 bool IsSuccess() const {
226 return is_error == 0; 231 return is_error == 0;
@@ -246,8 +251,8 @@ const ResultCode RESULT_SUCCESS(0);
246 251
247/// Might be returned instead of a dummy success for unimplemented APIs. 252/// Might be returned instead of a dummy success for unimplemented APIs.
248inline ResultCode UnimplementedFunction(ErrorModule module) { 253inline ResultCode UnimplementedFunction(ErrorModule module) {
249 return ResultCode(ErrorDescription::NotImplemented, module, 254 return ResultCode(ErrorDescription::NotImplemented, module, ErrorSummary::NotSupported,
250 ErrorSummary::NotSupported, ErrorLevel::Permanent); 255 ErrorLevel::Permanent);
251} 256}
252 257
253/** 258/**
@@ -285,10 +290,9 @@ inline ResultCode UnimplementedFunction(ErrorModule module) {
285template <typename T> 290template <typename T>
286class ResultVal { 291class ResultVal {
287public: 292public:
288 /// Constructs an empty `ResultVal` with the given error code. The code must not be a success code. 293 /// Constructs an empty `ResultVal` with the given error code. The code must not be a success
289 ResultVal(ResultCode error_code = ResultCode(-1)) 294 /// code.
290 : result_code(error_code) 295 ResultVal(ResultCode error_code = ResultCode(-1)) : result_code(error_code) {
291 {
292 ASSERT(error_code.IsError()); 296 ASSERT(error_code.IsError());
293 } 297 }
294 298
@@ -303,17 +307,13 @@ public:
303 return result; 307 return result;
304 } 308 }
305 309
306 ResultVal(const ResultVal& o) 310 ResultVal(const ResultVal& o) : result_code(o.result_code) {
307 : result_code(o.result_code)
308 {
309 if (!o.empty()) { 311 if (!o.empty()) {
310 new (&object) T(o.object); 312 new (&object) T(o.object);
311 } 313 }
312 } 314 }
313 315
314 ResultVal(ResultVal&& o) 316 ResultVal(ResultVal&& o) : result_code(o.result_code) {
315 : result_code(o.result_code)
316 {
317 if (!o.empty()) { 317 if (!o.empty()) {
318 new (&object) T(std::move(o.object)); 318 new (&object) T(std::move(o.object));
319 } 319 }
@@ -357,19 +357,35 @@ public:
357 } 357 }
358 358
359 /// Returns true if the `ResultVal` contains an error code and no value. 359 /// Returns true if the `ResultVal` contains an error code and no value.
360 bool empty() const { return result_code.IsError(); } 360 bool empty() const {
361 return result_code.IsError();
362 }
361 363
362 /// Returns true if the `ResultVal` contains a return value. 364 /// Returns true if the `ResultVal` contains a return value.
363 bool Succeeded() const { return result_code.IsSuccess(); } 365 bool Succeeded() const {
366 return result_code.IsSuccess();
367 }
364 /// Returns true if the `ResultVal` contains an error code and no value. 368 /// Returns true if the `ResultVal` contains an error code and no value.
365 bool Failed() const { return empty(); } 369 bool Failed() const {
370 return empty();
371 }
366 372
367 ResultCode Code() const { return result_code; } 373 ResultCode Code() const {
374 return result_code;
375 }
368 376
369 const T& operator* () const { return object; } 377 const T& operator*() const {
370 T& operator* () { return object; } 378 return object;
371 const T* operator->() const { return &object; } 379 }
372 T* operator->() { return &object; } 380 T& operator*() {
381 return object;
382 }
383 const T* operator->() const {
384 return &object;
385 }
386 T* operator->() {
387 return &object;
388 }
373 389
374 /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing. 390 /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing.
375 template <typename U> 391 template <typename U>
@@ -390,7 +406,9 @@ public:
390private: 406private:
391 // A union is used to allocate the storage for the value, while allowing us to construct and 407 // A union is used to allocate the storage for the value, while allowing us to construct and
392 // destruct it at will. 408 // destruct it at will.
393 union { T object; }; 409 union {
410 T object;
411 };
394 ResultCode result_code; 412 ResultCode result_code;
395}; 413};
396 414
@@ -409,8 +427,8 @@ ResultVal<T> MakeResult(Args&&... args) {
409 * variable declaration. If it fails the return code is returned from the current function. Thus it 427 * variable declaration. If it fails the return code is returned from the current function. Thus it
410 * can be used to cascade errors out, achieving something akin to exception handling. 428 * can be used to cascade errors out, achieving something akin to exception handling.
411 */ 429 */
412#define CASCADE_RESULT(target, source) \ 430#define CASCADE_RESULT(target, source) \
413 auto CONCAT2(check_result_L, __LINE__) = source; \ 431 auto CONCAT2(check_result_L, __LINE__) = source; \
414 if (CONCAT2(check_result_L, __LINE__).Failed()) \ 432 if (CONCAT2(check_result_L, __LINE__).Failed()) \
415 return CONCAT2(check_result_L, __LINE__).Code(); \ 433 return CONCAT2(check_result_L, __LINE__).Code(); \
416 target = std::move(*CONCAT2(check_result_L, __LINE__)) 434 target = std::move(*CONCAT2(check_result_L, __LINE__))
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index 5241dd3e7..12d94f37a 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6
7#include "core/hle/kernel/event.h" 6#include "core/hle/kernel/event.h"
8#include "core/hle/service/ac_u.h" 7#include "core/hle/service/ac_u.h"
9 8
@@ -47,7 +46,7 @@ static void GetWifiStatus(Service::Interface* self) {
47 // it returns a valid result without implementing full functionality. 46 // it returns a valid result without implementing full functionality.
48 47
49 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 48 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
50 cmd_buff[2] = 0; // Connection type set to none 49 cmd_buff[2] = 0; // Connection type set to none
51 50
52 LOG_WARNING(Service_AC, "(STUBBED) called"); 51 LOG_WARNING(Service_AC, "(STUBBED) called");
53} 52}
@@ -62,29 +61,29 @@ static void IsConnected(Service::Interface* self) {
62 u32* cmd_buff = Kernel::GetCommandBuffer(); 61 u32* cmd_buff = Kernel::GetCommandBuffer();
63 62
64 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 63 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
65 cmd_buff[2] = false; // Not connected to ac:u service 64 cmd_buff[2] = false; // Not connected to ac:u service
66 65
67 LOG_WARNING(Service_AC, "(STUBBED) called"); 66 LOG_WARNING(Service_AC, "(STUBBED) called");
68} 67}
69 68
70const Interface::FunctionInfo FunctionTable[] = { 69const Interface::FunctionInfo FunctionTable[] = {
71 {0x00010000, nullptr, "CreateDefaultConfig"}, 70 {0x00010000, nullptr, "CreateDefaultConfig"},
72 {0x00040006, nullptr, "ConnectAsync"}, 71 {0x00040006, nullptr, "ConnectAsync"},
73 {0x00050002, nullptr, "GetConnectResult"}, 72 {0x00050002, nullptr, "GetConnectResult"},
74 {0x00080004, CloseAsync, "CloseAsync"}, 73 {0x00080004, CloseAsync, "CloseAsync"},
75 {0x00090002, nullptr, "GetCloseResult"}, 74 {0x00090002, nullptr, "GetCloseResult"},
76 {0x000A0000, nullptr, "GetLastErrorCode"}, 75 {0x000A0000, nullptr, "GetLastErrorCode"},
77 {0x000D0000, GetWifiStatus, "GetWifiStatus"}, 76 {0x000D0000, GetWifiStatus, "GetWifiStatus"},
78 {0x000E0042, nullptr, "GetCurrentAPInfo"}, 77 {0x000E0042, nullptr, "GetCurrentAPInfo"},
79 {0x00100042, nullptr, "GetCurrentNZoneInfo"}, 78 {0x00100042, nullptr, "GetCurrentNZoneInfo"},
80 {0x00110042, nullptr, "GetNZoneApNumService"}, 79 {0x00110042, nullptr, "GetNZoneApNumService"},
81 {0x00240042, nullptr, "AddDenyApType"}, 80 {0x00240042, nullptr, "AddDenyApType"},
82 {0x00270002, nullptr, "GetInfraPriority"}, 81 {0x00270002, nullptr, "GetInfraPriority"},
83 {0x002D0082, nullptr, "SetRequestEulaVersion"}, 82 {0x002D0082, nullptr, "SetRequestEulaVersion"},
84 {0x00300004, nullptr, "RegisterDisconnectEvent"}, 83 {0x00300004, nullptr, "RegisterDisconnectEvent"},
85 {0x003C0042, nullptr, "GetAPSSIDList"}, 84 {0x003C0042, nullptr, "GetAPSSIDList"},
86 {0x003E0042, IsConnected, "IsConnected"}, 85 {0x003E0042, IsConnected, "IsConnected"},
87 {0x00400042, nullptr, "SetClientVersion"}, 86 {0x00400042, nullptr, "SetClientVersion"},
88}; 87};
89 88
90//////////////////////////////////////////////////////////////////////////////////////////////////// 89////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 3f71e7f2b..f7a990d69 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -3,22 +3,20 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes> 5#include <cinttypes>
6
7#include "common/logging/log.h" 6#include "common/logging/log.h"
8
9#include "core/hle/service/service.h"
10#include "core/hle/service/am/am.h" 7#include "core/hle/service/am/am.h"
11#include "core/hle/service/am/am_app.h" 8#include "core/hle/service/am/am_app.h"
12#include "core/hle/service/am/am_net.h" 9#include "core/hle/service/am/am_net.h"
13#include "core/hle/service/am/am_sys.h" 10#include "core/hle/service/am/am_sys.h"
14#include "core/hle/service/am/am_u.h" 11#include "core/hle/service/am/am_u.h"
12#include "core/hle/service/service.h"
15 13
16namespace Service { 14namespace Service {
17namespace AM { 15namespace AM {
18 16
19static std::array<u32, 3> am_content_count = { 0, 0, 0 }; 17static std::array<u32, 3> am_content_count = {0, 0, 0};
20static std::array<u32, 3> am_titles_count = { 0, 0, 0 }; 18static std::array<u32, 3> am_titles_count = {0, 0, 0};
21static std::array<u32, 3> am_titles_list_count = { 0, 0, 0 }; 19static std::array<u32, 3> am_titles_list_count = {0, 0, 0};
22static u32 am_ticket_count = 0; 20static u32 am_ticket_count = 0;
23static u32 am_ticket_list_count = 0; 21static u32 am_ticket_list_count = 0;
24 22
@@ -29,7 +27,8 @@ void GetTitleCount(Service::Interface* self) {
29 27
30 cmd_buff[1] = RESULT_SUCCESS.raw; 28 cmd_buff[1] = RESULT_SUCCESS.raw;
31 cmd_buff[2] = am_titles_count[media_type]; 29 cmd_buff[2] = am_titles_count[media_type];
32 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_count=0x%08x", media_type, am_titles_count[media_type]); 30 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_count=0x%08x", media_type,
31 am_titles_count[media_type]);
33} 32}
34 33
35void FindContentInfos(Service::Interface* self) { 34void FindContentInfos(Service::Interface* self) {
@@ -43,8 +42,10 @@ void FindContentInfos(Service::Interface* self) {
43 am_content_count[media_type] = cmd_buff[4]; 42 am_content_count[media_type] = cmd_buff[4];
44 43
45 cmd_buff[1] = RESULT_SUCCESS.raw; 44 cmd_buff[1] = RESULT_SUCCESS.raw;
46 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016llx, content_cound=%u, content_ids_pointer=0x%08x, content_info_pointer=0x%08x", 45 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016llx, content_cound=%u, "
47 media_type, title_id, am_content_count[media_type], content_ids_pointer, content_info_pointer); 46 "content_ids_pointer=0x%08x, content_info_pointer=0x%08x",
47 media_type, title_id, am_content_count[media_type], content_ids_pointer,
48 content_info_pointer);
48} 49}
49 50
50void ListContentInfos(Service::Interface* self) { 51void ListContentInfos(Service::Interface* self) {
@@ -59,8 +60,10 @@ void ListContentInfos(Service::Interface* self) {
59 60
60 cmd_buff[1] = RESULT_SUCCESS.raw; 61 cmd_buff[1] = RESULT_SUCCESS.raw;
61 cmd_buff[2] = am_content_count[media_type]; 62 cmd_buff[2] = am_content_count[media_type];
62 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, content_count=%u, title_id=0x%016" PRIx64 ", start_index=0x%08x, content_info_pointer=0x%08X", 63 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, content_count=%u, title_id=0x%016" PRIx64
63 media_type, am_content_count[media_type], title_id, start_index, content_info_pointer); 64 ", start_index=0x%08x, content_info_pointer=0x%08X",
65 media_type, am_content_count[media_type], title_id, start_index,
66 content_info_pointer);
64} 67}
65 68
66void DeleteContents(Service::Interface* self) { 69void DeleteContents(Service::Interface* self) {
@@ -73,8 +76,9 @@ void DeleteContents(Service::Interface* self) {
73 am_content_count[media_type] = cmd_buff[4]; 76 am_content_count[media_type] = cmd_buff[4];
74 77
75 cmd_buff[1] = RESULT_SUCCESS.raw; 78 cmd_buff[1] = RESULT_SUCCESS.raw;
76 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016" PRIx64 ", content_count=%u, content_ids_pointer=0x%08x", 79 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016" PRIx64
77 media_type, title_id, am_content_count[media_type], content_ids_pointer); 80 ", content_count=%u, content_ids_pointer=0x%08x",
81 media_type, title_id, am_content_count[media_type], content_ids_pointer);
78} 82}
79 83
80void GetTitleList(Service::Interface* self) { 84void GetTitleList(Service::Interface* self) {
@@ -87,8 +91,10 @@ void GetTitleList(Service::Interface* self) {
87 91
88 cmd_buff[1] = RESULT_SUCCESS.raw; 92 cmd_buff[1] = RESULT_SUCCESS.raw;
89 cmd_buff[2] = am_titles_list_count[media_type]; 93 cmd_buff[2] = am_titles_list_count[media_type];
90 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, titles_list_count=0x%08X, title_ids_output_pointer=0x%08X", 94 LOG_WARNING(
91 media_type, am_titles_list_count[media_type], title_ids_output_pointer); 95 Service_AM,
96 "(STUBBED) media_type=%u, titles_list_count=0x%08X, title_ids_output_pointer=0x%08X",
97 media_type, am_titles_list_count[media_type], title_ids_output_pointer);
92} 98}
93 99
94void GetTitleInfo(Service::Interface* self) { 100void GetTitleInfo(Service::Interface* self) {
@@ -101,7 +107,8 @@ void GetTitleInfo(Service::Interface* self) {
101 am_titles_count[media_type] = cmd_buff[2]; 107 am_titles_count[media_type] = cmd_buff[2];
102 108
103 cmd_buff[1] = RESULT_SUCCESS.raw; 109 cmd_buff[1] = RESULT_SUCCESS.raw;
104 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, total_titles=0x%08X, title_id_list_pointer=0x%08X, title_list_pointer=0x%08X", 110 LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, total_titles=0x%08X, "
111 "title_id_list_pointer=0x%08X, title_list_pointer=0x%08X",
105 media_type, am_titles_count[media_type], title_id_list_pointer, title_list_pointer); 112 media_type, am_titles_count[media_type], title_id_list_pointer, title_list_pointer);
106} 113}
107 114
@@ -122,8 +129,9 @@ void ListDataTitleTicketInfos(Service::Interface* self) {
122 129
123 cmd_buff[1] = RESULT_SUCCESS.raw; 130 cmd_buff[1] = RESULT_SUCCESS.raw;
124 cmd_buff[2] = am_ticket_count; 131 cmd_buff[2] = am_ticket_count;
125 LOG_WARNING(Service_AM, "(STUBBED) ticket_count=0x%08X, title_id=0x%016" PRIx64 ", start_index=0x%08X, ticket_info_pointer=0x%08X", 132 LOG_WARNING(Service_AM, "(STUBBED) ticket_count=0x%08X, title_id=0x%016" PRIx64
126 am_ticket_count, title_id, start_index, ticket_info_pointer); 133 ", start_index=0x%08X, ticket_info_pointer=0x%08X",
134 am_ticket_count, title_id, start_index, ticket_info_pointer);
127} 135}
128 136
129void GetNumContentInfos(Service::Interface* self) { 137void GetNumContentInfos(Service::Interface* self) {
@@ -140,7 +148,7 @@ void DeleteTicket(Service::Interface* self) {
140 u64 title_id = (static_cast<u64>(cmd_buff[2]) << 32) | cmd_buff[1]; 148 u64 title_id = (static_cast<u64>(cmd_buff[2]) << 32) | cmd_buff[1];
141 149
142 cmd_buff[1] = RESULT_SUCCESS.raw; 150 cmd_buff[1] = RESULT_SUCCESS.raw;
143 LOG_WARNING(Service_AM, "(STUBBED) called title_id=0x%016" PRIx64 "",title_id); 151 LOG_WARNING(Service_AM, "(STUBBED) called title_id=0x%016" PRIx64 "", title_id);
144} 152}
145 153
146void GetTicketCount(Service::Interface* self) { 154void GetTicketCount(Service::Interface* self) {
@@ -148,7 +156,7 @@ void GetTicketCount(Service::Interface* self) {
148 156
149 cmd_buff[1] = RESULT_SUCCESS.raw; 157 cmd_buff[1] = RESULT_SUCCESS.raw;
150 cmd_buff[2] = am_ticket_count; 158 cmd_buff[2] = am_ticket_count;
151 LOG_WARNING(Service_AM, "(STUBBED) called ticket_count=0x%08x",am_ticket_count); 159 LOG_WARNING(Service_AM, "(STUBBED) called ticket_count=0x%08x", am_ticket_count);
152} 160}
153 161
154void GetTicketList(Service::Interface* self) { 162void GetTicketList(Service::Interface* self) {
@@ -161,8 +169,10 @@ void GetTicketList(Service::Interface* self) {
161 169
162 cmd_buff[1] = RESULT_SUCCESS.raw; 170 cmd_buff[1] = RESULT_SUCCESS.raw;
163 cmd_buff[2] = am_ticket_list_count; 171 cmd_buff[2] = am_ticket_list_count;
164 LOG_WARNING(Service_AM, "(STUBBED) ticket_list_count=0x%08x, num_of_skip=0x%08x, ticket_list_pointer=0x%08x", 172 LOG_WARNING(
165 am_ticket_list_count, num_of_skip, ticket_list_pointer); 173 Service_AM,
174 "(STUBBED) ticket_list_count=0x%08x, num_of_skip=0x%08x, ticket_list_pointer=0x%08x",
175 am_ticket_list_count, num_of_skip, ticket_list_pointer);
166} 176}
167 177
168void Init() { 178void Init() {
@@ -174,9 +184,7 @@ void Init() {
174 AddService(new AM_U_Interface); 184 AddService(new AM_U_Interface);
175} 185}
176 186
177void Shutdown() { 187void Shutdown() {}
178
179}
180 188
181} // namespace AM 189} // namespace AM
182 190
diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp
index d27b3defd..bfc1ca6bd 100644
--- a/src/core/hle/service/am/am_app.cpp
+++ b/src/core/hle/service/am/am_app.cpp
@@ -9,14 +9,14 @@ namespace Service {
9namespace AM { 9namespace AM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, 12 {0x100100C0, GetNumContentInfos, "GetNumContentInfos"},
13 {0x10020104, FindContentInfos, "FindContentInfos"}, 13 {0x10020104, FindContentInfos, "FindContentInfos"},
14 {0x10030142, ListContentInfos, "ListContentInfos"}, 14 {0x10030142, ListContentInfos, "ListContentInfos"},
15 {0x10040102, DeleteContents, "DeleteContents"}, 15 {0x10040102, DeleteContents, "DeleteContents"},
16 {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"}, 16 {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"},
17 {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"}, 17 {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"},
18 {0x100900C0, nullptr, "IsDataTitleInUse"}, 18 {0x100900C0, nullptr, "IsDataTitleInUse"},
19 {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, 19 {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"},
20}; 20};
21 21
22AM_APP_Interface::AM_APP_Interface() { 22AM_APP_Interface::AM_APP_Interface() {
diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp
index e75755245..3a597a34c 100644
--- a/src/core/hle/service/am/am_net.cpp
+++ b/src/core/hle/service/am/am_net.cpp
@@ -9,61 +9,61 @@ namespace Service {
9namespace AM { 9namespace AM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, GetTitleCount, "GetTitleCount"}, 12 {0x00010040, GetTitleCount, "GetTitleCount"},
13 {0x00020082, GetTitleList, "GetTitleList"}, 13 {0x00020082, GetTitleList, "GetTitleList"},
14 {0x00030084, GetTitleInfo, "GetTitleInfo"}, 14 {0x00030084, GetTitleInfo, "GetTitleInfo"},
15 {0x000400C0, nullptr, "DeleteApplicationTitle"}, 15 {0x000400C0, nullptr, "DeleteApplicationTitle"},
16 {0x000500C0, nullptr, "GetTitleProductCode"}, 16 {0x000500C0, nullptr, "GetTitleProductCode"},
17 {0x000600C0, nullptr, "GetTitleExtDataId"}, 17 {0x000600C0, nullptr, "GetTitleExtDataId"},
18 {0x00070080, DeleteTicket, "DeleteTicket"}, 18 {0x00070080, DeleteTicket, "DeleteTicket"},
19 {0x00080000, GetTicketCount, "GetTicketCount"}, 19 {0x00080000, GetTicketCount, "GetTicketCount"},
20 {0x00090082, GetTicketList, "GetTicketList"}, 20 {0x00090082, GetTicketList, "GetTicketList"},
21 {0x000A0000, nullptr, "GetDeviceID"}, 21 {0x000A0000, nullptr, "GetDeviceID"},
22 {0x000D0084, nullptr, "GetPendingTitleInfo"}, 22 {0x000D0084, nullptr, "GetPendingTitleInfo"},
23 {0x000E00C0, nullptr, "DeletePendingTitle"}, 23 {0x000E00C0, nullptr, "DeletePendingTitle"},
24 {0x00140040, nullptr, "FinalizePendingTitles"}, 24 {0x00140040, nullptr, "FinalizePendingTitles"},
25 {0x00150040, nullptr, "DeleteAllPendingTitles"}, 25 {0x00150040, nullptr, "DeleteAllPendingTitles"},
26 {0x00180080, nullptr, "InitializeTitleDatabase"}, 26 {0x00180080, nullptr, "InitializeTitleDatabase"},
27 {0x00190040, nullptr, "ReloadDBS"}, 27 {0x00190040, nullptr, "ReloadDBS"},
28 {0x001A00C0, nullptr, "GetDSiWareExportSize"}, 28 {0x001A00C0, nullptr, "GetDSiWareExportSize"},
29 {0x001B0144, nullptr, "ExportDSiWare"}, 29 {0x001B0144, nullptr, "ExportDSiWare"},
30 {0x001C0084, nullptr, "ImportDSiWare"}, 30 {0x001C0084, nullptr, "ImportDSiWare"},
31 {0x00230080, nullptr, "TitleIDListGetTotal2"}, 31 {0x00230080, nullptr, "TitleIDListGetTotal2"},
32 {0x002400C2, nullptr, "GetTitleIDList2"}, 32 {0x002400C2, nullptr, "GetTitleIDList2"},
33 {0x04010080, nullptr, "InstallFIRM"}, 33 {0x04010080, nullptr, "InstallFIRM"},
34 {0x04020040, nullptr, "StartInstallCIADB0"}, 34 {0x04020040, nullptr, "StartInstallCIADB0"},
35 {0x04030000, nullptr, "StartInstallCIADB1"}, 35 {0x04030000, nullptr, "StartInstallCIADB1"},
36 {0x04040002, nullptr, "AbortCIAInstall"}, 36 {0x04040002, nullptr, "AbortCIAInstall"},
37 {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, 37 {0x04050002, nullptr, "CloseCIAFinalizeInstall"},
38 {0x04060002, nullptr, "CloseCIA"}, 38 {0x04060002, nullptr, "CloseCIA"},
39 {0x040700C2, nullptr, "FinalizeTitlesInstall"}, 39 {0x040700C2, nullptr, "FinalizeTitlesInstall"},
40 {0x04080042, nullptr, "GetCiaFileInfo"}, 40 {0x04080042, nullptr, "GetCiaFileInfo"},
41 {0x040E00C2, nullptr, "InstallTitlesFinish"}, 41 {0x040E00C2, nullptr, "InstallTitlesFinish"},
42 {0x040F0000, nullptr, "InstallNATIVEFIRM"}, 42 {0x040F0000, nullptr, "InstallNATIVEFIRM"},
43 {0x041000C0, nullptr, "DeleteTitle"}, 43 {0x041000C0, nullptr, "DeleteTitle"},
44 {0x04120000, nullptr, "Initialize"}, 44 {0x04120000, nullptr, "Initialize"},
45 {0x041700C0, nullptr, "MigrateAGBtoSAV"}, 45 {0x041700C0, nullptr, "MigrateAGBtoSAV"},
46 {0x08010000, nullptr, "OpenTicket"}, 46 {0x08010000, nullptr, "OpenTicket"},
47 {0x08020002, nullptr, "TicketAbortInstall"}, 47 {0x08020002, nullptr, "TicketAbortInstall"},
48 {0x08030002, nullptr, "TicketFinalizeInstall"}, 48 {0x08030002, nullptr, "TicketFinalizeInstall"},
49 {0x08040100, nullptr, "InstallTitleBegin"}, 49 {0x08040100, nullptr, "InstallTitleBegin"},
50 {0x08050000, nullptr, "InstallTitleAbort"}, 50 {0x08050000, nullptr, "InstallTitleAbort"},
51 {0x080600C0, nullptr, "InstallTitleResume"}, 51 {0x080600C0, nullptr, "InstallTitleResume"},
52 {0x08070000, nullptr, "InstallTitleAbortTMD"}, 52 {0x08070000, nullptr, "InstallTitleAbortTMD"},
53 {0x08080000, nullptr, "InstallTitleFinish"}, 53 {0x08080000, nullptr, "InstallTitleFinish"},
54 {0x080A0000, nullptr, "OpenTMD"}, 54 {0x080A0000, nullptr, "OpenTMD"},
55 {0x080B0002, nullptr, "TMDAbortInstall"}, 55 {0x080B0002, nullptr, "TMDAbortInstall"},
56 {0x080C0042, nullptr, "TMDFinalizeInstall"}, 56 {0x080C0042, nullptr, "TMDFinalizeInstall"},
57 {0x080E0040, nullptr, "OpenContentCreate"}, 57 {0x080E0040, nullptr, "OpenContentCreate"},
58 {0x080F0002, nullptr, "ContentAbortInstall"}, 58 {0x080F0002, nullptr, "ContentAbortInstall"},
59 {0x08100040, nullptr, "OpenContentResume"}, 59 {0x08100040, nullptr, "OpenContentResume"},
60 {0x08120002, nullptr, "ContentFinalizeInstall"}, 60 {0x08120002, nullptr, "ContentFinalizeInstall"},
61 {0x08130000, nullptr, "GetTotalContents"}, 61 {0x08130000, nullptr, "GetTotalContents"},
62 {0x08140042, nullptr, "GetContentIndexes"}, 62 {0x08140042, nullptr, "GetContentIndexes"},
63 {0x08150044, nullptr, "GetContentsInfo"}, 63 {0x08150044, nullptr, "GetContentsInfo"},
64 {0x08180042, nullptr, "GetCTCert"}, 64 {0x08180042, nullptr, "GetCTCert"},
65 {0x08190108, nullptr, "SetCertificates"}, 65 {0x08190108, nullptr, "SetCertificates"},
66 {0x081B00C2, nullptr, "InstallTitlesFinish"}, 66 {0x081B00C2, nullptr, "InstallTitlesFinish"},
67}; 67};
68 68
69AM_NET_Interface::AM_NET_Interface() { 69AM_NET_Interface::AM_NET_Interface() {
diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp
index 8bad5e1c9..a2268303c 100644
--- a/src/core/hle/service/am/am_sys.cpp
+++ b/src/core/hle/service/am/am_sys.cpp
@@ -9,27 +9,27 @@ namespace Service {
9namespace AM { 9namespace AM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, GetTitleCount, "GetTitleCount"}, 12 {0x00010040, GetTitleCount, "GetTitleCount"},
13 {0x00020082, GetTitleList, "GetTitleList"}, 13 {0x00020082, GetTitleList, "GetTitleList"},
14 {0x00030084, GetTitleInfo, "GetTitleInfo"}, 14 {0x00030084, GetTitleInfo, "GetTitleInfo"},
15 {0x000400C0, nullptr, "DeleteApplicationTitle"}, 15 {0x000400C0, nullptr, "DeleteApplicationTitle"},
16 {0x000500C0, nullptr, "GetTitleProductCode"}, 16 {0x000500C0, nullptr, "GetTitleProductCode"},
17 {0x000600C0, nullptr, "GetTitleExtDataId"}, 17 {0x000600C0, nullptr, "GetTitleExtDataId"},
18 {0x00070080, DeleteTicket, "DeleteTicket"}, 18 {0x00070080, DeleteTicket, "DeleteTicket"},
19 {0x00080000, GetTicketCount, "GetTicketCount"}, 19 {0x00080000, GetTicketCount, "GetTicketCount"},
20 {0x00090082, GetTicketList, "GetTicketList"}, 20 {0x00090082, GetTicketList, "GetTicketList"},
21 {0x000A0000, nullptr, "GetDeviceID"}, 21 {0x000A0000, nullptr, "GetDeviceID"},
22 {0x000D0084, nullptr, "GetPendingTitleInfo"}, 22 {0x000D0084, nullptr, "GetPendingTitleInfo"},
23 {0x000E00C0, nullptr, "DeletePendingTitle"}, 23 {0x000E00C0, nullptr, "DeletePendingTitle"},
24 {0x00140040, nullptr, "FinalizePendingTitles"}, 24 {0x00140040, nullptr, "FinalizePendingTitles"},
25 {0x00150040, nullptr, "DeleteAllPendingTitles"}, 25 {0x00150040, nullptr, "DeleteAllPendingTitles"},
26 {0x00180080, nullptr, "InitializeTitleDatabase"}, 26 {0x00180080, nullptr, "InitializeTitleDatabase"},
27 {0x00190040, nullptr, "ReloadDBS"}, 27 {0x00190040, nullptr, "ReloadDBS"},
28 {0x001A00C0, nullptr, "GetDSiWareExportSize"}, 28 {0x001A00C0, nullptr, "GetDSiWareExportSize"},
29 {0x001B0144, nullptr, "ExportDSiWare"}, 29 {0x001B0144, nullptr, "ExportDSiWare"},
30 {0x001C0084, nullptr, "ImportDSiWare"}, 30 {0x001C0084, nullptr, "ImportDSiWare"},
31 {0x00230080, nullptr, "GetPendingTitleCount"}, 31 {0x00230080, nullptr, "GetPendingTitleCount"},
32 {0x002400C2, nullptr, "GetPendingTitleList"} 32 {0x002400C2, nullptr, "GetPendingTitleList"},
33}; 33};
34 34
35AM_SYS_Interface::AM_SYS_Interface() { 35AM_SYS_Interface::AM_SYS_Interface() {
diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp
index d583dd9e6..151b5e42b 100644
--- a/src/core/hle/service/am/am_u.cpp
+++ b/src/core/hle/service/am/am_u.cpp
@@ -9,40 +9,40 @@ namespace Service {
9namespace AM { 9namespace AM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, GetTitleCount, "GetTitleCount"}, 12 {0x00010040, GetTitleCount, "GetTitleCount"},
13 {0x00020082, GetTitleList, "GetTitleList"}, 13 {0x00020082, GetTitleList, "GetTitleList"},
14 {0x00030084, GetTitleInfo, "GetTitleInfo"}, 14 {0x00030084, GetTitleInfo, "GetTitleInfo"},
15 {0x000400C0, nullptr, "DeleteApplicationTitle"}, 15 {0x000400C0, nullptr, "DeleteApplicationTitle"},
16 {0x000500C0, nullptr, "GetTitleProductCode"}, 16 {0x000500C0, nullptr, "GetTitleProductCode"},
17 {0x000600C0, nullptr, "GetTitleExtDataId"}, 17 {0x000600C0, nullptr, "GetTitleExtDataId"},
18 {0x00070080, DeleteTicket, "DeleteTicket"}, 18 {0x00070080, DeleteTicket, "DeleteTicket"},
19 {0x00080000, GetTicketCount, "GetTicketCount"}, 19 {0x00080000, GetTicketCount, "GetTicketCount"},
20 {0x00090082, GetTicketList, "GetTicketList"}, 20 {0x00090082, GetTicketList, "GetTicketList"},
21 {0x000A0000, nullptr, "GetDeviceID"}, 21 {0x000A0000, nullptr, "GetDeviceID"},
22 {0x000D0084, nullptr, "GetPendingTitleInfo"}, 22 {0x000D0084, nullptr, "GetPendingTitleInfo"},
23 {0x000E00C0, nullptr, "DeletePendingTitle"}, 23 {0x000E00C0, nullptr, "DeletePendingTitle"},
24 {0x00140040, nullptr, "FinalizePendingTitles"}, 24 {0x00140040, nullptr, "FinalizePendingTitles"},
25 {0x00150040, nullptr, "DeleteAllPendingTitles"}, 25 {0x00150040, nullptr, "DeleteAllPendingTitles"},
26 {0x00180080, nullptr, "InitializeTitleDatabase"}, 26 {0x00180080, nullptr, "InitializeTitleDatabase"},
27 {0x00190040, nullptr, "ReloadDBS"}, 27 {0x00190040, nullptr, "ReloadDBS"},
28 {0x001A00C0, nullptr, "GetDSiWareExportSize"}, 28 {0x001A00C0, nullptr, "GetDSiWareExportSize"},
29 {0x001B0144, nullptr, "ExportDSiWare"}, 29 {0x001B0144, nullptr, "ExportDSiWare"},
30 {0x001C0084, nullptr, "ImportDSiWare"}, 30 {0x001C0084, nullptr, "ImportDSiWare"},
31 {0x00230080, nullptr, "TitleIDListGetTotal2"}, 31 {0x00230080, nullptr, "TitleIDListGetTotal2"},
32 {0x002400C2, nullptr, "GetTitleIDList2"}, 32 {0x002400C2, nullptr, "GetTitleIDList2"},
33 {0x04010080, nullptr, "InstallFIRM"}, 33 {0x04010080, nullptr, "InstallFIRM"},
34 {0x04020040, nullptr, "StartInstallCIADB0"}, 34 {0x04020040, nullptr, "StartInstallCIADB0"},
35 {0x04030000, nullptr, "StartInstallCIADB1"}, 35 {0x04030000, nullptr, "StartInstallCIADB1"},
36 {0x04040002, nullptr, "AbortCIAInstall"}, 36 {0x04040002, nullptr, "AbortCIAInstall"},
37 {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, 37 {0x04050002, nullptr, "CloseCIAFinalizeInstall"},
38 {0x04060002, nullptr, "CloseCIA"}, 38 {0x04060002, nullptr, "CloseCIA"},
39 {0x040700C2, nullptr, "FinalizeTitlesInstall"}, 39 {0x040700C2, nullptr, "FinalizeTitlesInstall"},
40 {0x04080042, nullptr, "GetCiaFileInfo"}, 40 {0x04080042, nullptr, "GetCiaFileInfo"},
41 {0x040E00C2, nullptr, "InstallTitlesFinish"}, 41 {0x040E00C2, nullptr, "InstallTitlesFinish"},
42 {0x040F0000, nullptr, "InstallNATIVEFIRM"}, 42 {0x040F0000, nullptr, "InstallNATIVEFIRM"},
43 {0x041000C0, nullptr, "DeleteTitle"}, 43 {0x041000C0, nullptr, "DeleteTitle"},
44 {0x04120000, nullptr, "Initialize"}, 44 {0x04120000, nullptr, "Initialize"},
45 {0x041700C0, nullptr, "MigrateAGBtoSAV"} 45 {0x041700C0, nullptr, "MigrateAGBtoSAV"},
46}; 46};
47 47
48AM_U_Interface::AM_U_Interface() { 48AM_U_Interface::AM_U_Interface() {
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 4d2956638..c4bd65986 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -5,9 +5,11 @@
5#include "common/common_paths.h" 5#include "common/common_paths.h"
6#include "common/file_util.h" 6#include "common/file_util.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8
9#include "core/hle/applets/applet.h" 8#include "core/hle/applets/applet.h"
10#include "core/hle/service/service.h" 9#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/mutex.h"
11#include "core/hle/kernel/process.h"
12#include "core/hle/kernel/shared_memory.h"
11#include "core/hle/service/apt/apt.h" 13#include "core/hle/service/apt/apt.h"
12#include "core/hle/service/apt/apt_a.h" 14#include "core/hle/service/apt/apt_a.h"
13#include "core/hle/service/apt/apt_s.h" 15#include "core/hle/service/apt/apt_s.h"
@@ -15,11 +17,7 @@
15#include "core/hle/service/apt/bcfnt/bcfnt.h" 17#include "core/hle/service/apt/bcfnt/bcfnt.h"
16#include "core/hle/service/fs/archive.h" 18#include "core/hle/service/fs/archive.h"
17#include "core/hle/service/ptm/ptm.h" 19#include "core/hle/service/ptm/ptm.h"
18 20#include "core/hle/service/service.h"
19#include "core/hle/kernel/event.h"
20#include "core/hle/kernel/mutex.h"
21#include "core/hle/kernel/process.h"
22#include "core/hle/kernel/shared_memory.h"
23 21
24namespace Service { 22namespace Service {
25namespace APT { 23namespace APT {
@@ -30,7 +28,7 @@ static bool shared_font_relocated = false;
30 28
31static Kernel::SharedPtr<Kernel::Mutex> lock; 29static Kernel::SharedPtr<Kernel::Mutex> lock;
32static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event 30static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
33static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event 31static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event
34 32
35static u32 cpu_percent; ///< CPU time available to the running application 33static u32 cpu_percent; ///< CPU time available to the running application
36 34
@@ -51,7 +49,7 @@ void SendParameter(const MessageParameter& parameter) {
51void Initialize(Service::Interface* self) { 49void Initialize(Service::Interface* self) {
52 u32* cmd_buff = Kernel::GetCommandBuffer(); 50 u32* cmd_buff = Kernel::GetCommandBuffer();
53 u32 app_id = cmd_buff[1]; 51 u32 app_id = cmd_buff[1];
54 u32 flags = cmd_buff[2]; 52 u32 flags = cmd_buff[2];
55 53
56 cmd_buff[2] = IPC::CopyHandleDesc(2); 54 cmd_buff[2] = IPC::CopyHandleDesc(2);
57 cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom(); 55 cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
@@ -75,21 +73,23 @@ void GetSharedFont(Service::Interface* self) {
75 if (!shared_font_mem) { 73 if (!shared_font_mem) {
76 LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds"); 74 LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds");
77 cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2); 75 cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2);
78 cmd_buff[1] = -1; // TODO: Find the right error code 76 cmd_buff[1] = -1; // TODO: Find the right error code
79 return; 77 return;
80 } 78 }
81 79
82 // The shared font has to be relocated to the new address before being passed to the application. 80 // The shared font has to be relocated to the new address before being passed to the
83 VAddr target_address = Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address); 81 // application.
82 VAddr target_address =
83 Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address);
84 if (!shared_font_relocated) { 84 if (!shared_font_relocated) {
85 BCFNT::RelocateSharedFont(shared_font_mem, target_address); 85 BCFNT::RelocateSharedFont(shared_font_mem, target_address);
86 shared_font_relocated = true; 86 shared_font_relocated = true;
87 } 87 }
88 cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2); 88 cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2);
89 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 89 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
90 // Since the SharedMemory interface doesn't provide the address at which the memory was allocated, 90 // Since the SharedMemory interface doesn't provide the address at which the memory was
91 // the real APT service calculates this address by scanning the entire address space (using svcQueryMemory) 91 // allocated, the real APT service calculates this address by scanning the entire address space
92 // and searches for an allocation of the same size as the Shared Font. 92 // (using svcQueryMemory) and searches for an allocation of the same size as the Shared Font.
93 cmd_buff[2] = target_address; 93 cmd_buff[2] = target_address;
94 cmd_buff[3] = IPC::CopyHandleDesc(); 94 cmd_buff[3] = IPC::CopyHandleDesc();
95 cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom(); 95 cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
@@ -112,18 +112,19 @@ void GetLockHandle(Service::Interface* self) {
112 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 112 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
113 113
114 cmd_buff[2] = applet_attributes; // Applet Attributes, this value is passed to Enable. 114 cmd_buff[2] = applet_attributes; // Applet Attributes, this value is passed to Enable.
115 cmd_buff[3] = 0; // Least significant bit = power button state 115 cmd_buff[3] = 0; // Least significant bit = power button state
116 cmd_buff[4] = IPC::CopyHandleDesc(); 116 cmd_buff[4] = IPC::CopyHandleDesc();
117 cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom(); 117 cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom();
118 118
119 LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", cmd_buff[5], applet_attributes); 119 LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", cmd_buff[5],
120 applet_attributes);
120} 121}
121 122
122void Enable(Service::Interface* self) { 123void Enable(Service::Interface* self) {
123 u32* cmd_buff = Kernel::GetCommandBuffer(); 124 u32* cmd_buff = Kernel::GetCommandBuffer();
124 u32 attributes = cmd_buff[1]; 125 u32 attributes = cmd_buff[1];
125 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 126 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
126 parameter_event->Signal(); // Let the application know that it has been started 127 parameter_event->Signal(); // Let the application know that it has been started
127 LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes); 128 LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes);
128} 129}
129 130
@@ -133,7 +134,7 @@ void GetAppletManInfo(Service::Interface* self) {
133 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 134 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
134 cmd_buff[2] = 0; 135 cmd_buff[2] = 0;
135 cmd_buff[3] = 0; 136 cmd_buff[3] = 0;
136 cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID 137 cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID
137 cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly 138 cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly
138 139
139 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk); 140 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
@@ -159,23 +160,24 @@ void IsRegistered(Service::Interface* self) {
159void InquireNotification(Service::Interface* self) { 160void InquireNotification(Service::Interface* self) {
160 u32* cmd_buff = Kernel::GetCommandBuffer(); 161 u32* cmd_buff = Kernel::GetCommandBuffer();
161 u32 app_id = cmd_buff[1]; 162 u32 app_id = cmd_buff[1];
162 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 163 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
163 cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type 164 cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
164 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); 165 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
165} 166}
166 167
167void SendParameter(Service::Interface* self) { 168void SendParameter(Service::Interface* self) {
168 u32* cmd_buff = Kernel::GetCommandBuffer(); 169 u32* cmd_buff = Kernel::GetCommandBuffer();
169 u32 src_app_id = cmd_buff[1]; 170 u32 src_app_id = cmd_buff[1];
170 u32 dst_app_id = cmd_buff[2]; 171 u32 dst_app_id = cmd_buff[2];
171 u32 signal_type = cmd_buff[3]; 172 u32 signal_type = cmd_buff[3];
172 u32 buffer_size = cmd_buff[4]; 173 u32 buffer_size = cmd_buff[4];
173 u32 value = cmd_buff[5]; 174 u32 value = cmd_buff[5];
174 u32 handle = cmd_buff[6]; 175 u32 handle = cmd_buff[6];
175 u32 size = cmd_buff[7]; 176 u32 size = cmd_buff[7];
176 u32 buffer = cmd_buff[8]; 177 u32 buffer = cmd_buff[8];
177 178
178 std::shared_ptr<HLE::Applets::Applet> dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); 179 std::shared_ptr<HLE::Applets::Applet> dest_applet =
180 HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id));
179 181
180 if (dest_applet == nullptr) { 182 if (dest_applet == nullptr) {
181 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); 183 LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id);
@@ -193,9 +195,11 @@ void SendParameter(Service::Interface* self) {
193 195
194 cmd_buff[1] = dest_applet->ReceiveParameter(param).raw; 196 cmd_buff[1] = dest_applet->ReceiveParameter(param).raw;
195 197
196 LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," 198 LOG_WARNING(
197 "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X", 199 Service_APT,
198 src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, buffer); 200 "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
201 "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X",
202 src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, buffer);
199} 203}
200 204
201void ReceiveParameter(Service::Interface* self) { 205void ReceiveParameter(Service::Interface* self) {
@@ -206,7 +210,7 @@ void ReceiveParameter(Service::Interface* self) {
206 210
207 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 211 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
208 cmd_buff[2] = next_parameter.sender_id; 212 cmd_buff[2] = next_parameter.sender_id;
209 cmd_buff[3] = next_parameter.signal; // Signal type 213 cmd_buff[3] = next_parameter.signal; // Signal type
210 cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size 214 cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size
211 cmd_buff[5] = 0x10; 215 cmd_buff[5] = 0x10;
212 cmd_buff[6] = 0; 216 cmd_buff[6] = 0;
@@ -228,7 +232,7 @@ void GlanceParameter(Service::Interface* self) {
228 232
229 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 233 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
230 cmd_buff[2] = next_parameter.sender_id; 234 cmd_buff[2] = next_parameter.sender_id;
231 cmd_buff[3] = next_parameter.signal; // Signal type 235 cmd_buff[3] = next_parameter.signal; // Signal type
232 cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size 236 cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size
233 cmd_buff[5] = 0x10; 237 cmd_buff[5] = 0x10;
234 cmd_buff[6] = 0; 238 cmd_buff[6] = 0;
@@ -237,32 +241,34 @@ void GlanceParameter(Service::Interface* self) {
237 cmd_buff[7] = (next_parameter.buffer.size() << 14) | 2; 241 cmd_buff[7] = (next_parameter.buffer.size() << 14) | 2;
238 cmd_buff[8] = buffer; 242 cmd_buff[8] = buffer;
239 243
240 Memory::WriteBlock(buffer, next_parameter.buffer.data(), std::min(static_cast<size_t>(buffer_size), next_parameter.buffer.size())); 244 Memory::WriteBlock(buffer, next_parameter.buffer.data(),
245 std::min(static_cast<size_t>(buffer_size), next_parameter.buffer.size()));
241 246
242 LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size); 247 LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
243} 248}
244 249
245void CancelParameter(Service::Interface* self) { 250void CancelParameter(Service::Interface* self) {
246 u32* cmd_buff = Kernel::GetCommandBuffer(); 251 u32* cmd_buff = Kernel::GetCommandBuffer();
247 u32 flag1 = cmd_buff[1]; 252 u32 flag1 = cmd_buff[1];
248 u32 unk = cmd_buff[2]; 253 u32 unk = cmd_buff[2];
249 u32 flag2 = cmd_buff[3]; 254 u32 flag2 = cmd_buff[3];
250 u32 app_id = cmd_buff[4]; 255 u32 app_id = cmd_buff[4];
251 256
252 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 257 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
253 cmd_buff[2] = 1; // Set to Success 258 cmd_buff[2] = 1; // Set to Success
254 259
255 LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X", 260 LOG_WARNING(Service_APT,
256 flag1, unk, flag2, app_id); 261 "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X", flag1,
262 unk, flag2, app_id);
257} 263}
258 264
259void PrepareToStartApplication(Service::Interface* self) { 265void PrepareToStartApplication(Service::Interface* self) {
260 u32* cmd_buff = Kernel::GetCommandBuffer(); 266 u32* cmd_buff = Kernel::GetCommandBuffer();
261 u32 title_info1 = cmd_buff[1]; 267 u32 title_info1 = cmd_buff[1];
262 u32 title_info2 = cmd_buff[2]; 268 u32 title_info2 = cmd_buff[2];
263 u32 title_info3 = cmd_buff[3]; 269 u32 title_info3 = cmd_buff[3];
264 u32 title_info4 = cmd_buff[4]; 270 u32 title_info4 = cmd_buff[4];
265 u32 flags = cmd_buff[5]; 271 u32 flags = cmd_buff[5];
266 272
267 if (flags & 0x00000100) { 273 if (flags & 0x00000100) {
268 unknown_ns_state_field = 1; 274 unknown_ns_state_field = 1;
@@ -270,25 +276,28 @@ void PrepareToStartApplication(Service::Interface* self) {
270 276
271 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 277 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
272 278
273 LOG_WARNING(Service_APT, "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X," 279 LOG_WARNING(Service_APT,
274 "title_info4=0x%08X, flags=0x%08X", title_info1, title_info2, title_info3, title_info4, flags); 280 "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X,"
281 "title_info4=0x%08X, flags=0x%08X",
282 title_info1, title_info2, title_info3, title_info4, flags);
275} 283}
276 284
277void StartApplication(Service::Interface* self) { 285void StartApplication(Service::Interface* self) {
278 u32* cmd_buff = Kernel::GetCommandBuffer(); 286 u32* cmd_buff = Kernel::GetCommandBuffer();
279 u32 buffer1_size = cmd_buff[1]; 287 u32 buffer1_size = cmd_buff[1];
280 u32 buffer2_size = cmd_buff[2]; 288 u32 buffer2_size = cmd_buff[2];
281 u32 flag = cmd_buff[3]; 289 u32 flag = cmd_buff[3];
282 u32 size1 = cmd_buff[4]; 290 u32 size1 = cmd_buff[4];
283 u32 buffer1_ptr = cmd_buff[5]; 291 u32 buffer1_ptr = cmd_buff[5];
284 u32 size2 = cmd_buff[6]; 292 u32 size2 = cmd_buff[6];
285 u32 buffer2_ptr = cmd_buff[7]; 293 u32 buffer2_ptr = cmd_buff[7];
286 294
287 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 295 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
288 296
289 LOG_WARNING(Service_APT, "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X," 297 LOG_WARNING(Service_APT,
290 "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X", 298 "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X,"
291 buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr); 299 "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X",
300 buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr);
292} 301}
293 302
294void AppletUtility(Service::Interface* self) { 303void AppletUtility(Service::Interface* self) {
@@ -303,14 +312,15 @@ void AppletUtility(Service::Interface* self) {
303 312
304 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 313 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
305 314
306 LOG_WARNING(Service_APT, "(STUBBED) called command=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, " 315 LOG_WARNING(Service_APT,
307 "buffer1_addr=0x%08X, buffer2_addr=0x%08X", command, buffer1_size, buffer2_size, 316 "(STUBBED) called command=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, "
308 buffer1_addr, buffer2_addr); 317 "buffer1_addr=0x%08X, buffer2_addr=0x%08X",
318 command, buffer1_size, buffer2_size, buffer1_addr, buffer2_addr);
309} 319}
310 320
311void SetAppCpuTimeLimit(Service::Interface* self) { 321void SetAppCpuTimeLimit(Service::Interface* self) {
312 u32* cmd_buff = Kernel::GetCommandBuffer(); 322 u32* cmd_buff = Kernel::GetCommandBuffer();
313 u32 value = cmd_buff[1]; 323 u32 value = cmd_buff[1];
314 cpu_percent = cmd_buff[2]; 324 cpu_percent = cmd_buff[2];
315 325
316 if (value != 1) { 326 if (value != 1) {
@@ -393,7 +403,8 @@ void SetScreenCapPostPermission(Service::Interface* self) {
393 403
394 cmd_buff[0] = IPC::MakeHeader(0x55, 1, 0); 404 cmd_buff[0] = IPC::MakeHeader(0x55, 1, 0);
395 cmd_buff[1] = RESULT_SUCCESS.raw; 405 cmd_buff[1] = RESULT_SUCCESS.raw;
396 LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", screen_capture_post_permission); 406 LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u",
407 screen_capture_post_permission);
397} 408}
398 409
399void GetScreenCapPostPermission(Service::Interface* self) { 410void GetScreenCapPostPermission(Service::Interface* self) {
@@ -402,7 +413,8 @@ void GetScreenCapPostPermission(Service::Interface* self) {
402 cmd_buff[0] = IPC::MakeHeader(0x56, 2, 0); 413 cmd_buff[0] = IPC::MakeHeader(0x56, 2, 0);
403 cmd_buff[1] = RESULT_SUCCESS.raw; 414 cmd_buff[1] = RESULT_SUCCESS.raw;
404 cmd_buff[2] = static_cast<u32>(screen_capture_post_permission); 415 cmd_buff[2] = static_cast<u32>(screen_capture_post_permission);
405 LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", screen_capture_post_permission); 416 LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u",
417 screen_capture_post_permission);
406} 418}
407 419
408void GetAppletInfo(Service::Interface* self) { 420void GetAppletInfo(Service::Interface* self) {
@@ -418,7 +430,8 @@ void GetAppletInfo(Service::Interface* self) {
418 cmd_buff[7] = 0; // Applet Attributes 430 cmd_buff[7] = 0; // Applet Attributes
419 } else { 431 } else {
420 cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, 432 cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Applet,
421 ErrorSummary::NotFound, ErrorLevel::Status).raw; 433 ErrorSummary::NotFound, ErrorLevel::Status)
434 .raw;
422 } 435 }
423 LOG_WARNING(Service_APT, "(stubbed) called appid=%u", app_id); 436 LOG_WARNING(Service_APT, "(stubbed) called appid=%u", app_id);
424} 437}
@@ -429,11 +442,15 @@ void GetStartupArgument(Service::Interface* self) {
429 StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(cmd_buff[2]); 442 StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(cmd_buff[2]);
430 443
431 if (parameter_size >= 0x300) { 444 if (parameter_size >= 0x300) {
432 LOG_ERROR(Service_APT, "Parameter size is outside the valid range (capped to 0x300): parameter_size=0x%08x", parameter_size); 445 LOG_ERROR(
446 Service_APT,
447 "Parameter size is outside the valid range (capped to 0x300): parameter_size=0x%08x",
448 parameter_size);
433 return; 449 return;
434 } 450 }
435 451
436 LOG_WARNING(Service_APT,"(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , parameter_value=0x%08x", 452 LOG_WARNING(Service_APT, "(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , "
453 "parameter_value=0x%08x",
437 startup_argument_type, parameter_size, Memory::Read32(cmd_buff[41])); 454 startup_argument_type, parameter_size, Memory::Read32(cmd_buff[41]));
438 455
439 cmd_buff[1] = RESULT_SUCCESS.raw; 456 cmd_buff[1] = RESULT_SUCCESS.raw;
@@ -484,8 +501,10 @@ void Init() {
484 if (file.IsOpen()) { 501 if (file.IsOpen()) {
485 // Create shared font memory object 502 // Create shared font memory object
486 using Kernel::MemoryPermission; 503 using Kernel::MemoryPermission;
487 shared_font_mem = Kernel::SharedMemory::Create(nullptr, 0x332000, // 3272 KB 504 shared_font_mem =
488 MemoryPermission::ReadWrite, MemoryPermission::Read, 0, Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); 505 Kernel::SharedMemory::Create(nullptr, 0x332000, // 3272 KB
506 MemoryPermission::ReadWrite, MemoryPermission::Read, 0,
507 Kernel::MemoryRegion::SYSTEM, "APT:SharedFont");
489 // Read shared font data 508 // Read shared font data
490 file.ReadBytes(shared_font_mem->GetPointer(), file.GetSize()); 509 file.ReadBytes(shared_font_mem->GetPointer(), file.GetSize());
491 } else { 510 } else {
@@ -497,7 +516,8 @@ void Init() {
497 516
498 cpu_percent = 0; 517 cpu_percent = 0;
499 unknown_ns_state_field = 0; 518 unknown_ns_state_field = 0;
500 screen_capture_post_permission = ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value 519 screen_capture_post_permission =
520 ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value
501 521
502 // TODO(bunnei): Check if these are created in Initialize or on APT process startup. 522 // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
503 notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification"); 523 notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification");
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index 077a6a316..a118cda1f 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -6,7 +6,6 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/swap.h" 8#include "common/swap.h"
9
10#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
11 10
12namespace Service { 11namespace Service {
@@ -46,58 +45,58 @@ static_assert(sizeof(CaptureBufferInfo) == 0x20, "CaptureBufferInfo struct has i
46 45
47/// Signals used by APT functions 46/// Signals used by APT functions
48enum class SignalType : u32 { 47enum class SignalType : u32 {
49 None = 0x0, 48 None = 0x0,
50 AppJustStarted = 0x1, 49 AppJustStarted = 0x1,
51 LibAppJustStarted = 0x2, 50 LibAppJustStarted = 0x2,
52 LibAppFinished = 0x3, 51 LibAppFinished = 0x3,
53 LibAppClosed = 0xA, 52 LibAppClosed = 0xA,
54 ReturningToApp = 0xB, 53 ReturningToApp = 0xB,
55 ExitingApp = 0xC, 54 ExitingApp = 0xC,
56}; 55};
57 56
58/// App Id's used by APT functions 57/// App Id's used by APT functions
59enum class AppletId : u32 { 58enum class AppletId : u32 {
60 HomeMenu = 0x101, 59 HomeMenu = 0x101,
61 AlternateMenu = 0x103, 60 AlternateMenu = 0x103,
62 Camera = 0x110, 61 Camera = 0x110,
63 FriendsList = 0x112, 62 FriendsList = 0x112,
64 GameNotes = 0x113, 63 GameNotes = 0x113,
65 InternetBrowser = 0x114, 64 InternetBrowser = 0x114,
66 InstructionManual = 0x115, 65 InstructionManual = 0x115,
67 Notifications = 0x116, 66 Notifications = 0x116,
68 Miiverse = 0x117, 67 Miiverse = 0x117,
69 MiiversePost = 0x118, 68 MiiversePost = 0x118,
70 AmiiboSettings = 0x119, 69 AmiiboSettings = 0x119,
71 SoftwareKeyboard1 = 0x201, 70 SoftwareKeyboard1 = 0x201,
72 Ed1 = 0x202, 71 Ed1 = 0x202,
73 PnoteApp = 0x204, 72 PnoteApp = 0x204,
74 SnoteApp = 0x205, 73 SnoteApp = 0x205,
75 Error = 0x206, 74 Error = 0x206,
76 Mint = 0x207, 75 Mint = 0x207,
77 Extrapad = 0x208, 76 Extrapad = 0x208,
78 Memolib = 0x209, 77 Memolib = 0x209,
79 Application = 0x300, 78 Application = 0x300,
80 AnyLibraryApplet = 0x400, 79 AnyLibraryApplet = 0x400,
81 SoftwareKeyboard2 = 0x401, 80 SoftwareKeyboard2 = 0x401,
82 Ed2 = 0x402, 81 Ed2 = 0x402,
83 PnoteApp2 = 0x404, 82 PnoteApp2 = 0x404,
84 SnoteApp2 = 0x405, 83 SnoteApp2 = 0x405,
85 Error2 = 0x406, 84 Error2 = 0x406,
86 Mint2 = 0x407, 85 Mint2 = 0x407,
87 Extrapad2 = 0x408, 86 Extrapad2 = 0x408,
88 Memolib2 = 0x409, 87 Memolib2 = 0x409,
89}; 88};
90 89
91enum class StartupArgumentType : u32 { 90enum class StartupArgumentType : u32 {
92 OtherApp = 0, 91 OtherApp = 0,
93 Restart = 1, 92 Restart = 1,
94 OtherMedia = 2, 93 OtherMedia = 2,
95}; 94};
96 95
97enum class ScreencapPostPermission : u32 { 96enum class ScreencapPostPermission : u32 {
98 CleanThePermission = 0, //TODO(JamePeng): verify what "zero" means 97 CleanThePermission = 0, // TODO(JamePeng): verify what "zero" means
99 NoExplicitSetting = 1, 98 NoExplicitSetting = 1,
100 EnableScreenshotPostingToMiiverse = 2, 99 EnableScreenshotPostingToMiiverse = 2,
101 DisableScreenshotPostingToMiiverse = 3 100 DisableScreenshotPostingToMiiverse = 3
102}; 101};
103 102
@@ -182,10 +181,11 @@ void GetAppletManInfo(Service::Interface* self);
182void GetAppletInfo(Service::Interface* self); 181void GetAppletInfo(Service::Interface* self);
183 182
184/** 183/**
185 * APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet. 184 * APT::IsRegistered service function. This returns whether the specified AppID is registered with
186 * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this 185 * NS yet. An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home
187 * command to determine when the launched process is running and to determine when to stop using GSP etc, 186 * Menu uses this command to determine when the launched process is running and to determine when to
188 * while displaying the "Nintendo 3DS" loading screen. 187 * stop using GSP, etc., while displaying the "Nintendo 3DS" loading screen.
188 *
189 * Inputs: 189 * Inputs:
190 * 1 : AppID 190 * 1 : AppID
191 * Outputs: 191 * Outputs:
@@ -260,9 +260,11 @@ void GlanceParameter(Service::Interface* self);
260 * clears the flag which indicates that parameter data is available 260 * clears the flag which indicates that parameter data is available
261 * (same flag cleared by APT:ReceiveParameter). 261 * (same flag cleared by APT:ReceiveParameter).
262 * Inputs: 262 * Inputs:
263 * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state. 263 * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS
264 * state.
264 * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter. 265 * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter.
265 * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state. 266 * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS
267 * state.
266 * 4 : AppID 268 * 4 : AppID
267 * Outputs: 269 * Outputs:
268 * 0 : Return header 270 * 0 : Return header
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp
index 6c44c491c..f27ad91b7 100644
--- a/src/core/hle/service/apt/apt_a.cpp
+++ b/src/core/hle/service/apt/apt_a.cpp
@@ -9,34 +9,34 @@ namespace Service {
9namespace APT { 9namespace APT {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, GetLockHandle, "GetLockHandle?"}, 12 {0x00010040, GetLockHandle, "GetLockHandle?"},
13 {0x00020080, Initialize, "Initialize?"}, 13 {0x00020080, Initialize, "Initialize?"},
14 {0x00030040, Enable, "Enable?"}, 14 {0x00030040, Enable, "Enable?"},
15 {0x00040040, nullptr, "Finalize?"}, 15 {0x00040040, nullptr, "Finalize?"},
16 {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, 16 {0x00050040, GetAppletManInfo, "GetAppletManInfo"},
17 {0x00060040, GetAppletInfo, "GetAppletInfo"}, 17 {0x00060040, GetAppletInfo, "GetAppletInfo"},
18 {0x00090040, IsRegistered, "IsRegistered"}, 18 {0x00090040, IsRegistered, "IsRegistered"},
19 {0x000B0040, InquireNotification, "InquireNotification"}, 19 {0x000B0040, InquireNotification, "InquireNotification"},
20 {0x000C0104, SendParameter, "SendParameter"}, 20 {0x000C0104, SendParameter, "SendParameter"},
21 {0x000D0080, ReceiveParameter, "ReceiveParameter"}, 21 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
22 {0x000E0080, GlanceParameter, "GlanceParameter"}, 22 {0x000E0080, GlanceParameter, "GlanceParameter"},
23 {0x000F0100, CancelParameter, "CancelParameter"}, 23 {0x000F0100, CancelParameter, "CancelParameter"},
24 {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, 24 {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
25 {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, 25 {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
26 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, 26 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
27 {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, 27 {0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
28 {0x003B0040, nullptr, "CancelLibraryApplet?"}, 28 {0x003B0040, nullptr, "CancelLibraryApplet?"},
29 {0x003E0080, nullptr, "ReplySleepQuery"}, 29 {0x003E0080, nullptr, "ReplySleepQuery"},
30 {0x00430040, NotifyToWait, "NotifyToWait?"}, 30 {0x00430040, NotifyToWait, "NotifyToWait?"},
31 {0x00440000, GetSharedFont, "GetSharedFont?"}, 31 {0x00440000, GetSharedFont, "GetSharedFont?"},
32 {0x004B00C2, AppletUtility, "AppletUtility?"}, 32 {0x004B00C2, AppletUtility, "AppletUtility?"},
33 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, 33 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
34 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, 34 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
35 {0x00510080, GetStartupArgument, "GetStartupArgument"}, 35 {0x00510080, GetStartupArgument, "GetStartupArgument"},
36 {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, 36 {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"},
37 {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, 37 {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
38 {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, 38 {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
39 {0x01020000, CheckNew3DS, "CheckNew3DS"} 39 {0x01020000, CheckNew3DS, "CheckNew3DS"},
40}; 40};
41 41
42APT_A_Interface::APT_A_Interface() { 42APT_A_Interface::APT_A_Interface() {
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index c70f2201f..c4556a5de 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -9,94 +9,94 @@ namespace Service {
9namespace APT { 9namespace APT {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, GetLockHandle, "GetLockHandle"}, 12 {0x00010040, GetLockHandle, "GetLockHandle"},
13 {0x00020080, Initialize, "Initialize"}, 13 {0x00020080, Initialize, "Initialize"},
14 {0x00030040, Enable, "Enable"}, 14 {0x00030040, Enable, "Enable"},
15 {0x00040040, nullptr, "Finalize"}, 15 {0x00040040, nullptr, "Finalize"},
16 {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, 16 {0x00050040, GetAppletManInfo, "GetAppletManInfo"},
17 {0x00060040, GetAppletInfo, "GetAppletInfo"}, 17 {0x00060040, GetAppletInfo, "GetAppletInfo"},
18 {0x00070000, nullptr, "GetLastSignaledAppletId"}, 18 {0x00070000, nullptr, "GetLastSignaledAppletId"},
19 {0x00080000, nullptr, "CountRegisteredApplet"}, 19 {0x00080000, nullptr, "CountRegisteredApplet"},
20 {0x00090040, nullptr, "IsRegistered"}, 20 {0x00090040, nullptr, "IsRegistered"},
21 {0x000A0040, nullptr, "GetAttribute"}, 21 {0x000A0040, nullptr, "GetAttribute"},
22 {0x000B0040, InquireNotification, "InquireNotification"}, 22 {0x000B0040, InquireNotification, "InquireNotification"},
23 {0x000C0104, nullptr, "SendParameter"}, 23 {0x000C0104, nullptr, "SendParameter"},
24 {0x000D0080, ReceiveParameter, "ReceiveParameter"}, 24 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
25 {0x000E0080, GlanceParameter, "GlanceParameter"}, 25 {0x000E0080, GlanceParameter, "GlanceParameter"},
26 {0x000F0100, nullptr, "CancelParameter"}, 26 {0x000F0100, nullptr, "CancelParameter"},
27 {0x001000C2, nullptr, "DebugFunc"}, 27 {0x001000C2, nullptr, "DebugFunc"},
28 {0x001100C0, nullptr, "MapProgramIdForDebug"}, 28 {0x001100C0, nullptr, "MapProgramIdForDebug"},
29 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, 29 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
30 {0x00130000, nullptr, "GetPreparationState"}, 30 {0x00130000, nullptr, "GetPreparationState"},
31 {0x00140040, nullptr, "SetPreparationState"}, 31 {0x00140040, nullptr, "SetPreparationState"},
32 {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, 32 {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
33 {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, 33 {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
34 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, 34 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
35 {0x00180040, PrepareToStartLibraryApplet,"PrepareToStartLibraryApplet"}, 35 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
36 {0x00190040, nullptr, "PrepareToStartSystemApplet"}, 36 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
37 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, 37 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
38 {0x001B00C4, nullptr, "StartApplication"}, 38 {0x001B00C4, nullptr, "StartApplication"},
39 {0x001C0000, nullptr, "WakeupApplication"}, 39 {0x001C0000, nullptr, "WakeupApplication"},
40 {0x001D0000, nullptr, "CancelApplication"}, 40 {0x001D0000, nullptr, "CancelApplication"},
41 {0x001E0084, nullptr, "StartLibraryApplet"}, 41 {0x001E0084, nullptr, "StartLibraryApplet"},
42 {0x001F0084, nullptr, "StartSystemApplet"}, 42 {0x001F0084, nullptr, "StartSystemApplet"},
43 {0x00200044, nullptr, "StartNewestHomeMenu"}, 43 {0x00200044, nullptr, "StartNewestHomeMenu"},
44 {0x00210000, nullptr, "OrderToCloseApplication"}, 44 {0x00210000, nullptr, "OrderToCloseApplication"},
45 {0x00220040, nullptr, "PrepareToCloseApplication"}, 45 {0x00220040, nullptr, "PrepareToCloseApplication"},
46 {0x00230040, nullptr, "PrepareToJumpToApplication"}, 46 {0x00230040, nullptr, "PrepareToJumpToApplication"},
47 {0x00240044, nullptr, "JumpToApplication"}, 47 {0x00240044, nullptr, "JumpToApplication"},
48 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, 48 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
49 {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, 49 {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
50 {0x00270044, nullptr, "CloseApplication"}, 50 {0x00270044, nullptr, "CloseApplication"},
51 {0x00280044, nullptr, "CloseLibraryApplet"}, 51 {0x00280044, nullptr, "CloseLibraryApplet"},
52 {0x00290044, nullptr, "CloseSystemApplet"}, 52 {0x00290044, nullptr, "CloseSystemApplet"},
53 {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, 53 {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
54 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, 54 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
55 {0x002C0044, nullptr, "JumpToHomeMenu"}, 55 {0x002C0044, nullptr, "JumpToHomeMenu"},
56 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, 56 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
57 {0x002E0044, nullptr, "LeaveHomeMenu"}, 57 {0x002E0044, nullptr, "LeaveHomeMenu"},
58 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, 58 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
59 {0x00300044, nullptr, "LeaveResidentApplet"}, 59 {0x00300044, nullptr, "LeaveResidentApplet"},
60 {0x00310100, nullptr, "PrepareToDoApplicationJump"}, 60 {0x00310100, nullptr, "PrepareToDoApplicationJump"},
61 {0x00320084, nullptr, "DoApplicationJump"}, 61 {0x00320084, nullptr, "DoApplicationJump"},
62 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, 62 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
63 {0x00340084, nullptr, "SendDeliverArg"}, 63 {0x00340084, nullptr, "SendDeliverArg"},
64 {0x00350080, nullptr, "ReceiveDeliverArg"}, 64 {0x00350080, nullptr, "ReceiveDeliverArg"},
65 {0x00360040, nullptr, "LoadSysMenuArg"}, 65 {0x00360040, nullptr, "LoadSysMenuArg"},
66 {0x00370042, nullptr, "StoreSysMenuArg"}, 66 {0x00370042, nullptr, "StoreSysMenuArg"},
67 {0x00380040, nullptr, "PreloadResidentApplet"}, 67 {0x00380040, nullptr, "PreloadResidentApplet"},
68 {0x00390040, nullptr, "PrepareToStartResidentApplet"}, 68 {0x00390040, nullptr, "PrepareToStartResidentApplet"},
69 {0x003A0044, nullptr, "StartResidentApplet"}, 69 {0x003A0044, nullptr, "StartResidentApplet"},
70 {0x003B0040, nullptr, "CancelLibraryApplet"}, 70 {0x003B0040, nullptr, "CancelLibraryApplet"},
71 {0x003C0042, nullptr, "SendDspSleep"}, 71 {0x003C0042, nullptr, "SendDspSleep"},
72 {0x003D0042, nullptr, "SendDspWakeUp"}, 72 {0x003D0042, nullptr, "SendDspWakeUp"},
73 {0x003E0080, nullptr, "ReplySleepQuery"}, 73 {0x003E0080, nullptr, "ReplySleepQuery"},
74 {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, 74 {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
75 {0x00400042, nullptr, "SendCaptureBufferInfo"}, 75 {0x00400042, nullptr, "SendCaptureBufferInfo"},
76 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, 76 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
77 {0x00420080, nullptr, "SleepSystem"}, 77 {0x00420080, nullptr, "SleepSystem"},
78 {0x00430040, NotifyToWait, "NotifyToWait"}, 78 {0x00430040, NotifyToWait, "NotifyToWait"},
79 {0x00440000, GetSharedFont, "GetSharedFont"}, 79 {0x00440000, GetSharedFont, "GetSharedFont"},
80 {0x00450040, nullptr, "GetWirelessRebootInfo"}, 80 {0x00450040, nullptr, "GetWirelessRebootInfo"},
81 {0x00460104, nullptr, "Wrap"}, 81 {0x00460104, nullptr, "Wrap"},
82 {0x00470104, nullptr, "Unwrap"}, 82 {0x00470104, nullptr, "Unwrap"},
83 {0x00480100, nullptr, "GetProgramInfo"}, 83 {0x00480100, nullptr, "GetProgramInfo"},
84 {0x00490180, nullptr, "Reboot"}, 84 {0x00490180, nullptr, "Reboot"},
85 {0x004A0040, nullptr, "GetCaptureInfo"}, 85 {0x004A0040, nullptr, "GetCaptureInfo"},
86 {0x004B00C2, AppletUtility, "AppletUtility"}, 86 {0x004B00C2, AppletUtility, "AppletUtility"},
87 {0x004C0000, nullptr, "SetFatalErrDispMode"}, 87 {0x004C0000, nullptr, "SetFatalErrDispMode"},
88 {0x004D0080, nullptr, "GetAppletProgramInfo"}, 88 {0x004D0080, nullptr, "GetAppletProgramInfo"},
89 {0x004E0000, nullptr, "HardwareResetAsync"}, 89 {0x004E0000, nullptr, "HardwareResetAsync"},
90 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, 90 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
91 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, 91 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
92 {0x00510080, GetStartupArgument, "GetStartupArgument"}, 92 {0x00510080, GetStartupArgument, "GetStartupArgument"},
93 {0x00520104, nullptr, "Wrap1"}, 93 {0x00520104, nullptr, "Wrap1"},
94 {0x00530104, nullptr, "Unwrap1"}, 94 {0x00530104, nullptr, "Unwrap1"},
95 {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, 95 {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"},
96 {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, 96 {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
97 {0x00580002, nullptr, "GetProgramID"}, 97 {0x00580002, nullptr, "GetProgramID"},
98 {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, 98 {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
99 {0x01020000, CheckNew3DS, "CheckNew3DS"} 99 {0x01020000, CheckNew3DS, "CheckNew3DS"},
100}; 100};
101 101
102APT_S_Interface::APT_S_Interface() { 102APT_S_Interface::APT_S_Interface() {
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp
index 7bb804ffa..d6ad42e21 100644
--- a/src/core/hle/service/apt/apt_u.cpp
+++ b/src/core/hle/service/apt/apt_u.cpp
@@ -9,94 +9,94 @@ namespace Service {
9namespace APT { 9namespace APT {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, GetLockHandle, "GetLockHandle"}, 12 {0x00010040, GetLockHandle, "GetLockHandle"},
13 {0x00020080, Initialize, "Initialize"}, 13 {0x00020080, Initialize, "Initialize"},
14 {0x00030040, Enable, "Enable"}, 14 {0x00030040, Enable, "Enable"},
15 {0x00040040, nullptr, "Finalize"}, 15 {0x00040040, nullptr, "Finalize"},
16 {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, 16 {0x00050040, GetAppletManInfo, "GetAppletManInfo"},
17 {0x00060040, GetAppletInfo, "GetAppletInfo"}, 17 {0x00060040, GetAppletInfo, "GetAppletInfo"},
18 {0x00070000, nullptr, "GetLastSignaledAppletId"}, 18 {0x00070000, nullptr, "GetLastSignaledAppletId"},
19 {0x00080000, nullptr, "CountRegisteredApplet"}, 19 {0x00080000, nullptr, "CountRegisteredApplet"},
20 {0x00090040, IsRegistered, "IsRegistered"}, 20 {0x00090040, IsRegistered, "IsRegistered"},
21 {0x000A0040, nullptr, "GetAttribute"}, 21 {0x000A0040, nullptr, "GetAttribute"},
22 {0x000B0040, InquireNotification, "InquireNotification"}, 22 {0x000B0040, InquireNotification, "InquireNotification"},
23 {0x000C0104, SendParameter, "SendParameter"}, 23 {0x000C0104, SendParameter, "SendParameter"},
24 {0x000D0080, ReceiveParameter, "ReceiveParameter"}, 24 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
25 {0x000E0080, GlanceParameter, "GlanceParameter"}, 25 {0x000E0080, GlanceParameter, "GlanceParameter"},
26 {0x000F0100, CancelParameter, "CancelParameter"}, 26 {0x000F0100, CancelParameter, "CancelParameter"},
27 {0x001000C2, nullptr, "DebugFunc"}, 27 {0x001000C2, nullptr, "DebugFunc"},
28 {0x001100C0, nullptr, "MapProgramIdForDebug"}, 28 {0x001100C0, nullptr, "MapProgramIdForDebug"},
29 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, 29 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
30 {0x00130000, nullptr, "GetPreparationState"}, 30 {0x00130000, nullptr, "GetPreparationState"},
31 {0x00140040, nullptr, "SetPreparationState"}, 31 {0x00140040, nullptr, "SetPreparationState"},
32 {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, 32 {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
33 {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, 33 {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
34 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, 34 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
35 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, 35 {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
36 {0x00190040, nullptr, "PrepareToStartSystemApplet"}, 36 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
37 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, 37 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
38 {0x001B00C4, nullptr, "StartApplication"}, 38 {0x001B00C4, nullptr, "StartApplication"},
39 {0x001C0000, nullptr, "WakeupApplication"}, 39 {0x001C0000, nullptr, "WakeupApplication"},
40 {0x001D0000, nullptr, "CancelApplication"}, 40 {0x001D0000, nullptr, "CancelApplication"},
41 {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, 41 {0x001E0084, StartLibraryApplet, "StartLibraryApplet"},
42 {0x001F0084, nullptr, "StartSystemApplet"}, 42 {0x001F0084, nullptr, "StartSystemApplet"},
43 {0x00200044, nullptr, "StartNewestHomeMenu"}, 43 {0x00200044, nullptr, "StartNewestHomeMenu"},
44 {0x00210000, nullptr, "OrderToCloseApplication"}, 44 {0x00210000, nullptr, "OrderToCloseApplication"},
45 {0x00220040, nullptr, "PrepareToCloseApplication"}, 45 {0x00220040, nullptr, "PrepareToCloseApplication"},
46 {0x00230040, nullptr, "PrepareToJumpToApplication"}, 46 {0x00230040, nullptr, "PrepareToJumpToApplication"},
47 {0x00240044, nullptr, "JumpToApplication"}, 47 {0x00240044, nullptr, "JumpToApplication"},
48 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, 48 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
49 {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, 49 {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
50 {0x00270044, nullptr, "CloseApplication"}, 50 {0x00270044, nullptr, "CloseApplication"},
51 {0x00280044, nullptr, "CloseLibraryApplet"}, 51 {0x00280044, nullptr, "CloseLibraryApplet"},
52 {0x00290044, nullptr, "CloseSystemApplet"}, 52 {0x00290044, nullptr, "CloseSystemApplet"},
53 {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, 53 {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
54 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, 54 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
55 {0x002C0044, nullptr, "JumpToHomeMenu"}, 55 {0x002C0044, nullptr, "JumpToHomeMenu"},
56 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, 56 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
57 {0x002E0044, nullptr, "LeaveHomeMenu"}, 57 {0x002E0044, nullptr, "LeaveHomeMenu"},
58 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, 58 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
59 {0x00300044, nullptr, "LeaveResidentApplet"}, 59 {0x00300044, nullptr, "LeaveResidentApplet"},
60 {0x00310100, nullptr, "PrepareToDoApplicationJump"}, 60 {0x00310100, nullptr, "PrepareToDoApplicationJump"},
61 {0x00320084, nullptr, "DoApplicationJump"}, 61 {0x00320084, nullptr, "DoApplicationJump"},
62 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, 62 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
63 {0x00340084, nullptr, "SendDeliverArg"}, 63 {0x00340084, nullptr, "SendDeliverArg"},
64 {0x00350080, nullptr, "ReceiveDeliverArg"}, 64 {0x00350080, nullptr, "ReceiveDeliverArg"},
65 {0x00360040, nullptr, "LoadSysMenuArg"}, 65 {0x00360040, nullptr, "LoadSysMenuArg"},
66 {0x00370042, nullptr, "StoreSysMenuArg"}, 66 {0x00370042, nullptr, "StoreSysMenuArg"},
67 {0x00380040, nullptr, "PreloadResidentApplet"}, 67 {0x00380040, nullptr, "PreloadResidentApplet"},
68 {0x00390040, nullptr, "PrepareToStartResidentApplet"}, 68 {0x00390040, nullptr, "PrepareToStartResidentApplet"},
69 {0x003A0044, nullptr, "StartResidentApplet"}, 69 {0x003A0044, nullptr, "StartResidentApplet"},
70 {0x003B0040, nullptr, "CancelLibraryApplet"}, 70 {0x003B0040, nullptr, "CancelLibraryApplet"},
71 {0x003C0042, nullptr, "SendDspSleep"}, 71 {0x003C0042, nullptr, "SendDspSleep"},
72 {0x003D0042, nullptr, "SendDspWakeUp"}, 72 {0x003D0042, nullptr, "SendDspWakeUp"},
73 {0x003E0080, nullptr, "ReplySleepQuery"}, 73 {0x003E0080, nullptr, "ReplySleepQuery"},
74 {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, 74 {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
75 {0x00400042, nullptr, "SendCaptureBufferInfo"}, 75 {0x00400042, nullptr, "SendCaptureBufferInfo"},
76 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, 76 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
77 {0x00420080, nullptr, "SleepSystem"}, 77 {0x00420080, nullptr, "SleepSystem"},
78 {0x00430040, NotifyToWait, "NotifyToWait"}, 78 {0x00430040, NotifyToWait, "NotifyToWait"},
79 {0x00440000, GetSharedFont, "GetSharedFont"}, 79 {0x00440000, GetSharedFont, "GetSharedFont"},
80 {0x00450040, nullptr, "GetWirelessRebootInfo"}, 80 {0x00450040, nullptr, "GetWirelessRebootInfo"},
81 {0x00460104, nullptr, "Wrap"}, 81 {0x00460104, nullptr, "Wrap"},
82 {0x00470104, nullptr, "Unwrap"}, 82 {0x00470104, nullptr, "Unwrap"},
83 {0x00480100, nullptr, "GetProgramInfo"}, 83 {0x00480100, nullptr, "GetProgramInfo"},
84 {0x00490180, nullptr, "Reboot"}, 84 {0x00490180, nullptr, "Reboot"},
85 {0x004A0040, nullptr, "GetCaptureInfo"}, 85 {0x004A0040, nullptr, "GetCaptureInfo"},
86 {0x004B00C2, AppletUtility, "AppletUtility"}, 86 {0x004B00C2, AppletUtility, "AppletUtility"},
87 {0x004C0000, nullptr, "SetFatalErrDispMode"}, 87 {0x004C0000, nullptr, "SetFatalErrDispMode"},
88 {0x004D0080, nullptr, "GetAppletProgramInfo"}, 88 {0x004D0080, nullptr, "GetAppletProgramInfo"},
89 {0x004E0000, nullptr, "HardwareResetAsync"}, 89 {0x004E0000, nullptr, "HardwareResetAsync"},
90 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, 90 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
91 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, 91 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
92 {0x00510080, GetStartupArgument, "GetStartupArgument"}, 92 {0x00510080, GetStartupArgument, "GetStartupArgument"},
93 {0x00520104, nullptr, "Wrap1"}, 93 {0x00520104, nullptr, "Wrap1"},
94 {0x00530104, nullptr, "Unwrap1"}, 94 {0x00530104, nullptr, "Unwrap1"},
95 {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, 95 {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"},
96 {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, 96 {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"},
97 {0x00580002, nullptr, "GetProgramID"}, 97 {0x00580002, nullptr, "GetProgramID"},
98 {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, 98 {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"},
99 {0x01020000, CheckNew3DS, "CheckNew3DS"} 99 {0x01020000, CheckNew3DS, "CheckNew3DS"},
100}; 100};
101 101
102APT_U_Interface::APT_U_Interface() { 102APT_U_Interface::APT_U_Interface() {
diff --git a/src/core/hle/service/apt/bcfnt/bcfnt.h b/src/core/hle/service/apt/bcfnt/bcfnt.h
index 8936dcf63..453bf7606 100644
--- a/src/core/hle/service/apt/bcfnt/bcfnt.h
+++ b/src/core/hle/service/apt/bcfnt/bcfnt.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include "common/swap.h" 7#include "common/swap.h"
8
9#include "core/hle/kernel/shared_memory.h" 8#include "core/hle/kernel/shared_memory.h"
10#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
11 10
diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp
index 419ec976e..757a8c2c7 100644
--- a/src/core/hle/service/boss/boss.cpp
+++ b/src/core/hle/service/boss/boss.cpp
@@ -2,10 +2,10 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/service.h"
6#include "core/hle/service/boss/boss.h" 5#include "core/hle/service/boss/boss.h"
7#include "core/hle/service/boss/boss_p.h" 6#include "core/hle/service/boss/boss_p.h"
8#include "core/hle/service/boss/boss_u.h" 7#include "core/hle/service/boss/boss_u.h"
8#include "core/hle/service/service.h"
9 9
10namespace Service { 10namespace Service {
11namespace BOSS { 11namespace BOSS {
@@ -17,8 +17,7 @@ void Init() {
17 AddService(new BOSS_U_Interface); 17 AddService(new BOSS_U_Interface);
18} 18}
19 19
20void Shutdown() { 20void Shutdown() {}
21}
22 21
23} // namespace BOSS 22} // namespace BOSS
24 23
diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp
index c498abe4e..dfee8d055 100644
--- a/src/core/hle/service/boss/boss_p.cpp
+++ b/src/core/hle/service/boss/boss_p.cpp
@@ -11,7 +11,7 @@ namespace BOSS {
11// const Interface::FunctionInfo FunctionTable[] = { }; 11// const Interface::FunctionInfo FunctionTable[] = { };
12 12
13BOSS_P_Interface::BOSS_P_Interface() { 13BOSS_P_Interface::BOSS_P_Interface() {
14 //Register(FunctionTable); 14 // Register(FunctionTable);
15} 15}
16 16
17} // namespace BOSS 17} // namespace BOSS
diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp
index d59babe71..6affa23b1 100644
--- a/src/core/hle/service/boss/boss_u.cpp
+++ b/src/core/hle/service/boss/boss_u.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace BOSS { 8namespace BOSS {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x00020100, nullptr, "GetStorageInfo"}, 11 {0x00020100, nullptr, "GetStorageInfo"},
12 {0x000C0082, nullptr, "UnregisterTask"}, 12 {0x000C0082, nullptr, "UnregisterTask"},
13 {0x001E0042, nullptr, "CancelTask"}, 13 {0x001E0042, nullptr, "CancelTask"},
14 {0x00330042, nullptr, "StartBgImmediate"}, 14 {0x00330042, nullptr, "StartBgImmediate"},
15}; 15};
16 16
17BOSS_U_Interface::BOSS_U_Interface() { 17BOSS_U_Interface::BOSS_U_Interface() {
diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp
index 6edcf9610..5594aedab 100644
--- a/src/core/hle/service/cam/cam.cpp
+++ b/src/core/hle/service/cam/cam.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6
7#include "core/hle/kernel/event.h" 6#include "core/hle/kernel/event.h"
8#include "core/hle/service/cam/cam.h" 7#include "core/hle/service/cam/cam.h"
9#include "core/hle/service/cam/cam_c.h" 8#include "core/hle/service/cam/cam_c.h"
@@ -71,15 +70,15 @@ void GetBufferErrorInterruptEvent(Service::Interface* self) {
71} 70}
72 71
73void SetReceiving(Service::Interface* self) { 72void SetReceiving(Service::Interface* self) {
74 u32* cmd_buff = Kernel::GetCommandBuffer(); 73 u32* cmd_buff = Kernel::GetCommandBuffer();
75 74
76 VAddr dest = cmd_buff[1]; 75 VAddr dest = cmd_buff[1];
77 u8 port = cmd_buff[2] & 0xFF; 76 u8 port = cmd_buff[2] & 0xFF;
78 u32 image_size = cmd_buff[3]; 77 u32 image_size = cmd_buff[3];
79 u16 trans_unit = cmd_buff[4] & 0xFFFF; 78 u16 trans_unit = cmd_buff[4] & 0xFFFF;
80 79
81 Kernel::Event* completion_event = (Port)port == Port::Cam2 ? 80 Kernel::Event* completion_event =
82 completion_event_cam2.get() : completion_event_cam1.get(); 81 (Port)port == Port::Cam2 ? completion_event_cam2.get() : completion_event_cam1.get();
83 82
84 completion_event->Signal(); 83 completion_event->Signal();
85 84
@@ -89,36 +88,36 @@ void SetReceiving(Service::Interface* self) {
89 cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); 88 cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom();
90 89
91 LOG_WARNING(Service_CAM, "(STUBBED) called, addr=0x%X, port=%d, image_size=%d, trans_unit=%d", 90 LOG_WARNING(Service_CAM, "(STUBBED) called, addr=0x%X, port=%d, image_size=%d, trans_unit=%d",
92 dest, port, image_size, trans_unit); 91 dest, port, image_size, trans_unit);
93} 92}
94 93
95void SetTransferLines(Service::Interface* self) { 94void SetTransferLines(Service::Interface* self) {
96 u32* cmd_buff = Kernel::GetCommandBuffer(); 95 u32* cmd_buff = Kernel::GetCommandBuffer();
97 96
98 u8 port = cmd_buff[1] & 0xFF; 97 u8 port = cmd_buff[1] & 0xFF;
99 u16 transfer_lines = cmd_buff[2] & 0xFFFF; 98 u16 transfer_lines = cmd_buff[2] & 0xFFFF;
100 u16 width = cmd_buff[3] & 0xFFFF; 99 u16 width = cmd_buff[3] & 0xFFFF;
101 u16 height = cmd_buff[4] & 0xFFFF; 100 u16 height = cmd_buff[4] & 0xFFFF;
102 101
103 cmd_buff[0] = IPC::MakeHeader(0x9, 1, 0); 102 cmd_buff[0] = IPC::MakeHeader(0x9, 1, 0);
104 cmd_buff[1] = RESULT_SUCCESS.raw; 103 cmd_buff[1] = RESULT_SUCCESS.raw;
105 104
106 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, lines=%d, width=%d, height=%d", 105 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, lines=%d, width=%d, height=%d", port,
107 port, transfer_lines, width, height); 106 transfer_lines, width, height);
108} 107}
109 108
110void GetMaxLines(Service::Interface* self) { 109void GetMaxLines(Service::Interface* self) {
111 u32* cmd_buff = Kernel::GetCommandBuffer(); 110 u32* cmd_buff = Kernel::GetCommandBuffer();
112 111
113 u16 width = cmd_buff[1] & 0xFFFF; 112 u16 width = cmd_buff[1] & 0xFFFF;
114 u16 height = cmd_buff[2] & 0xFFFF; 113 u16 height = cmd_buff[2] & 0xFFFF;
115 114
116 cmd_buff[0] = IPC::MakeHeader(0xA, 2, 0); 115 cmd_buff[0] = IPC::MakeHeader(0xA, 2, 0);
117 cmd_buff[1] = RESULT_SUCCESS.raw; 116 cmd_buff[1] = RESULT_SUCCESS.raw;
118 cmd_buff[2] = TRANSFER_BYTES / (2 * width); 117 cmd_buff[2] = TRANSFER_BYTES / (2 * width);
119 118
120 LOG_WARNING(Service_CAM, "(STUBBED) called, width=%d, height=%d, lines = %d", 119 LOG_WARNING(Service_CAM, "(STUBBED) called, width=%d, height=%d, lines = %d", width, height,
121 width, height, cmd_buff[2]); 120 cmd_buff[2]);
122} 121}
123 122
124void GetTransferBytes(Service::Interface* self) { 123void GetTransferBytes(Service::Interface* self) {
@@ -136,7 +135,7 @@ void GetTransferBytes(Service::Interface* self) {
136void SetTrimming(Service::Interface* self) { 135void SetTrimming(Service::Interface* self) {
137 u32* cmd_buff = Kernel::GetCommandBuffer(); 136 u32* cmd_buff = Kernel::GetCommandBuffer();
138 137
139 u8 port = cmd_buff[1] & 0xFF; 138 u8 port = cmd_buff[1] & 0xFF;
140 bool trim = (cmd_buff[2] & 0xFF) != 0; 139 bool trim = (cmd_buff[2] & 0xFF) != 0;
141 140
142 cmd_buff[0] = IPC::MakeHeader(0xE, 1, 0); 141 cmd_buff[0] = IPC::MakeHeader(0xE, 1, 0);
@@ -148,17 +147,17 @@ void SetTrimming(Service::Interface* self) {
148void SetTrimmingParamsCenter(Service::Interface* self) { 147void SetTrimmingParamsCenter(Service::Interface* self) {
149 u32* cmd_buff = Kernel::GetCommandBuffer(); 148 u32* cmd_buff = Kernel::GetCommandBuffer();
150 149
151 u8 port = cmd_buff[1] & 0xFF; 150 u8 port = cmd_buff[1] & 0xFF;
152 s16 trimW = cmd_buff[2] & 0xFFFF; 151 s16 trimW = cmd_buff[2] & 0xFFFF;
153 s16 trimH = cmd_buff[3] & 0xFFFF; 152 s16 trimH = cmd_buff[3] & 0xFFFF;
154 s16 camW = cmd_buff[4] & 0xFFFF; 153 s16 camW = cmd_buff[4] & 0xFFFF;
155 s16 camH = cmd_buff[5] & 0xFFFF; 154 s16 camH = cmd_buff[5] & 0xFFFF;
156 155
157 cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0); 156 cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0);
158 cmd_buff[1] = RESULT_SUCCESS.raw; 157 cmd_buff[1] = RESULT_SUCCESS.raw;
159 158
160 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trimW=%d, trimH=%d, camW=%d, camH=%d", 159 LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trimW=%d, trimH=%d, camW=%d, camH=%d",
161 port, trimW, trimH, camW, camH); 160 port, trimW, trimH, camW, camH);
162} 161}
163 162
164void Activate(Service::Interface* self) { 163void Activate(Service::Interface* self) {
@@ -169,36 +168,35 @@ void Activate(Service::Interface* self) {
169 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); 168 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0);
170 cmd_buff[1] = RESULT_SUCCESS.raw; 169 cmd_buff[1] = RESULT_SUCCESS.raw;
171 170
172 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d", 171 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d", cam_select);
173 cam_select);
174} 172}
175 173
176void FlipImage(Service::Interface* self) { 174void FlipImage(Service::Interface* self) {
177 u32* cmd_buff = Kernel::GetCommandBuffer(); 175 u32* cmd_buff = Kernel::GetCommandBuffer();
178 176
179 u8 cam_select = cmd_buff[1] & 0xFF; 177 u8 cam_select = cmd_buff[1] & 0xFF;
180 u8 flip = cmd_buff[2] & 0xFF; 178 u8 flip = cmd_buff[2] & 0xFF;
181 u8 context = cmd_buff[3] & 0xFF; 179 u8 context = cmd_buff[3] & 0xFF;
182 180
183 cmd_buff[0] = IPC::MakeHeader(0x1D, 1, 0); 181 cmd_buff[0] = IPC::MakeHeader(0x1D, 1, 0);
184 cmd_buff[1] = RESULT_SUCCESS.raw; 182 cmd_buff[1] = RESULT_SUCCESS.raw;
185 183
186 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, flip=%d, context=%d", 184 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, flip=%d, context=%d", cam_select,
187 cam_select, flip, context); 185 flip, context);
188} 186}
189 187
190void SetSize(Service::Interface* self) { 188void SetSize(Service::Interface* self) {
191 u32* cmd_buff = Kernel::GetCommandBuffer(); 189 u32* cmd_buff = Kernel::GetCommandBuffer();
192 190
193 u8 cam_select = cmd_buff[1] & 0xFF; 191 u8 cam_select = cmd_buff[1] & 0xFF;
194 u8 size = cmd_buff[2] & 0xFF; 192 u8 size = cmd_buff[2] & 0xFF;
195 u8 context = cmd_buff[3] & 0xFF; 193 u8 context = cmd_buff[3] & 0xFF;
196 194
197 cmd_buff[0] = IPC::MakeHeader(0x1F, 1, 0); 195 cmd_buff[0] = IPC::MakeHeader(0x1F, 1, 0);
198 cmd_buff[1] = RESULT_SUCCESS.raw; 196 cmd_buff[1] = RESULT_SUCCESS.raw;
199 197
200 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, size=%d, context=%d", 198 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, size=%d, context=%d", cam_select,
201 cam_select, size, context); 199 size, context);
202} 200}
203 201
204void SetFrameRate(Service::Interface* self) { 202void SetFrameRate(Service::Interface* self) {
@@ -210,8 +208,8 @@ void SetFrameRate(Service::Interface* self) {
210 cmd_buff[0] = IPC::MakeHeader(0x20, 1, 0); 208 cmd_buff[0] = IPC::MakeHeader(0x20, 1, 0);
211 cmd_buff[1] = RESULT_SUCCESS.raw; 209 cmd_buff[1] = RESULT_SUCCESS.raw;
212 210
213 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, frame_rate=%d", 211 LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, frame_rate=%d", cam_select,
214 cam_select, frame_rate); 212 frame_rate);
215} 213}
216 214
217void GetStereoCameraCalibrationData(Service::Interface* self) { 215void GetStereoCameraCalibrationData(Service::Interface* self) {
@@ -293,10 +291,14 @@ void Init() {
293 AddService(new CAM_S_Interface); 291 AddService(new CAM_S_Interface);
294 AddService(new CAM_U_Interface); 292 AddService(new CAM_U_Interface);
295 293
296 completion_event_cam1 = Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam1"); 294 completion_event_cam1 =
297 completion_event_cam2 = Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam2"); 295 Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam1");
298 interrupt_error_event = Kernel::Event::Create(ResetType::OneShot, "CAM_U::interrupt_error_event"); 296 completion_event_cam2 =
299 vsync_interrupt_error_event = Kernel::Event::Create(ResetType::OneShot, "CAM_U::vsync_interrupt_error_event"); 297 Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam2");
298 interrupt_error_event =
299 Kernel::Event::Create(ResetType::OneShot, "CAM_U::interrupt_error_event");
300 vsync_interrupt_error_event =
301 Kernel::Event::Create(ResetType::OneShot, "CAM_U::vsync_interrupt_error_event");
300} 302}
301 303
302void Shutdown() { 304void Shutdown() {
diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h
index 2f4923728..c9b6f8acf 100644
--- a/src/core/hle/service/cam/cam.h
+++ b/src/core/hle/service/cam/cam.h
@@ -7,19 +7,13 @@
7#include "common/common_funcs.h" 7#include "common/common_funcs.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/swap.h" 9#include "common/swap.h"
10
11#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
12#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
13 12
14namespace Service { 13namespace Service {
15namespace CAM { 14namespace CAM {
16 15
17enum class Port : u8 { 16enum class Port : u8 { None = 0, Cam1 = 1, Cam2 = 2, Both = Cam1 | Cam2 };
18 None = 0,
19 Cam1 = 1,
20 Cam2 = 2,
21 Both = Cam1 | Cam2
22};
23 17
24enum class CameraSelect : u8 { 18enum class CameraSelect : u8 {
25 None = 0, 19 None = 0,
@@ -29,7 +23,7 @@ enum class CameraSelect : u8 {
29 In1Out1 = Out1 | In1, 23 In1Out1 = Out1 | In1,
30 Out1Out2 = Out1 | Out2, 24 Out1Out2 = Out1 | Out2,
31 In1Out2 = In1 | Out2, 25 In1Out2 = In1 | Out2,
32 All = Out1 | In1 | Out2 26 All = Out1 | In1 | Out2,
33}; 27};
34 28
35enum class Effect : u8 { 29enum class Effect : u8 {
@@ -38,21 +32,21 @@ enum class Effect : u8 {
38 Sepia = 2, 32 Sepia = 2,
39 Negative = 3, 33 Negative = 3,
40 Negafilm = 4, 34 Negafilm = 4,
41 Sepia01 = 5 35 Sepia01 = 5,
42}; 36};
43 37
44enum class Context : u8 { 38enum class Context : u8 {
45 None = 0, 39 None = 0,
46 A = 1, 40 A = 1,
47 B = 2, 41 B = 2,
48 Both = A | B 42 Both = A | B,
49}; 43};
50 44
51enum class Flip : u8 { 45enum class Flip : u8 {
52 None = 0, 46 None = 0,
53 Horizontal = 1, 47 Horizontal = 1,
54 Vertical = 2, 48 Vertical = 2,
55 Reverse = 3 49 Reverse = 3,
56}; 50};
57 51
58enum class Size : u8 { 52enum class Size : u8 {
@@ -64,7 +58,7 @@ enum class Size : u8 {
64 DS_LCD = 5, 58 DS_LCD = 5,
65 DS_LCDx4 = 6, 59 DS_LCDx4 = 6,
66 CTR_TOP_LCD = 7, 60 CTR_TOP_LCD = 7,
67 CTR_BOTTOM_LCD = QVGA 61 CTR_BOTTOM_LCD = QVGA,
68}; 62};
69 63
70enum class FrameRate : u8 { 64enum class FrameRate : u8 {
@@ -80,13 +74,13 @@ enum class FrameRate : u8 {
80 Rate_30_To_5 = 9, 74 Rate_30_To_5 = 9,
81 Rate_15_To_10 = 10, 75 Rate_15_To_10 = 10,
82 Rate_20_To_10 = 11, 76 Rate_20_To_10 = 11,
83 Rate_30_To_10 = 12 77 Rate_30_To_10 = 12,
84}; 78};
85 79
86enum class ShutterSoundType : u8 { 80enum class ShutterSoundType : u8 {
87 Normal = 0, 81 Normal = 0,
88 Movie = 1, 82 Movie = 1,
89 MovieEnd = 2 83 MovieEnd = 2,
90}; 84};
91 85
92enum class WhiteBalance : u8 { 86enum class WhiteBalance : u8 {
@@ -103,7 +97,7 @@ enum class WhiteBalance : u8 {
103 BalanceDaylight = Balance5200K, 97 BalanceDaylight = Balance5200K,
104 BalanceCloudy = Balance6000K, 98 BalanceCloudy = Balance6000K,
105 BalanceHorizon = Balance6000K, 99 BalanceHorizon = Balance6000K,
106 BalanceShade = Balance7000K 100 BalanceShade = Balance7000K,
107}; 101};
108 102
109enum class PhotoMode : u8 { 103enum class PhotoMode : u8 {
@@ -111,7 +105,7 @@ enum class PhotoMode : u8 {
111 Portrait = 1, 105 Portrait = 1,
112 Landscape = 2, 106 Landscape = 2,
113 Nightview = 3, 107 Nightview = 3,
114 Letter0 = 4 108 Letter0 = 4,
115}; 109};
116 110
117enum class LensCorrection : u8 { 111enum class LensCorrection : u8 {
@@ -120,7 +114,7 @@ enum class LensCorrection : u8 {
120 On90 = 2, 114 On90 = 2,
121 Dark = Off, 115 Dark = Off,
122 Normal = On70, 116 Normal = On70,
123 Bright = On90 117 Bright = On90,
124}; 118};
125 119
126enum class Contrast : u8 { 120enum class Contrast : u8 {
@@ -137,24 +131,24 @@ enum class Contrast : u8 {
137 Pattern11 = 11, 131 Pattern11 = 11,
138 Low = Pattern05, 132 Low = Pattern05,
139 Normal = Pattern06, 133 Normal = Pattern06,
140 High = Pattern07 134 High = Pattern07,
141}; 135};
142 136
143enum class OutputFormat : u8 { 137enum class OutputFormat : u8 {
144 YUV422 = 0, 138 YUV422 = 0,
145 RGB565 = 1 139 RGB565 = 1,
146}; 140};
147 141
148/// Stereo camera calibration data. 142/// Stereo camera calibration data.
149struct StereoCameraCalibrationData { 143struct StereoCameraCalibrationData {
150 u8 isValidRotationXY; ///< Bool indicating whether the X and Y rotation data is valid. 144 u8 isValidRotationXY; ///< Bool indicating whether the X and Y rotation data is valid.
151 INSERT_PADDING_BYTES(3); 145 INSERT_PADDING_BYTES(3);
152 float_le scale; ///< Scale to match the left camera image with the right. 146 float_le scale; ///< Scale to match the left camera image with the right.
153 float_le rotationZ; ///< Z axis rotation to match the left camera image with the right. 147 float_le rotationZ; ///< Z axis rotation to match the left camera image with the right.
154 float_le translationX; ///< X axis translation to match the left camera image with the right. 148 float_le translationX; ///< X axis translation to match the left camera image with the right.
155 float_le translationY; ///< Y axis translation to match the left camera image with the right. 149 float_le translationY; ///< Y axis translation to match the left camera image with the right.
156 float_le rotationX; ///< X axis rotation to match the left camera image with the right. 150 float_le rotationX; ///< X axis rotation to match the left camera image with the right.
157 float_le rotationY; ///< Y axis rotation to match the left camera image with the right. 151 float_le rotationY; ///< Y axis rotation to match the left camera image with the right.
158 float_le angleOfViewRight; ///< Right camera angle of view. 152 float_le angleOfViewRight; ///< Right camera angle of view.
159 float_le angleOfViewLeft; ///< Left camera angle of view. 153 float_le angleOfViewLeft; ///< Left camera angle of view.
160 float_le distanceToChart; ///< Distance between cameras and measurement chart. 154 float_le distanceToChart; ///< Distance between cameras and measurement chart.
@@ -163,7 +157,8 @@ struct StereoCameraCalibrationData {
163 s16_le imageHeight; ///< Image height. 157 s16_le imageHeight; ///< Image height.
164 INSERT_PADDING_BYTES(16); 158 INSERT_PADDING_BYTES(16);
165}; 159};
166static_assert(sizeof(StereoCameraCalibrationData) == 64, "StereoCameraCalibrationData structure size is wrong"); 160static_assert(sizeof(StereoCameraCalibrationData) == 64,
161 "StereoCameraCalibrationData structure size is wrong");
167 162
168struct PackageParameterCameraSelect { 163struct PackageParameterCameraSelect {
169 CameraSelect camera; 164 CameraSelect camera;
@@ -188,7 +183,8 @@ struct PackageParameterCameraSelect {
188 s16 auto_white_balance_window_height; 183 s16 auto_white_balance_window_height;
189}; 184};
190 185
191static_assert(sizeof(PackageParameterCameraSelect) == 28, "PackageParameterCameraSelect structure size is wrong"); 186static_assert(sizeof(PackageParameterCameraSelect) == 28,
187 "PackageParameterCameraSelect structure size is wrong");
192 188
193/** 189/**
194 * Unknown 190 * Unknown
diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp
index 8fa7abc85..93b047c1a 100644
--- a/src/core/hle/service/cam/cam_c.cpp
+++ b/src/core/hle/service/cam/cam_c.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace CAM { 8namespace CAM {
9 9
10// Empty arrays are illegal -- commented out until an entry is added. 10// Empty arrays are illegal -- commented out until an entry is added.
11//const Interface::FunctionInfo FunctionTable[] = { }; 11// const Interface::FunctionInfo FunctionTable[] = { };
12 12
13CAM_C_Interface::CAM_C_Interface() { 13CAM_C_Interface::CAM_C_Interface() {
14 //Register(FunctionTable); 14 // Register(FunctionTable);
15} 15}
16 16
17} // namespace CAM 17} // namespace CAM
diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp
index d3ba91e9d..2ba853606 100644
--- a/src/core/hle/service/cam/cam_q.cpp
+++ b/src/core/hle/service/cam/cam_q.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace CAM { 8namespace CAM {
9 9
10// Empty arrays are illegal -- commented out until an entry is added. 10// Empty arrays are illegal -- commented out until an entry is added.
11//const Interface::FunctionInfo FunctionTable[] = { }; 11// const Interface::FunctionInfo FunctionTable[] = { };
12 12
13CAM_Q_Interface::CAM_Q_Interface() { 13CAM_Q_Interface::CAM_Q_Interface() {
14 //Register(FunctionTable); 14 // Register(FunctionTable);
15} 15}
16 16
17} // namespace CAM 17} // namespace CAM
diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp
index 2a13984d8..f1c6da587 100644
--- a/src/core/hle/service/cam/cam_s.cpp
+++ b/src/core/hle/service/cam/cam_s.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace CAM { 8namespace CAM {
9 9
10// Empty arrays are illegal -- commented out until an entry is added. 10// Empty arrays are illegal -- commented out until an entry is added.
11//const Interface::FunctionInfo FunctionTable[] = { }; 11// const Interface::FunctionInfo FunctionTable[] = { };
12 12
13CAM_S_Interface::CAM_S_Interface() { 13CAM_S_Interface::CAM_S_Interface() {
14 //Register(FunctionTable); 14 // Register(FunctionTable);
15} 15}
16 16
17} // namespace CAM 17} // namespace CAM
diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp
index a1070ebb2..af2123e5b 100644
--- a/src/core/hle/service/cam/cam_u.cpp
+++ b/src/core/hle/service/cam/cam_u.cpp
@@ -9,68 +9,68 @@ namespace Service {
9namespace CAM { 9namespace CAM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010040, StartCapture, "StartCapture"}, 12 {0x00010040, StartCapture, "StartCapture"},
13 {0x00020040, StopCapture, "StopCapture"}, 13 {0x00020040, StopCapture, "StopCapture"},
14 {0x00030040, nullptr, "IsBusy"}, 14 {0x00030040, nullptr, "IsBusy"},
15 {0x00040040, nullptr, "ClearBuffer"}, 15 {0x00040040, nullptr, "ClearBuffer"},
16 {0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"}, 16 {0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"},
17 {0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"}, 17 {0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"},
18 {0x00070102, SetReceiving, "SetReceiving"}, 18 {0x00070102, SetReceiving, "SetReceiving"},
19 {0x00080040, nullptr, "IsFinishedReceiving"}, 19 {0x00080040, nullptr, "IsFinishedReceiving"},
20 {0x00090100, SetTransferLines, "SetTransferLines"}, 20 {0x00090100, SetTransferLines, "SetTransferLines"},
21 {0x000A0080, GetMaxLines, "GetMaxLines"}, 21 {0x000A0080, GetMaxLines, "GetMaxLines"},
22 {0x000B0100, nullptr, "SetTransferBytes"}, 22 {0x000B0100, nullptr, "SetTransferBytes"},
23 {0x000C0040, GetTransferBytes, "GetTransferBytes"}, 23 {0x000C0040, GetTransferBytes, "GetTransferBytes"},
24 {0x000D0080, nullptr, "GetMaxBytes"}, 24 {0x000D0080, nullptr, "GetMaxBytes"},
25 {0x000E0080, SetTrimming, "SetTrimming"}, 25 {0x000E0080, SetTrimming, "SetTrimming"},
26 {0x000F0040, nullptr, "IsTrimming"}, 26 {0x000F0040, nullptr, "IsTrimming"},
27 {0x00100140, nullptr, "SetTrimmingParams"}, 27 {0x00100140, nullptr, "SetTrimmingParams"},
28 {0x00110040, nullptr, "GetTrimmingParams"}, 28 {0x00110040, nullptr, "GetTrimmingParams"},
29 {0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"}, 29 {0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"},
30 {0x00130040, Activate, "Activate"}, 30 {0x00130040, Activate, "Activate"},
31 {0x00140080, nullptr, "SwitchContext"}, 31 {0x00140080, nullptr, "SwitchContext"},
32 {0x00150080, nullptr, "SetExposure"}, 32 {0x00150080, nullptr, "SetExposure"},
33 {0x00160080, nullptr, "SetWhiteBalance"}, 33 {0x00160080, nullptr, "SetWhiteBalance"},
34 {0x00170080, nullptr, "SetWhiteBalanceWithoutBaseUp"}, 34 {0x00170080, nullptr, "SetWhiteBalanceWithoutBaseUp"},
35 {0x00180080, nullptr, "SetSharpness"}, 35 {0x00180080, nullptr, "SetSharpness"},
36 {0x00190080, nullptr, "SetAutoExposure"}, 36 {0x00190080, nullptr, "SetAutoExposure"},
37 {0x001A0040, nullptr, "IsAutoExposure"}, 37 {0x001A0040, nullptr, "IsAutoExposure"},
38 {0x001B0080, nullptr, "SetAutoWhiteBalance"}, 38 {0x001B0080, nullptr, "SetAutoWhiteBalance"},
39 {0x001C0040, nullptr, "IsAutoWhiteBalance"}, 39 {0x001C0040, nullptr, "IsAutoWhiteBalance"},
40 {0x001D00C0, FlipImage, "FlipImage"}, 40 {0x001D00C0, FlipImage, "FlipImage"},
41 {0x001E0200, nullptr, "SetDetailSize"}, 41 {0x001E0200, nullptr, "SetDetailSize"},
42 {0x001F00C0, SetSize, "SetSize"}, 42 {0x001F00C0, SetSize, "SetSize"},
43 {0x00200080, SetFrameRate, "SetFrameRate"}, 43 {0x00200080, SetFrameRate, "SetFrameRate"},
44 {0x00210080, nullptr, "SetPhotoMode"}, 44 {0x00210080, nullptr, "SetPhotoMode"},
45 {0x002200C0, nullptr, "SetEffect"}, 45 {0x002200C0, nullptr, "SetEffect"},
46 {0x00230080, nullptr, "SetContrast"}, 46 {0x00230080, nullptr, "SetContrast"},
47 {0x00240080, nullptr, "SetLensCorrection"}, 47 {0x00240080, nullptr, "SetLensCorrection"},
48 {0x002500C0, nullptr, "SetOutputFormat"}, 48 {0x002500C0, nullptr, "SetOutputFormat"},
49 {0x00260140, nullptr, "SetAutoExposureWindow"}, 49 {0x00260140, nullptr, "SetAutoExposureWindow"},
50 {0x00270140, nullptr, "SetAutoWhiteBalanceWindow"}, 50 {0x00270140, nullptr, "SetAutoWhiteBalanceWindow"},
51 {0x00280080, nullptr, "SetNoiseFilter"}, 51 {0x00280080, nullptr, "SetNoiseFilter"},
52 {0x00290080, nullptr, "SynchronizeVsyncTiming"}, 52 {0x00290080, nullptr, "SynchronizeVsyncTiming"},
53 {0x002A0080, nullptr, "GetLatestVsyncTiming"}, 53 {0x002A0080, nullptr, "GetLatestVsyncTiming"},
54 {0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"}, 54 {0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"},
55 {0x002C0400, nullptr, "SetStereoCameraCalibrationData"}, 55 {0x002C0400, nullptr, "SetStereoCameraCalibrationData"},
56 {0x002D00C0, nullptr, "WriteRegisterI2c"}, 56 {0x002D00C0, nullptr, "WriteRegisterI2c"},
57 {0x002E00C0, nullptr, "WriteMcuVariableI2c"}, 57 {0x002E00C0, nullptr, "WriteMcuVariableI2c"},
58 {0x002F0080, nullptr, "ReadRegisterI2cExclusive"}, 58 {0x002F0080, nullptr, "ReadRegisterI2cExclusive"},
59 {0x00300080, nullptr, "ReadMcuVariableI2cExclusive"}, 59 {0x00300080, nullptr, "ReadMcuVariableI2cExclusive"},
60 {0x00310180, nullptr, "SetImageQualityCalibrationData"}, 60 {0x00310180, nullptr, "SetImageQualityCalibrationData"},
61 {0x00320000, nullptr, "GetImageQualityCalibrationData"}, 61 {0x00320000, nullptr, "GetImageQualityCalibrationData"},
62 {0x003302C0, nullptr, "SetPackageParameterWithoutContext"}, 62 {0x003302C0, nullptr, "SetPackageParameterWithoutContext"},
63 {0x00340140, nullptr, "SetPackageParameterWithContext"}, 63 {0x00340140, nullptr, "SetPackageParameterWithContext"},
64 {0x003501C0, nullptr, "SetPackageParameterWithContextDetail"}, 64 {0x003501C0, nullptr, "SetPackageParameterWithContextDetail"},
65 {0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"}, 65 {0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"},
66 {0x00370202, nullptr, "PlayShutterSoundWithWave"}, 66 {0x00370202, nullptr, "PlayShutterSoundWithWave"},
67 {0x00380040, PlayShutterSound, "PlayShutterSound"}, 67 {0x00380040, PlayShutterSound, "PlayShutterSound"},
68 {0x00390000, DriverInitialize, "DriverInitialize"}, 68 {0x00390000, DriverInitialize, "DriverInitialize"},
69 {0x003A0000, DriverFinalize, "DriverFinalize"}, 69 {0x003A0000, DriverFinalize, "DriverFinalize"},
70 {0x003B0000, nullptr, "GetActivatedCamera"}, 70 {0x003B0000, nullptr, "GetActivatedCamera"},
71 {0x003C0000, nullptr, "GetSleepCamera"}, 71 {0x003C0000, nullptr, "GetSleepCamera"},
72 {0x003D0040, nullptr, "SetSleepCamera"}, 72 {0x003D0040, nullptr, "SetSleepCamera"},
73 {0x003E0040, nullptr, "SetBrightnessSynchronization"}, 73 {0x003E0040, nullptr, "SetBrightnessSynchronization"},
74}; 74};
75 75
76CAM_U_Interface::CAM_U_Interface() { 76CAM_U_Interface::CAM_U_Interface() {
diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp
index 50c03495e..515b344e6 100644
--- a/src/core/hle/service/cecd/cecd.cpp
+++ b/src/core/hle/service/cecd/cecd.cpp
@@ -3,12 +3,11 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6
7#include "core/hle/kernel/event.h" 6#include "core/hle/kernel/event.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/cecd/cecd.h" 7#include "core/hle/service/cecd/cecd.h"
10#include "core/hle/service/cecd/cecd_s.h" 8#include "core/hle/service/cecd/cecd_s.h"
11#include "core/hle/service/cecd/cecd_u.h" 9#include "core/hle/service/cecd/cecd_u.h"
10#include "core/hle/service/service.h"
12 11
13namespace Service { 12namespace Service {
14namespace CECD { 13namespace CECD {
@@ -28,7 +27,7 @@ void GetCecStateAbbreviated(Service::Interface* self) {
28void GetCecInfoEventHandle(Service::Interface* self) { 27void GetCecInfoEventHandle(Service::Interface* self) {
29 u32* cmd_buff = Kernel::GetCommandBuffer(); 28 u32* cmd_buff = Kernel::GetCommandBuffer();
30 29
31 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 30 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
32 cmd_buff[3] = Kernel::g_handle_table.Create(cecinfo_event).MoveFrom(); // Event handle 31 cmd_buff[3] = Kernel::g_handle_table.Create(cecinfo_event).MoveFrom(); // Event handle
33 32
34 LOG_WARNING(Service_CECD, "(STUBBED) called"); 33 LOG_WARNING(Service_CECD, "(STUBBED) called");
@@ -37,7 +36,7 @@ void GetCecInfoEventHandle(Service::Interface* self) {
37void GetChangeStateEventHandle(Service::Interface* self) { 36void GetChangeStateEventHandle(Service::Interface* self) {
38 u32* cmd_buff = Kernel::GetCommandBuffer(); 37 u32* cmd_buff = Kernel::GetCommandBuffer();
39 38
40 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 39 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
41 cmd_buff[3] = Kernel::g_handle_table.Create(change_state_event).MoveFrom(); // Event handle 40 cmd_buff[3] = Kernel::g_handle_table.Create(change_state_event).MoveFrom(); // Event handle
42 41
43 LOG_WARNING(Service_CECD, "(STUBBED) called"); 42 LOG_WARNING(Service_CECD, "(STUBBED) called");
@@ -48,7 +47,8 @@ void Init() {
48 AddService(new CECD_U_Interface); 47 AddService(new CECD_U_Interface);
49 48
50 cecinfo_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::cecinfo_event"); 49 cecinfo_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::cecinfo_event");
51 change_state_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::change_state_event"); 50 change_state_event =
51 Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::change_state_event");
52} 52}
53 53
54void Shutdown() { 54void Shutdown() {
diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h
index 435611363..ea97f9266 100644
--- a/src/core/hle/service/cecd/cecd.h
+++ b/src/core/hle/service/cecd/cecd.h
@@ -11,11 +11,13 @@ class Interface;
11namespace CECD { 11namespace CECD {
12 12
13enum class CecStateAbbreviated { 13enum class CecStateAbbreviated {
14 CEC_STATE_ABBREV_IDLE = 1, ///< Corresponds to CEC_STATE_IDLE 14 CEC_STATE_ABBREV_IDLE = 1, ///< Corresponds to CEC_STATE_IDLE
15 CEC_STATE_ABBREV_NOT_LOCAL = 2, ///< Corresponds to CEC_STATEs *FINISH*, *POST, and OVER_BOSS 15 CEC_STATE_ABBREV_NOT_LOCAL = 2, ///< Corresponds to CEC_STATEs *FINISH*, *POST, and OVER_BOSS
16 CEC_STATE_ABBREV_SCANNING = 3, ///< Corresponds to CEC_STATE_SCANNING 16 CEC_STATE_ABBREV_SCANNING = 3, ///< Corresponds to CEC_STATE_SCANNING
17 CEC_STATE_ABBREV_WLREADY = 4, ///< Corresponds to CEC_STATE_WIRELESS_READY when some unknown bool is true 17 CEC_STATE_ABBREV_WLREADY =
18 CEC_STATE_ABBREV_OTHER = 5, ///< Corresponds to CEC_STATEs besides *FINISH*, *POST, and OVER_BOSS and those listed here 18 4, ///< Corresponds to CEC_STATE_WIRELESS_READY when some unknown bool is true
19 CEC_STATE_ABBREV_OTHER = 5, ///< Corresponds to CEC_STATEs besides *FINISH*, *POST, and
20 /// OVER_BOSS and those listed here
19}; 21};
20 22
21/** 23/**
diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp
index bfd821c07..7477b9320 100644
--- a/src/core/hle/service/cecd/cecd_s.cpp
+++ b/src/core/hle/service/cecd/cecd_s.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace CECD { 8namespace CECD {
9 9
10// Empty arrays are illegal -- commented out until an entry is added. 10// Empty arrays are illegal -- commented out until an entry is added.
11//const Interface::FunctionInfo FunctionTable[] = { }; 11// const Interface::FunctionInfo FunctionTable[] = { };
12 12
13CECD_S_Interface::CECD_S_Interface() { 13CECD_S_Interface::CECD_S_Interface() {
14 //Register(FunctionTable); 14 // Register(FunctionTable);
15} 15}
16 16
17} // namespace CECD 17} // namespace CECD
diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp
index be6d4d8f6..4b747de7b 100644
--- a/src/core/hle/service/cecd/cecd_u.cpp
+++ b/src/core/hle/service/cecd/cecd_u.cpp
@@ -9,10 +9,10 @@ namespace Service {
9namespace CECD { 9namespace CECD {
10 10
11static const Interface::FunctionInfo FunctionTable[] = { 11static const Interface::FunctionInfo FunctionTable[] = {
12 {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"}, 12 {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"},
13 {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"}, 13 {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"},
14 {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"}, 14 {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"},
15 {0x00120104, nullptr, "ReadSavedData"}, 15 {0x00120104, nullptr, "ReadSavedData"},
16}; 16};
17 17
18CECD_U_Interface::CECD_U_Interface() { 18CECD_U_Interface::CECD_U_Interface() {
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index a5dc47322..24eee6903 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -3,15 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6
7#include "common/file_util.h" 6#include "common/file_util.h"
8#include "common/logging/log.h" 7#include "common/logging/log.h"
9#include "common/string_util.h" 8#include "common/string_util.h"
10#include "common/swap.h" 9#include "common/swap.h"
11
12#include "core/file_sys/archive_systemsavedata.h" 10#include "core/file_sys/archive_systemsavedata.h"
13#include "core/file_sys/file_backend.h" 11#include "core/file_sys/file_backend.h"
14#include "core/settings.h"
15#include "core/hle/result.h" 12#include "core/hle/result.h"
16#include "core/hle/service/cfg/cfg.h" 13#include "core/hle/service/cfg/cfg.h"
17#include "core/hle/service/cfg/cfg_i.h" 14#include "core/hle/service/cfg/cfg_i.h"
@@ -19,6 +16,7 @@
19#include "core/hle/service/cfg/cfg_u.h" 16#include "core/hle/service/cfg/cfg_u.h"
20#include "core/hle/service/fs/archive.h" 17#include "core/hle/service/fs/archive.h"
21#include "core/hle/service/service.h" 18#include "core/hle/service/service.h"
19#include "core/settings.h"
22 20
23namespace Service { 21namespace Service {
24namespace CFG { 22namespace CFG {
@@ -33,25 +31,29 @@ namespace {
33 * contains information about the blocks in the file 31 * contains information about the blocks in the file
34 */ 32 */
35struct SaveFileConfig { 33struct SaveFileConfig {
36 u16 total_entries; ///< The total number of set entries in the config file 34 u16 total_entries; ///< The total number of set entries in the config file
37 u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware 35 u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded
38 SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware 36 /// to 0x455C as per hardware
39 u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware 37 SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the
38 /// maximum possible value is
39 /// 1479 as per hardware
40 u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware
40}; 41};
41static_assert(sizeof(SaveFileConfig) == 0x455C, "SaveFileConfig header must be exactly 0x455C bytes"); 42static_assert(sizeof(SaveFileConfig) == 0x455C,
43 "SaveFileConfig header must be exactly 0x455C bytes");
42 44
43enum ConfigBlockID { 45enum ConfigBlockID {
44 StereoCameraSettingsBlockID = 0x00050005, 46 StereoCameraSettingsBlockID = 0x00050005,
45 SoundOutputModeBlockID = 0x00070001, 47 SoundOutputModeBlockID = 0x00070001,
46 ConsoleUniqueIDBlockID = 0x00090001, 48 ConsoleUniqueIDBlockID = 0x00090001,
47 UsernameBlockID = 0x000A0000, 49 UsernameBlockID = 0x000A0000,
48 BirthdayBlockID = 0x000A0001, 50 BirthdayBlockID = 0x000A0001,
49 LanguageBlockID = 0x000A0002, 51 LanguageBlockID = 0x000A0002,
50 CountryInfoBlockID = 0x000B0000, 52 CountryInfoBlockID = 0x000B0000,
51 CountryNameBlockID = 0x000B0001, 53 CountryNameBlockID = 0x000B0001,
52 StateNameBlockID = 0x000B0002, 54 StateNameBlockID = 0x000B0002,
53 EULAVersionBlockID = 0x000D0000, 55 EULAVersionBlockID = 0x000D0000,
54 ConsoleModelBlockID = 0x000F0004, 56 ConsoleModelBlockID = 0x000F0004,
55}; 57};
56 58
57struct UsernameBlock { 59struct UsernameBlock {
@@ -68,8 +70,8 @@ struct BirthdayBlock {
68static_assert(sizeof(BirthdayBlock) == 2, "BirthdayBlock must be exactly 2 bytes"); 70static_assert(sizeof(BirthdayBlock) == 2, "BirthdayBlock must be exactly 2 bytes");
69 71
70struct ConsoleModelInfo { 72struct ConsoleModelInfo {
71 u8 model; ///< The console model (3DS, 2DS, etc) 73 u8 model; ///< The console model (3DS, 2DS, etc)
72 u8 unknown[3]; ///< Unknown data 74 u8 unknown[3]; ///< Unknown data
73}; 75};
74static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes"); 76static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes");
75 77
@@ -78,36 +80,38 @@ struct ConsoleCountryInfo {
78 u8 country_code; ///< The country code of the console 80 u8 country_code; ///< The country code of the console
79}; 81};
80static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); 82static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes");
81
82} 83}
83 84
84static const u64 CFG_SAVE_ID = 0x00010017; 85static const u64 CFG_SAVE_ID = 0x00010017;
85static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; 86static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE;
86static const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; 87static const ConsoleModelInfo CONSOLE_MODEL = {NINTENDO_3DS_XL, {0, 0, 0}};
87static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; 88static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN;
88static const UsernameBlock CONSOLE_USERNAME_BLOCK = { u"CITRA", 0, 0 }; 89static const UsernameBlock CONSOLE_USERNAME_BLOCK = {u"CITRA", 0, 0};
89static const BirthdayBlock PROFILE_BIRTHDAY = { 3, 25 }; // March 25th, 2014 90static const BirthdayBlock PROFILE_BIRTHDAY = {3, 25}; // March 25th, 2014
90static const u8 SOUND_OUTPUT_MODE = SOUND_SURROUND; 91static const u8 SOUND_OUTPUT_MODE = SOUND_SURROUND;
91static const u8 UNITED_STATES_COUNTRY_ID = 49; 92static const u8 UNITED_STATES_COUNTRY_ID = 49;
92/// TODO(Subv): Find what the other bytes are 93/// TODO(Subv): Find what the other bytes are
93static const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID }; 94static const ConsoleCountryInfo COUNTRY_INFO = {{0, 0, 0}, UNITED_STATES_COUNTRY_ID};
94 95
95/** 96/**
96 * TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games, 97 * TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games,
97 * for example Nintendo Zone 98 * for example Nintendo Zone
98 * Thanks Normmatt for providing this information 99 * Thanks Normmatt for providing this information
99 */ 100 */
100static const std::array<float, 8> STEREO_CAMERA_SETTINGS = {{ 101static const std::array<float, 8> STEREO_CAMERA_SETTINGS = {
101 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, 102 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f,
102 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f 103 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f,
103}}; 104};
104static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); 105static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20,
106 "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes");
105 107
106static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; 108static const u32 CONFIG_SAVEFILE_SIZE = 0x8000;
107static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; 109static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
108 110
109static Service::FS::ArchiveHandle cfg_system_save_data_archive; 111static Service::FS::ArchiveHandle cfg_system_save_data_archive;
110static const std::vector<u8> cfg_system_savedata_id = { 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00 }; 112static const std::vector<u8> cfg_system_savedata_id = {
113 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00,
114};
111 115
112void GetCountryCodeString(Service::Interface* self) { 116void GetCountryCodeString(Service::Interface* self) {
113 u32* cmd_buff = Kernel::GetCommandBuffer(); 117 u32* cmd_buff = Kernel::GetCommandBuffer();
@@ -115,7 +119,9 @@ void GetCountryCodeString(Service::Interface* self) {
115 119
116 if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { 120 if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) {
117 LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id); 121 LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id);
118 cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; 122 cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config,
123 ErrorSummary::WrongArgument, ErrorLevel::Permanent)
124 .raw;
119 return; 125 return;
120 } 126 }
121 127
@@ -139,8 +145,11 @@ void GetCountryCodeID(Service::Interface* self) {
139 } 145 }
140 146
141 if (0 == country_code_id) { 147 if (0 == country_code_id) {
142 LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, country_code >> 8); 148 LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff,
143 cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; 149 country_code >> 8);
150 cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config,
151 ErrorSummary::WrongArgument, ErrorLevel::Permanent)
152 .raw;
144 cmd_buff[2] = 0xFFFF; 153 cmd_buff[2] = 0xFFFF;
145 return; 154 return;
146 } 155 }
@@ -185,8 +194,8 @@ void GetSystemModel(Service::Interface* self) {
185 u32 data; 194 u32 data;
186 195
187 // TODO(Subv): Find out the correct error codes 196 // TODO(Subv): Find out the correct error codes
188 cmd_buff[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, 197 cmd_buff[1] =
189 reinterpret_cast<u8*>(&data)).raw; 198 Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, reinterpret_cast<u8*>(&data)).raw;
190 cmd_buff[2] = data & 0xFF; 199 cmd_buff[2] = data & 0xFF;
191} 200}
192 201
@@ -195,8 +204,8 @@ void GetModelNintendo2DS(Service::Interface* self) {
195 u32 data; 204 u32 data;
196 205
197 // TODO(Subv): Find out the correct error codes 206 // TODO(Subv): Find out the correct error codes
198 cmd_buff[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, 207 cmd_buff[1] =
199 reinterpret_cast<u8*>(&data)).raw; 208 Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, reinterpret_cast<u8*>(&data)).raw;
200 209
201 u8 model = data & 0xFF; 210 u8 model = data & 0xFF;
202 if (model == Service::CFG::NINTENDO_2DS) 211 if (model == Service::CFG::NINTENDO_2DS)
@@ -267,24 +276,29 @@ static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 fl
267 // Read the header 276 // Read the header
268 SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); 277 SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data());
269 278
270 auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), 279 auto itr =
271 [&](const SaveConfigBlockEntry& entry) { 280 std::find_if(std::begin(config->block_entries), std::end(config->block_entries),
272 return entry.block_id == block_id; 281 [&](const SaveConfigBlockEntry& entry) { return entry.block_id == block_id; });
273 });
274 282
275 if (itr == std::end(config->block_entries)) { 283 if (itr == std::end(config->block_entries)) {
276 LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found", block_id, flag, size); 284 LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found",
277 return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 285 block_id, flag, size);
286 return ResultCode(ErrorDescription::NotFound, ErrorModule::Config,
287 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
278 } 288 }
279 289
280 if ((itr->flags & flag) == 0) { 290 if ((itr->flags & flag) == 0) {
281 LOG_ERROR(Service_CFG, "Invalid flag %u for config block 0x%X with size %u", flag, block_id, size); 291 LOG_ERROR(Service_CFG, "Invalid flag %u for config block 0x%X with size %u", flag, block_id,
282 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 292 size);
293 return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config,
294 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
283 } 295 }
284 296
285 if (itr->size != size) { 297 if (itr->size != size) {
286 LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag); 298 LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size,
287 return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 299 block_id, flag);
300 return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config,
301 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
288 } 302 }
289 303
290 void* pointer; 304 void* pointer;
@@ -318,7 +332,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da
318 return ResultCode(-1); // TODO(Subv): Find the right error code 332 return ResultCode(-1); // TODO(Subv): Find the right error code
319 333
320 // Insert the block header with offset 0 for now 334 // Insert the block header with offset 0 for now
321 config->block_entries[config->total_entries] = { block_id, 0, size, flags }; 335 config->block_entries[config->total_entries] = {block_id, 0, size, flags};
322 if (size > 4) { 336 if (size > 4) {
323 u32 offset = config->data_entries_offset; 337 u32 offset = config->data_entries_offset;
324 // Perform a search to locate the next offset for the new data 338 // Perform a search to locate the next offset for the new data
@@ -326,8 +340,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da
326 for (int i = config->total_entries - 1; i >= 0; --i) { 340 for (int i = config->total_entries - 1; i >= 0; --i) {
327 // Ignore the blocks that don't have a separate data offset 341 // Ignore the blocks that don't have a separate data offset
328 if (config->block_entries[i].size > 4) { 342 if (config->block_entries[i].size > 4) {
329 offset = config->block_entries[i].offset_or_data + 343 offset = config->block_entries[i].offset_or_data + config->block_entries[i].size;
330 config->block_entries[i].size;
331 break; 344 break;
332 } 345 }
333 } 346 }
@@ -336,8 +349,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da
336 349
337 // Write the data at the new offset 350 // Write the data at the new offset
338 memcpy(&cfg_config_file_buffer[offset], data, size); 351 memcpy(&cfg_config_file_buffer[offset], data, size);
339 } 352 } else {
340 else {
341 // The offset_or_data field in the header contains the data itself if it's 4 bytes or less 353 // The offset_or_data field in the header contains the data itself if it's 4 bytes or less
342 memcpy(&config->block_entries[config->total_entries].offset_or_data, data, size); 354 memcpy(&config->block_entries[config->total_entries].offset_or_data, data, size);
343 } 355 }
@@ -384,28 +396,40 @@ ResultCode FormatConfig() {
384 396
385 // 0x00030001 - Unknown 397 // 0x00030001 - Unknown
386 res = CreateConfigInfoBlk(0x00030001, 0x8, 0xE, zero_buffer); 398 res = CreateConfigInfoBlk(0x00030001, 0x8, 0xE, zero_buffer);
387 if (!res.IsSuccess()) return res; 399 if (!res.IsSuccess())
400 return res;
388 401
389 res = CreateConfigInfoBlk(StereoCameraSettingsBlockID, sizeof(STEREO_CAMERA_SETTINGS), 0xE, STEREO_CAMERA_SETTINGS.data()); 402 res = CreateConfigInfoBlk(StereoCameraSettingsBlockID, sizeof(STEREO_CAMERA_SETTINGS), 0xE,
390 if (!res.IsSuccess()) return res; 403 STEREO_CAMERA_SETTINGS.data());
404 if (!res.IsSuccess())
405 return res;
391 406
392 res = CreateConfigInfoBlk(SoundOutputModeBlockID, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE); 407 res = CreateConfigInfoBlk(SoundOutputModeBlockID, sizeof(SOUND_OUTPUT_MODE), 0xE,
393 if (!res.IsSuccess()) return res; 408 &SOUND_OUTPUT_MODE);
409 if (!res.IsSuccess())
410 return res;
394 411
395 res = CreateConfigInfoBlk(ConsoleUniqueIDBlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE, &CONSOLE_UNIQUE_ID); 412 res = CreateConfigInfoBlk(ConsoleUniqueIDBlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE,
396 if (!res.IsSuccess()) return res; 413 &CONSOLE_UNIQUE_ID);
414 if (!res.IsSuccess())
415 return res;
397 416
398 res = CreateConfigInfoBlk(UsernameBlockID, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); 417 res = CreateConfigInfoBlk(UsernameBlockID, sizeof(CONSOLE_USERNAME_BLOCK), 0xE,
399 if (!res.IsSuccess()) return res; 418 &CONSOLE_USERNAME_BLOCK);
419 if (!res.IsSuccess())
420 return res;
400 421
401 res = CreateConfigInfoBlk(BirthdayBlockID, sizeof(PROFILE_BIRTHDAY), 0xE, &PROFILE_BIRTHDAY); 422 res = CreateConfigInfoBlk(BirthdayBlockID, sizeof(PROFILE_BIRTHDAY), 0xE, &PROFILE_BIRTHDAY);
402 if (!res.IsSuccess()) return res; 423 if (!res.IsSuccess())
424 return res;
403 425
404 res = CreateConfigInfoBlk(LanguageBlockID, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE); 426 res = CreateConfigInfoBlk(LanguageBlockID, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE);
405 if (!res.IsSuccess()) return res; 427 if (!res.IsSuccess())
428 return res;
406 429
407 res = CreateConfigInfoBlk(CountryInfoBlockID, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); 430 res = CreateConfigInfoBlk(CountryInfoBlockID, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO);
408 if (!res.IsSuccess()) return res; 431 if (!res.IsSuccess())
432 return res;
409 433
410 u16_le country_name_buffer[16][0x40] = {}; 434 u16_le country_name_buffer[16][0x40] = {};
411 std::u16string region_name = Common::UTF8ToUTF16("Gensokyo"); 435 std::u16string region_name = Common::UTF8ToUTF16("Gensokyo");
@@ -413,34 +437,44 @@ ResultCode FormatConfig() {
413 std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]); 437 std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]);
414 } 438 }
415 // 0x000B0001 - Localized names for the profile Country 439 // 0x000B0001 - Localized names for the profile Country
416 res = CreateConfigInfoBlk(CountryNameBlockID, sizeof(country_name_buffer), 0xE, country_name_buffer); 440 res = CreateConfigInfoBlk(CountryNameBlockID, sizeof(country_name_buffer), 0xE,
417 if (!res.IsSuccess()) return res; 441 country_name_buffer);
442 if (!res.IsSuccess())
443 return res;
418 // 0x000B0002 - Localized names for the profile State/Province 444 // 0x000B0002 - Localized names for the profile State/Province
419 res = CreateConfigInfoBlk(StateNameBlockID, sizeof(country_name_buffer), 0xE, country_name_buffer); 445 res = CreateConfigInfoBlk(StateNameBlockID, sizeof(country_name_buffer), 0xE,
420 if (!res.IsSuccess()) return res; 446 country_name_buffer);
447 if (!res.IsSuccess())
448 return res;
421 449
422 // 0x000B0003 - Unknown, related to country/address (zip code?) 450 // 0x000B0003 - Unknown, related to country/address (zip code?)
423 res = CreateConfigInfoBlk(0x000B0003, 0x4, 0xE, zero_buffer); 451 res = CreateConfigInfoBlk(0x000B0003, 0x4, 0xE, zero_buffer);
424 if (!res.IsSuccess()) return res; 452 if (!res.IsSuccess())
453 return res;
425 454
426 // 0x000C0000 - Unknown 455 // 0x000C0000 - Unknown
427 res = CreateConfigInfoBlk(0x000C0000, 0xC0, 0xE, zero_buffer); 456 res = CreateConfigInfoBlk(0x000C0000, 0xC0, 0xE, zero_buffer);
428 if (!res.IsSuccess()) return res; 457 if (!res.IsSuccess())
458 return res;
429 459
430 // 0x000C0001 - Unknown 460 // 0x000C0001 - Unknown
431 res = CreateConfigInfoBlk(0x000C0001, 0x14, 0xE, zero_buffer); 461 res = CreateConfigInfoBlk(0x000C0001, 0x14, 0xE, zero_buffer);
432 if (!res.IsSuccess()) return res; 462 if (!res.IsSuccess())
463 return res;
433 464
434 // 0x000D0000 - Accepted EULA version 465 // 0x000D0000 - Accepted EULA version
435 res = CreateConfigInfoBlk(EULAVersionBlockID, 0x4, 0xE, zero_buffer); 466 res = CreateConfigInfoBlk(EULAVersionBlockID, 0x4, 0xE, zero_buffer);
436 if (!res.IsSuccess()) return res; 467 if (!res.IsSuccess())
468 return res;
437 469
438 res = CreateConfigInfoBlk(ConsoleModelBlockID, sizeof(CONSOLE_MODEL), 0xC, &CONSOLE_MODEL); 470 res = CreateConfigInfoBlk(ConsoleModelBlockID, sizeof(CONSOLE_MODEL), 0xC, &CONSOLE_MODEL);
439 if (!res.IsSuccess()) return res; 471 if (!res.IsSuccess())
472 return res;
440 473
441 // 0x00170000 - Unknown 474 // 0x00170000 - Unknown
442 res = CreateConfigInfoBlk(0x00170000, 0x4, 0xE, zero_buffer); 475 res = CreateConfigInfoBlk(0x00170000, 0x4, 0xE, zero_buffer);
443 if (!res.IsSuccess()) return res; 476 if (!res.IsSuccess())
477 return res;
444 478
445 // Save the buffer to the file 479 // Save the buffer to the file
446 res = UpdateConfigNANDSavegame(); 480 res = UpdateConfigNANDSavegame();
@@ -452,15 +486,18 @@ ResultCode FormatConfig() {
452ResultCode LoadConfigNANDSaveFile() { 486ResultCode LoadConfigNANDSaveFile() {
453 // Open the SystemSaveData archive 0x00010017 487 // Open the SystemSaveData archive 0x00010017
454 FileSys::Path archive_path(cfg_system_savedata_id); 488 FileSys::Path archive_path(cfg_system_savedata_id);
455 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); 489 auto archive_result =
490 Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
456 491
457 // If the archive didn't exist, create the files inside 492 // If the archive didn't exist, create the files inside
458 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { 493 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
459 // Format the archive to create the directories 494 // Format the archive to create the directories
460 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData, FileSys::ArchiveFormatInfo(), archive_path); 495 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData,
496 FileSys::ArchiveFormatInfo(), archive_path);
461 497
462 // Open it again to get a valid archive now that the folder exists 498 // Open it again to get a valid archive now that the folder exists
463 archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); 499 archive_result =
500 Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
464 } 501 }
465 502
466 ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!"); 503 ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!");
@@ -491,8 +528,7 @@ void Init() {
491 LoadConfigNANDSaveFile(); 528 LoadConfigNANDSaveFile();
492} 529}
493 530
494void Shutdown() { 531void Shutdown() {}
495}
496 532
497void SetUsername(const std::u16string& name) { 533void SetUsername(const std::u16string& name) {
498 ASSERT(name.size() <= 10); 534 ASSERT(name.size() <= 10);
@@ -515,7 +551,7 @@ std::u16string GetUsername() {
515} 551}
516 552
517void SetBirthday(u8 month, u8 day) { 553void SetBirthday(u8 month, u8 day) {
518 BirthdayBlock block = { month, day }; 554 BirthdayBlock block = {month, day};
519 SetConfigInfoBlock(BirthdayBlockID, sizeof(block), 4, &block); 555 SetConfigInfoBlock(BirthdayBlockID, sizeof(block), 4, &block);
520} 556}
521 557
diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h
index 18f60f4ca..fb47c2aa5 100644
--- a/src/core/hle/service/cfg/cfg.h
+++ b/src/core/hle/service/cfg/cfg.h
@@ -6,7 +6,6 @@
6 6
7#include <array> 7#include <array>
8#include <string> 8#include <string>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11 10
12union ResultCode; 11union ResultCode;
@@ -40,16 +39,13 @@ enum SystemLanguage {
40 LANGUAGE_TW = 11 39 LANGUAGE_TW = 11
41}; 40};
42 41
43enum SoundOutputMode { 42enum SoundOutputMode { SOUND_MONO = 0, SOUND_STEREO = 1, SOUND_SURROUND = 2 };
44 SOUND_MONO = 0,
45 SOUND_STEREO = 1,
46 SOUND_SURROUND = 2
47};
48 43
49/// Block header in the config savedata file 44/// Block header in the config savedata file
50struct SaveConfigBlockEntry { 45struct SaveConfigBlockEntry {
51 u32 block_id; ///< The id of the current block 46 u32 block_id; ///< The id of the current block
52 u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater than 4 bytes, otherwise it contains the data itself 47 u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater
48 /// than 4 bytes, otherwise it contains the data itself
53 u16 size; ///< The size of the block 49 u16 size; ///< The size of the block
54 u16 flags; ///< The flags of the block, possibly used for access control 50 u16 flags; ///< The flags of the block, possibly used for access control
55}; 51};
@@ -82,7 +78,7 @@ static const std::array<u16, 187> country_codes = {{
82 C("CN"), 0, 0, 0, 0, 0, 0, 0, // 160-167 78 C("CN"), 0, 0, 0, 0, 0, 0, 0, // 160-167
83 C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175 79 C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175
84 C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183 80 C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183
85 C("SM"), C("VA"), C("BM") // 184-186 81 C("SM"), C("VA"), C("BM"), // 184-186
86}}; 82}};
87 83
88/** 84/**
@@ -221,8 +217,9 @@ void FormatConfig(Service::Interface* self);
221 217
222/** 218/**
223 * Reads a block with the specified id and flag from the Config savegame buffer 219 * Reads a block with the specified id and flag from the Config savegame buffer
224 * and writes the output to output. 220 * and writes the output to output. The input size must match exactly the size of the requested
225 * The input size must match exactly the size of the requested block 221 * block.
222 *
226 * @param block_id The id of the block we want to read 223 * @param block_id The id of the block we want to read
227 * @param size The size of the block we want to read 224 * @param size The size of the block we want to read
228 * @param flag The requested block must have this flag set 225 * @param flag The requested block must have this flag set
@@ -233,8 +230,8 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output);
233 230
234/** 231/**
235 * Reads data from input and writes to a block with the specified id and flag 232 * Reads data from input and writes to a block with the specified id and flag
236 * in the Config savegame buffer. 233 * in the Config savegame buffer. The input size must match exactly the size of the target block.
237 * The input size must match exactly the size of the target block 234 *
238 * @param block_id The id of the block we want to write 235 * @param block_id The id of the block we want to write
239 * @param size The size of the block we want to write 236 * @param size The size of the block we want to write
240 * @param flag The target block must have this flag set 237 * @param flag The target block must have this flag set
@@ -244,8 +241,9 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output);
244ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input); 241ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input);
245 242
246/** 243/**
247 * Creates a block with the specified id and writes the input data to the cfg savegame buffer in memory. 244 * Creates a block with the specified id and writes the input data to the cfg savegame buffer in
248 * The config savegame file in the filesystem is not updated. 245 * memory. The config savegame file in the filesystem is not updated.
246 *
249 * @param block_id The id of the block we want to create 247 * @param block_id The id of the block we want to create
250 * @param size The size of the block we want to create 248 * @param size The size of the block we want to create
251 * @param flags The flags of the new block 249 * @param flags The flags of the new block
diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp
index 8b0db785f..2ff52c8b8 100644
--- a/src/core/hle/service/cfg/cfg_i.cpp
+++ b/src/core/hle/service/cfg/cfg_i.cpp
@@ -10,49 +10,49 @@ namespace CFG {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 // cfg common 12 // cfg common
13 {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, 13 {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"},
14 {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, 14 {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"},
15 {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, 15 {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"},
16 {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, 16 {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"},
17 {0x00050000, GetSystemModel, "GetSystemModel"}, 17 {0x00050000, GetSystemModel, "GetSystemModel"},
18 {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, 18 {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"},
19 {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, 19 {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"},
20 {0x00080080, nullptr, "GoThroughTable"}, 20 {0x00080080, nullptr, "GoThroughTable"},
21 {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, 21 {0x00090040, GetCountryCodeString, "GetCountryCodeString"},
22 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, 22 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
23 // cfg:i 23 // cfg:i
24 {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, 24 {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
25 {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, 25 {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"},
26 {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, 26 {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
27 {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, 27 {0x04040042, nullptr, "GetLocalFriendCodeSeedData"},
28 {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, 28 {0x04050000, nullptr, "GetLocalFriendCodeSeed"},
29 {0x04060000, SecureInfoGetRegion, "SecureInfoGetRegion"}, 29 {0x04060000, SecureInfoGetRegion, "SecureInfoGetRegion"},
30 {0x04070000, nullptr, "SecureInfoGetByte101"}, 30 {0x04070000, nullptr, "SecureInfoGetByte101"},
31 {0x04080042, nullptr, "SecureInfoGetSerialNo"}, 31 {0x04080042, nullptr, "SecureInfoGetSerialNo"},
32 {0x04090000, nullptr, "UpdateConfigBlk00040003"}, 32 {0x04090000, nullptr, "UpdateConfigBlk00040003"},
33 {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, 33 {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
34 {0x08020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, 34 {0x08020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"},
35 {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, 35 {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
36 {0x080400C2, nullptr, "CreateConfigInfoBlk"}, 36 {0x080400C2, nullptr, "CreateConfigInfoBlk"},
37 {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, 37 {0x08050000, nullptr, "DeleteConfigNANDSavefile"},
38 {0x08060000, FormatConfig, "FormatConfig"}, 38 {0x08060000, FormatConfig, "FormatConfig"},
39 {0x08080000, nullptr, "UpdateConfigBlk1"}, 39 {0x08080000, nullptr, "UpdateConfigBlk1"},
40 {0x08090000, nullptr, "UpdateConfigBlk2"}, 40 {0x08090000, nullptr, "UpdateConfigBlk2"},
41 {0x080A0000, nullptr, "UpdateConfigBlk3"}, 41 {0x080A0000, nullptr, "UpdateConfigBlk3"},
42 {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"}, 42 {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"},
43 {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"}, 43 {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"},
44 {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"}, 44 {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"},
45 {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"}, 45 {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"},
46 {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"}, 46 {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"},
47 {0x08100000, nullptr, "GetLocalFriendCodeSeed"}, 47 {0x08100000, nullptr, "GetLocalFriendCodeSeed"},
48 {0x08110084, nullptr, "SetSecureInfo"}, 48 {0x08110084, nullptr, "SetSecureInfo"},
49 {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"}, 49 {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"},
50 {0x08130000, nullptr, "VerifySigSecureInfo"}, 50 {0x08130000, nullptr, "VerifySigSecureInfo"},
51 {0x08140042, nullptr, "SecureInfoGetData"}, 51 {0x08140042, nullptr, "SecureInfoGetData"},
52 {0x08150042, nullptr, "SecureInfoGetSignature"}, 52 {0x08150042, nullptr, "SecureInfoGetSignature"},
53 {0x08160000, SecureInfoGetRegion, "SecureInfoGetRegion"}, 53 {0x08160000, SecureInfoGetRegion, "SecureInfoGetRegion"},
54 {0x08170000, nullptr, "SecureInfoGetByte101"}, 54 {0x08170000, nullptr, "SecureInfoGetByte101"},
55 {0x08180042, nullptr, "SecureInfoGetSerialNo"}, 55 {0x08180042, nullptr, "SecureInfoGetSerialNo"},
56}; 56};
57 57
58CFG_I_Interface::CFG_I_Interface() { 58CFG_I_Interface::CFG_I_Interface() {
diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp
index 12b458783..eed26dec7 100644
--- a/src/core/hle/service/cfg/cfg_s.cpp
+++ b/src/core/hle/service/cfg/cfg_s.cpp
@@ -10,26 +10,26 @@ namespace CFG {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 // cfg common 12 // cfg common
13 {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, 13 {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"},
14 {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, 14 {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"},
15 {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, 15 {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"},
16 {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, 16 {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"},
17 {0x00050000, GetSystemModel, "GetSystemModel"}, 17 {0x00050000, GetSystemModel, "GetSystemModel"},
18 {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, 18 {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"},
19 {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, 19 {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"},
20 {0x00080080, nullptr, "GoThroughTable"}, 20 {0x00080080, nullptr, "GoThroughTable"},
21 {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, 21 {0x00090040, GetCountryCodeString, "GetCountryCodeString"},
22 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, 22 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
23 // cfg:s 23 // cfg:s
24 {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, 24 {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
25 {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, 25 {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"},
26 {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, 26 {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
27 {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, 27 {0x04040042, nullptr, "GetLocalFriendCodeSeedData"},
28 {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, 28 {0x04050000, nullptr, "GetLocalFriendCodeSeed"},
29 {0x04060000, nullptr, "SecureInfoGetRegion"}, 29 {0x04060000, nullptr, "SecureInfoGetRegion"},
30 {0x04070000, nullptr, "SecureInfoGetByte101"}, 30 {0x04070000, nullptr, "SecureInfoGetByte101"},
31 {0x04080042, nullptr, "SecureInfoGetSerialNo"}, 31 {0x04080042, nullptr, "SecureInfoGetSerialNo"},
32 {0x04090000, nullptr, "UpdateConfigBlk00040003"}, 32 {0x04090000, nullptr, "UpdateConfigBlk00040003"},
33}; 33};
34 34
35CFG_S_Interface::CFG_S_Interface() { 35CFG_S_Interface::CFG_S_Interface() {
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp
index 606f7b2eb..f28217134 100644
--- a/src/core/hle/service/cfg/cfg_u.cpp
+++ b/src/core/hle/service/cfg/cfg_u.cpp
@@ -10,16 +10,16 @@ namespace CFG {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 // cfg common 12 // cfg common
13 {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, 13 {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"},
14 {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, 14 {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"},
15 {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, 15 {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"},
16 {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, 16 {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"},
17 {0x00050000, GetSystemModel, "GetSystemModel"}, 17 {0x00050000, GetSystemModel, "GetSystemModel"},
18 {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, 18 {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"},
19 {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, 19 {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"},
20 {0x00080080, nullptr, "GoThroughTable"}, 20 {0x00080080, nullptr, "GoThroughTable"},
21 {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, 21 {0x00090040, GetCountryCodeString, "GetCountryCodeString"},
22 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, 22 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
23}; 23};
24 24
25CFG_U_Interface::CFG_U_Interface() { 25CFG_U_Interface::CFG_U_Interface() {
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp
index 913c8dc09..20c759ad7 100644
--- a/src/core/hle/service/csnd_snd.cpp
+++ b/src/core/hle/service/csnd_snd.cpp
@@ -15,18 +15,18 @@
15namespace CSND_SND { 15namespace CSND_SND {
16 16
17const Interface::FunctionInfo FunctionTable[] = { 17const Interface::FunctionInfo FunctionTable[] = {
18 {0x00010140, Initialize, "Initialize"}, 18 {0x00010140, Initialize, "Initialize"},
19 {0x00020000, Shutdown, "Shutdown"}, 19 {0x00020000, Shutdown, "Shutdown"},
20 {0x00030040, ExecuteType0Commands, "ExecuteType0Commands"}, 20 {0x00030040, ExecuteType0Commands, "ExecuteType0Commands"},
21 {0x00040080, nullptr, "ExecuteType1Commands"}, 21 {0x00040080, nullptr, "ExecuteType1Commands"},
22 {0x00050000, AcquireSoundChannels, "AcquireSoundChannels"}, 22 {0x00050000, AcquireSoundChannels, "AcquireSoundChannels"},
23 {0x00060000, nullptr, "ReleaseSoundChannels"}, 23 {0x00060000, nullptr, "ReleaseSoundChannels"},
24 {0x00070000, nullptr, "AcquireCaptureDevice"}, 24 {0x00070000, nullptr, "AcquireCaptureDevice"},
25 {0x00080040, nullptr, "ReleaseCaptureDevice"}, 25 {0x00080040, nullptr, "ReleaseCaptureDevice"},
26 {0x00090082, nullptr, "FlushDataCache"}, 26 {0x00090082, nullptr, "FlushDataCache"},
27 {0x000A0082, nullptr, "StoreDataCache"}, 27 {0x000A0082, nullptr, "StoreDataCache"},
28 {0x000B0082, nullptr, "InvalidateDataCache"}, 28 {0x000B0082, nullptr, "InvalidateDataCache"},
29 {0x000C0000, nullptr, "Reset"}, 29 {0x000C0000, nullptr, "Reset"},
30}; 30};
31 31
32//////////////////////////////////////////////////////////////////////////////////////////////////// 32////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -44,9 +44,9 @@ void Initialize(Service::Interface* self) {
44 44
45 u32 size = Common::AlignUp(cmd_buff[1], Memory::PAGE_SIZE); 45 u32 size = Common::AlignUp(cmd_buff[1], Memory::PAGE_SIZE);
46 using Kernel::MemoryPermission; 46 using Kernel::MemoryPermission;
47 shared_memory = Kernel::SharedMemory::Create(nullptr, size, 47 shared_memory = Kernel::SharedMemory::Create(nullptr, size, MemoryPermission::ReadWrite,
48 MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 48 MemoryPermission::ReadWrite, 0,
49 0, Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); 49 Kernel::MemoryRegion::BASE, "CSND:SharedMemory");
50 50
51 mutex = Kernel::Mutex::Create(false); 51 mutex = Kernel::Mutex::Create(false);
52 52
@@ -58,7 +58,7 @@ void Initialize(Service::Interface* self) {
58 58
59void ExecuteType0Commands(Service::Interface* self) { 59void ExecuteType0Commands(Service::Interface* self) {
60 u32* const cmd_buff = Kernel::GetCommandBuffer(); 60 u32* const cmd_buff = Kernel::GetCommandBuffer();
61 u8* const ptr = shared_memory->GetPointer(cmd_buff[1]); 61 u8* const ptr = shared_memory->GetPointer(cmd_buff[1]);
62 62
63 if (shared_memory != nullptr && ptr != nullptr) { 63 if (shared_memory != nullptr && ptr != nullptr) {
64 Type0Command command; 64 Type0Command command;
diff --git a/src/core/hle/service/csnd_snd.h b/src/core/hle/service/csnd_snd.h
index e861f3327..a146d116b 100644
--- a/src/core/hle/service/csnd_snd.h
+++ b/src/core/hle/service/csnd_snd.h
@@ -25,7 +25,7 @@ struct Type0Command {
25 u32 command_id; 25 u32 command_id;
26 u32 finished; 26 u32 finished;
27 u32 flags; 27 u32 flags;
28 u8 parameters[20]; 28 u8 parameters[20];
29}; 29};
30 30
31void Initialize(Service::Interface* self); 31void Initialize(Service::Interface* self);
diff --git a/src/core/hle/service/dlp/dlp.cpp b/src/core/hle/service/dlp/dlp.cpp
index 7c8db794b..8f4b67a5d 100644
--- a/src/core/hle/service/dlp/dlp.cpp
+++ b/src/core/hle/service/dlp/dlp.cpp
@@ -2,11 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/service.h"
6#include "core/hle/service/dlp/dlp.h" 5#include "core/hle/service/dlp/dlp.h"
7#include "core/hle/service/dlp/dlp_clnt.h" 6#include "core/hle/service/dlp/dlp_clnt.h"
8#include "core/hle/service/dlp/dlp_fkcl.h" 7#include "core/hle/service/dlp/dlp_fkcl.h"
9#include "core/hle/service/dlp/dlp_srvr.h" 8#include "core/hle/service/dlp/dlp_srvr.h"
9#include "core/hle/service/service.h"
10 10
11namespace Service { 11namespace Service {
12namespace DLP { 12namespace DLP {
@@ -17,8 +17,7 @@ void Init() {
17 AddService(new DLP_SRVR_Interface); 17 AddService(new DLP_SRVR_Interface);
18} 18}
19 19
20void Shutdown() { 20void Shutdown() {}
21}
22 21
23} // namespace DLP 22} // namespace DLP
24} // namespace Service 23} // namespace Service
diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp
index 0b31d47df..56f934b3f 100644
--- a/src/core/hle/service/dlp/dlp_clnt.cpp
+++ b/src/core/hle/service/dlp/dlp_clnt.cpp
@@ -8,8 +8,7 @@ namespace Service {
8namespace DLP { 8namespace DLP {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x000100C3, nullptr, "Initialize"}, 11 {0x000100C3, nullptr, "Initialize"}, {0x00110000, nullptr, "GetWirelessRebootPassphrase"},
12 {0x00110000, nullptr, "GetWirelessRebootPassphrase"},
13}; 12};
14 13
15DLP_CLNT_Interface::DLP_CLNT_Interface() { 14DLP_CLNT_Interface::DLP_CLNT_Interface() {
diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp
index a845260e5..29b9d52e0 100644
--- a/src/core/hle/service/dlp/dlp_fkcl.cpp
+++ b/src/core/hle/service/dlp/dlp_fkcl.cpp
@@ -8,8 +8,7 @@ namespace Service {
8namespace DLP { 8namespace DLP {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x00010083, nullptr, "Initialize"}, 11 {0x00010083, nullptr, "Initialize"}, {0x000F0000, nullptr, "GetWirelessRebootPassphrase"},
12 {0x000F0000, nullptr, "GetWirelessRebootPassphrase"},
13}; 12};
14 13
15DLP_FKCL_Interface::DLP_FKCL_Interface() { 14DLP_FKCL_Interface::DLP_FKCL_Interface() {
diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp
index da9b30f56..49d5b8d1c 100644
--- a/src/core/hle/service/dlp/dlp_srvr.cpp
+++ b/src/core/hle/service/dlp/dlp_srvr.cpp
@@ -20,10 +20,10 @@ static void unk_0x000E0040(Interface* self) {
20} 20}
21 21
22const Interface::FunctionInfo FunctionTable[] = { 22const Interface::FunctionInfo FunctionTable[] = {
23 {0x00010183, nullptr, "Initialize"}, 23 {0x00010183, nullptr, "Initialize"},
24 {0x00020000, nullptr, "Finalize"}, 24 {0x00020000, nullptr, "Finalize"},
25 {0x000800C0, nullptr, "SendWirelessRebootPassphrase"}, 25 {0x000800C0, nullptr, "SendWirelessRebootPassphrase"},
26 {0x000E0040, unk_0x000E0040, "unk_0x000E0040"}, 26 {0x000E0040, unk_0x000E0040, "unk_0x000E0040"},
27}; 27};
28 28
29DLP_SRVR_Interface::DLP_SRVR_Interface() { 29DLP_SRVR_Interface::DLP_SRVR_Interface() {
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index c8aadd9db..a15aa3696 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -4,12 +4,9 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <cinttypes> 6#include <cinttypes>
7
8#include "audio_core/hle/pipe.h" 7#include "audio_core/hle/pipe.h"
9
10#include "common/hash.h" 8#include "common/hash.h"
11#include "common/logging/log.h" 9#include "common/logging/log.h"
12
13#include "core/hle/kernel/event.h" 10#include "core/hle/kernel/event.h"
14#include "core/hle/service/dsp_dsp.h" 11#include "core/hle/service/dsp_dsp.h"
15 12
@@ -23,9 +20,7 @@ namespace DSP_DSP {
23static Kernel::SharedPtr<Kernel::Event> semaphore_event; 20static Kernel::SharedPtr<Kernel::Event> semaphore_event;
24 21
25/// There are three types of interrupts 22/// There are three types of interrupts
26enum class InterruptType { 23enum class InterruptType { Zero, One, Pipe };
27 Zero, One, Pipe
28};
29constexpr size_t NUM_INTERRUPT_TYPE = 3; 24constexpr size_t NUM_INTERRUPT_TYPE = 3;
30 25
31class InterruptEvents final { 26class InterruptEvents final {
@@ -57,9 +52,8 @@ public:
57 // Actual service implementation only has 6 'slots' for interrupts. 52 // Actual service implementation only has 6 'slots' for interrupts.
58 constexpr size_t max_number_of_interrupt_events = 6; 53 constexpr size_t max_number_of_interrupt_events = 6;
59 54
60 size_t number = std::count_if(pipe.begin(), pipe.end(), [](const auto& evt) { 55 size_t number =
61 return evt != nullptr; 56 std::count_if(pipe.begin(), pipe.end(), [](const auto& evt) { return evt != nullptr; });
62 });
63 57
64 if (zero != nullptr) 58 if (zero != nullptr)
65 number++; 59 number++;
@@ -105,7 +99,8 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
105 cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0); 99 cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0);
106 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 100 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
107 101
108 // TODO(merry): There is a per-region offset missing in this calculation (that seems to be always zero). 102 // TODO(merry): There is a per-region offset missing in this calculation (that seems to be
103 // always zero).
109 cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); 104 cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000);
110 105
111 LOG_DEBUG(Service_DSP, "addr=0x%08X", addr); 106 LOG_DEBUG(Service_DSP, "addr=0x%08X", addr);
@@ -126,15 +121,15 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) {
126static void LoadComponent(Service::Interface* self) { 121static void LoadComponent(Service::Interface* self) {
127 u32* cmd_buff = Kernel::GetCommandBuffer(); 122 u32* cmd_buff = Kernel::GetCommandBuffer();
128 123
129 u32 size = cmd_buff[1]; 124 u32 size = cmd_buff[1];
130 u32 prog_mask = cmd_buff[2]; 125 u32 prog_mask = cmd_buff[2];
131 u32 data_mask = cmd_buff[3]; 126 u32 data_mask = cmd_buff[3];
132 u32 desc = cmd_buff[4]; 127 u32 desc = cmd_buff[4];
133 u32 buffer = cmd_buff[5]; 128 u32 buffer = cmd_buff[5];
134 129
135 cmd_buff[0] = IPC::MakeHeader(0x11, 2, 2); 130 cmd_buff[0] = IPC::MakeHeader(0x11, 2, 2);
136 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 131 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
137 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware 132 cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
138 cmd_buff[3] = desc; 133 cmd_buff[3] = desc;
139 cmd_buff[4] = buffer; 134 cmd_buff[4] = buffer;
140 135
@@ -145,12 +140,15 @@ static void LoadComponent(Service::Interface* self) {
145 std::vector<u8> component_data(size); 140 std::vector<u8> component_data(size);
146 Memory::ReadBlock(buffer, component_data.data(), component_data.size()); 141 Memory::ReadBlock(buffer, component_data.data(), component_data.size());
147 142
148 LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64, Common::ComputeHash64(component_data.data(), component_data.size())); 143 LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64,
144 Common::ComputeHash64(component_data.data(), component_data.size()));
149 // Some versions of the firmware have the location of DSP structures listed here. 145 // Some versions of the firmware have the location of DSP structures listed here.
150 ASSERT(size > 0x37C); 146 ASSERT(size > 0x37C);
151 LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64, Common::ComputeHash64(component_data.data() + 0x340, 60)); 147 LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64,
148 Common::ComputeHash64(component_data.data() + 0x340, 60));
152 149
153 LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, prog_mask=0x%08X, data_mask=0x%08X, buffer=0x%08X", 150 LOG_WARNING(Service_DSP,
151 "(STUBBED) called size=0x%X, prog_mask=0x%08X, data_mask=0x%08X, buffer=0x%08X",
154 size, prog_mask, data_mask, buffer); 152 size, prog_mask, data_mask, buffer);
155} 153}
156 154
@@ -187,13 +185,14 @@ static void GetSemaphoreEventHandle(Service::Interface* self) {
187static void FlushDataCache(Service::Interface* self) { 185static void FlushDataCache(Service::Interface* self) {
188 u32* cmd_buff = Kernel::GetCommandBuffer(); 186 u32* cmd_buff = Kernel::GetCommandBuffer();
189 u32 address = cmd_buff[1]; 187 u32 address = cmd_buff[1];
190 u32 size = cmd_buff[2]; 188 u32 size = cmd_buff[2];
191 u32 process = cmd_buff[4]; 189 u32 process = cmd_buff[4];
192 190
193 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); 191 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0);
194 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 192 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
195 193
196 LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size, process); 194 LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size,
195 process);
197} 196}
198 197
199/** 198/**
@@ -224,23 +223,29 @@ static void RegisterInterruptEvents(Service::Interface* self) {
224 auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); 223 auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]);
225 224
226 if (!evt) { 225 if (!evt) {
227 LOG_INFO(Service_DSP, "Invalid event handle! type=%u, pipe=%u, event_handle=0x%08X", type_index, pipe_index, event_handle); 226 LOG_INFO(Service_DSP, "Invalid event handle! type=%u, pipe=%u, event_handle=0x%08X",
227 type_index, pipe_index, event_handle);
228 ASSERT(false); // TODO: This should really be handled at an IPC translation layer. 228 ASSERT(false); // TODO: This should really be handled at an IPC translation layer.
229 } 229 }
230 230
231 if (interrupt_events.HasTooManyEventsRegistered()) { 231 if (interrupt_events.HasTooManyEventsRegistered()) {
232 LOG_INFO(Service_DSP, "Ran out of space to register interrupts (Attempted to register type=%u, pipe=%u, event_handle=0x%08X)", 232 LOG_INFO(Service_DSP, "Ran out of space to register interrupts (Attempted to register "
233 "type=%u, pipe=%u, event_handle=0x%08X)",
233 type_index, pipe_index, event_handle); 234 type_index, pipe_index, event_handle);
234 cmd_buff[1] = ResultCode(ErrorDescription::InvalidResultValue, ErrorModule::DSP, ErrorSummary::OutOfResource, ErrorLevel::Status).raw; 235 cmd_buff[1] = ResultCode(ErrorDescription::InvalidResultValue, ErrorModule::DSP,
236 ErrorSummary::OutOfResource, ErrorLevel::Status)
237 .raw;
235 return; 238 return;
236 } 239 }
237 240
238 interrupt_events.Get(type, pipe) = evt; 241 interrupt_events.Get(type, pipe) = evt;
239 LOG_INFO(Service_DSP, "Registered type=%u, pipe=%u, event_handle=0x%08X", type_index, pipe_index, event_handle); 242 LOG_INFO(Service_DSP, "Registered type=%u, pipe=%u, event_handle=0x%08X", type_index,
243 pipe_index, event_handle);
240 cmd_buff[1] = RESULT_SUCCESS.raw; 244 cmd_buff[1] = RESULT_SUCCESS.raw;
241 } else { 245 } else {
242 interrupt_events.Get(type, pipe) = nullptr; 246 interrupt_events.Get(type, pipe) = nullptr;
243 LOG_INFO(Service_DSP, "Unregistered interrupt=%u, channel=%u, event_handle=0x%08X", type_index, pipe_index, event_handle); 247 LOG_INFO(Service_DSP, "Unregistered interrupt=%u, channel=%u, event_handle=0x%08X",
248 type_index, pipe_index, event_handle);
244 cmd_buff[1] = RESULT_SUCCESS.raw; 249 cmd_buff[1] = RESULT_SUCCESS.raw;
245 } 250 }
246} 251}
@@ -282,13 +287,18 @@ static void WriteProcessPipe(Service::Interface* self) {
282 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index); 287 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index);
283 288
284 if (IPC::StaticBufferDesc(size, 1) != cmd_buff[3]) { 289 if (IPC::StaticBufferDesc(size, 1) != cmd_buff[3]) {
285 LOG_ERROR(Service_DSP, "IPC static buffer descriptor failed validation (0x%X). pipe=%u, size=0x%X, buffer=0x%08X", cmd_buff[3], pipe_index, size, buffer); 290 LOG_ERROR(Service_DSP, "IPC static buffer descriptor failed validation (0x%X). pipe=%u, "
291 "size=0x%X, buffer=0x%08X",
292 cmd_buff[3], pipe_index, size, buffer);
286 cmd_buff[0] = IPC::MakeHeader(0, 1, 0); 293 cmd_buff[0] = IPC::MakeHeader(0, 1, 0);
287 cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; 294 cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
295 ErrorSummary::WrongArgument, ErrorLevel::Permanent)
296 .raw;
288 return; 297 return;
289 } 298 }
290 299
291 ASSERT_MSG(Memory::IsValidVirtualAddress(buffer), "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); 300 ASSERT_MSG(Memory::IsValidVirtualAddress(buffer),
301 "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer);
292 302
293 std::vector<u8> message(size); 303 std::vector<u8> message(size);
294 for (u32 i = 0; i < size; i++) { 304 for (u32 i = 0; i < size; i++) {
@@ -327,7 +337,9 @@ static void ReadPipeIfPossible(Service::Interface* self) {
327 337
328 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index); 338 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index);
329 339
330 ASSERT_MSG(Memory::IsValidVirtualAddress(addr), "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr); 340 ASSERT_MSG(Memory::IsValidVirtualAddress(addr),
341 "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown,
342 size, addr);
331 343
332 cmd_buff[0] = IPC::MakeHeader(0x10, 1, 2); 344 cmd_buff[0] = IPC::MakeHeader(0x10, 1, 2);
333 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 345 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
@@ -343,7 +355,9 @@ static void ReadPipeIfPossible(Service::Interface* self) {
343 cmd_buff[3] = IPC::StaticBufferDesc(size, 0); 355 cmd_buff[3] = IPC::StaticBufferDesc(size, 0);
344 cmd_buff[4] = addr; 356 cmd_buff[4] = addr;
345 357
346 LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, unknown, size, addr, cmd_buff[2]); 358 LOG_DEBUG(Service_DSP,
359 "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X",
360 pipe_index, unknown, size, addr, cmd_buff[2]);
347} 361}
348 362
349/** 363/**
@@ -367,7 +381,9 @@ static void ReadPipe(Service::Interface* self) {
367 381
368 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index); 382 DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index);
369 383
370 ASSERT_MSG(Memory::IsValidVirtualAddress(addr), "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr); 384 ASSERT_MSG(Memory::IsValidVirtualAddress(addr),
385 "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown,
386 size, addr);
371 387
372 if (DSP::HLE::GetPipeReadableSize(pipe) >= size) { 388 if (DSP::HLE::GetPipeReadableSize(pipe) >= size) {
373 std::vector<u8> response = DSP::HLE::PipeRead(pipe, size); 389 std::vector<u8> response = DSP::HLE::PipeRead(pipe, size);
@@ -384,7 +400,9 @@ static void ReadPipe(Service::Interface* self) {
384 UNREACHABLE(); 400 UNREACHABLE();
385 } 401 }
386 402
387 LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, unknown, size, addr, cmd_buff[2]); 403 LOG_DEBUG(Service_DSP,
404 "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X",
405 pipe_index, unknown, size, addr, cmd_buff[2]);
388} 406}
389 407
390/** 408/**
@@ -408,7 +426,8 @@ static void GetPipeReadableSize(Service::Interface* self) {
408 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 426 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
409 cmd_buff[2] = static_cast<u32>(DSP::HLE::GetPipeReadableSize(pipe)); 427 cmd_buff[2] = static_cast<u32>(DSP::HLE::GetPipeReadableSize(pipe));
410 428
411 LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, unknown, cmd_buff[2]); 429 LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, return cmd_buff[2]=0x%08X", pipe_index,
430 unknown, cmd_buff[2]);
412} 431}
413 432
414/** 433/**
@@ -443,7 +462,7 @@ static void GetHeadphoneStatus(Service::Interface* self) {
443 462
444 cmd_buff[0] = IPC::MakeHeader(0x1F, 2, 0); 463 cmd_buff[0] = IPC::MakeHeader(0x1F, 2, 0);
445 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 464 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
446 cmd_buff[2] = 0; // Not using headphones 465 cmd_buff[2] = 0; // Not using headphones
447 466
448 LOG_DEBUG(Service_DSP, "called"); 467 LOG_DEBUG(Service_DSP, "called");
449} 468}
@@ -466,7 +485,8 @@ static void RecvData(Service::Interface* self) {
466 485
467 ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number); 486 ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number);
468 487
469 // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown or slept. 488 // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown
489 // or slept.
470 490
471 cmd_buff[0] = IPC::MakeHeader(0x1, 2, 0); 491 cmd_buff[0] = IPC::MakeHeader(0x1, 2, 0);
472 cmd_buff[1] = RESULT_SUCCESS.raw; 492 cmd_buff[1] = RESULT_SUCCESS.raw;
@@ -512,39 +532,39 @@ static void RecvDataIsReady(Service::Interface* self) {
512} 532}
513 533
514const Interface::FunctionInfo FunctionTable[] = { 534const Interface::FunctionInfo FunctionTable[] = {
515 {0x00010040, RecvData, "RecvData"}, 535 {0x00010040, RecvData, "RecvData"},
516 {0x00020040, RecvDataIsReady, "RecvDataIsReady"}, 536 {0x00020040, RecvDataIsReady, "RecvDataIsReady"},
517 {0x00030080, nullptr, "SendData"}, 537 {0x00030080, nullptr, "SendData"},
518 {0x00040040, nullptr, "SendDataIsEmpty"}, 538 {0x00040040, nullptr, "SendDataIsEmpty"},
519 {0x000500C2, nullptr, "SendFifoEx"}, 539 {0x000500C2, nullptr, "SendFifoEx"},
520 {0x000600C0, nullptr, "RecvFifoEx"}, 540 {0x000600C0, nullptr, "RecvFifoEx"},
521 {0x00070040, SetSemaphore, "SetSemaphore"}, 541 {0x00070040, SetSemaphore, "SetSemaphore"},
522 {0x00080000, nullptr, "GetSemaphore"}, 542 {0x00080000, nullptr, "GetSemaphore"},
523 {0x00090040, nullptr, "ClearSemaphore"}, 543 {0x00090040, nullptr, "ClearSemaphore"},
524 {0x000A0040, nullptr, "MaskSemaphore"}, 544 {0x000A0040, nullptr, "MaskSemaphore"},
525 {0x000B0000, nullptr, "CheckSemaphoreRequest"}, 545 {0x000B0000, nullptr, "CheckSemaphoreRequest"},
526 {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"}, 546 {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"},
527 {0x000D0082, WriteProcessPipe, "WriteProcessPipe"}, 547 {0x000D0082, WriteProcessPipe, "WriteProcessPipe"},
528 {0x000E00C0, ReadPipe, "ReadPipe"}, 548 {0x000E00C0, ReadPipe, "ReadPipe"},
529 {0x000F0080, GetPipeReadableSize, "GetPipeReadableSize"}, 549 {0x000F0080, GetPipeReadableSize, "GetPipeReadableSize"},
530 {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"}, 550 {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"},
531 {0x001100C2, LoadComponent, "LoadComponent"}, 551 {0x001100C2, LoadComponent, "LoadComponent"},
532 {0x00120000, nullptr, "UnloadComponent"}, 552 {0x00120000, nullptr, "UnloadComponent"},
533 {0x00130082, FlushDataCache, "FlushDataCache"}, 553 {0x00130082, FlushDataCache, "FlushDataCache"},
534 {0x00140082, nullptr, "InvalidateDCache"}, 554 {0x00140082, nullptr, "InvalidateDCache"},
535 {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"}, 555 {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"},
536 {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"}, 556 {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"},
537 {0x00170040, SetSemaphoreMask, "SetSemaphoreMask"}, 557 {0x00170040, SetSemaphoreMask, "SetSemaphoreMask"},
538 {0x00180040, nullptr, "GetPhysicalAddress"}, 558 {0x00180040, nullptr, "GetPhysicalAddress"},
539 {0x00190040, nullptr, "GetVirtualAddress"}, 559 {0x00190040, nullptr, "GetVirtualAddress"},
540 {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, 560 {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"},
541 {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, 561 {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"},
542 {0x001C0082, nullptr, "SetIirFilterEQ"}, 562 {0x001C0082, nullptr, "SetIirFilterEQ"},
543 {0x001D00C0, nullptr, "ReadMultiEx_SPI2"}, 563 {0x001D00C0, nullptr, "ReadMultiEx_SPI2"},
544 {0x001E00C2, nullptr, "WriteMultiEx_SPI2"}, 564 {0x001E00C2, nullptr, "WriteMultiEx_SPI2"},
545 {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"}, 565 {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"},
546 {0x00200040, nullptr, "ForceHeadphoneOut"}, 566 {0x00200040, nullptr, "ForceHeadphoneOut"},
547 {0x00210000, nullptr, "GetIsDspOccupied"}, 567 {0x00210000, nullptr, "GetIsDspOccupied"},
548}; 568};
549 569
550//////////////////////////////////////////////////////////////////////////////////////////////////// 570////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 22f6687cc..3e97da6eb 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8
9#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
10 9
11namespace DSP { 10namespace DSP {
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index 5f9cf6e94..3ca4f98de 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -5,7 +5,6 @@
5#include "common/bit_field.h" 5#include "common/bit_field.h"
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8
9#include "core/hle/service/err_f.h" 8#include "core/hle/service/err_f.h"
10 9
11//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -35,70 +34,70 @@ union ErrInfo {
35 u8 specifier; 34 u8 specifier;
36 35
37 struct { 36 struct {
38 u8 specifier; // 0x0 37 u8 specifier; // 0x0
39 u8 rev_high; // 0x1 38 u8 rev_high; // 0x1
40 u16 rev_low; // 0x2 39 u16 rev_low; // 0x2
41 RSL result_code; // 0x4 40 RSL result_code; // 0x4
42 u32 address; // 0x8 41 u32 address; // 0x8
43 INSERT_PADDING_BYTES(4); // 0xC 42 INSERT_PADDING_BYTES(4); // 0xC
44 u32 pid_low; // 0x10 43 u32 pid_low; // 0x10
45 u32 pid_high; // 0x14 44 u32 pid_high; // 0x14
46 u32 aid_low; // 0x18 45 u32 aid_low; // 0x18
47 u32 aid_high; // 0x1C 46 u32 aid_high; // 0x1C
48 } errtype1; 47 } errtype1;
49 48
50 struct { 49 struct {
51 u8 specifier; // 0x0 50 u8 specifier; // 0x0
52 u8 rev_high; // 0x1 51 u8 rev_high; // 0x1
53 u16 rev_low; // 0x2 52 u16 rev_low; // 0x2
54 INSERT_PADDING_BYTES(0xC); // 0x4 53 INSERT_PADDING_BYTES(0xC); // 0x4
55 u32 pid_low; // 0x10 54 u32 pid_low; // 0x10
56 u32 pid_high; // 0x14 55 u32 pid_high; // 0x14
57 u32 aid_low; // 0x18 56 u32 aid_low; // 0x18
58 u32 aid_high; // 0x1C 57 u32 aid_high; // 0x1C
59 u8 error_type; // 0x20 58 u8 error_type; // 0x20
60 INSERT_PADDING_BYTES(3); // 0x21 59 INSERT_PADDING_BYTES(3); // 0x21
61 u32 fault_status_reg; // 0x24 60 u32 fault_status_reg; // 0x24
62 u32 fault_addr; // 0x28 61 u32 fault_addr; // 0x28
63 u32 fpexc; // 0x2C 62 u32 fpexc; // 0x2C
64 u32 finst; // 0x30 63 u32 finst; // 0x30
65 u32 finst2; // 0x34 64 u32 finst2; // 0x34
66 INSERT_PADDING_BYTES(0x34); // 0x38 65 INSERT_PADDING_BYTES(0x34); // 0x38
67 u32 sp; // 0x6C 66 u32 sp; // 0x6C
68 u32 pc; // 0x70 67 u32 pc; // 0x70
69 u32 lr; // 0x74 68 u32 lr; // 0x74
70 u32 cpsr; // 0x78 69 u32 cpsr; // 0x78
71 } errtype3; 70 } errtype3;
72 71
73 struct { 72 struct {
74 u8 specifier; // 0x0 73 u8 specifier; // 0x0
75 u8 rev_high; // 0x1 74 u8 rev_high; // 0x1
76 u16 rev_low; // 0x2 75 u16 rev_low; // 0x2
77 RSL result_code; // 0x4 76 RSL result_code; // 0x4
78 INSERT_PADDING_BYTES(8); // 0x8 77 INSERT_PADDING_BYTES(8); // 0x8
79 u32 pid_low; // 0x10 78 u32 pid_low; // 0x10
80 u32 pid_high; // 0x14 79 u32 pid_high; // 0x14
81 u32 aid_low; // 0x18 80 u32 aid_low; // 0x18
82 u32 aid_high; // 0x1C 81 u32 aid_high; // 0x1C
83 char debug_string1[0x2E]; // 0x20 82 char debug_string1[0x2E]; // 0x20
84 char debug_string2[0x2E]; // 0x4E 83 char debug_string2[0x2E]; // 0x4E
85 } errtype4; 84 } errtype4;
86}; 85};
87 86
88enum { 87enum { PrefetchAbort = 0, DataAbort = 1, UndefInstr = 2, VectorFP = 3 };
89 PrefetchAbort = 0,
90 DataAbort = 1,
91 UndefInstr = 2,
92 VectorFP = 3
93};
94 88
95static std::string GetErrInfo3Type(u8 type_code) { 89static std::string GetErrInfo3Type(u8 type_code) {
96 switch (type_code) { 90 switch (type_code) {
97 case PrefetchAbort: return "Prefetch Abort"; 91 case PrefetchAbort:
98 case DataAbort: return "Data Abort"; 92 return "Prefetch Abort";
99 case UndefInstr: return "Undefined Instruction"; 93 case DataAbort:
100 case VectorFP: return "Vector Floating Point"; 94 return "Data Abort";
101 default: return "unknown"; 95 case UndefInstr:
96 return "Undefined Instruction";
97 case VectorFP:
98 return "Vector Floating Point";
99 default:
100 return "unknown";
102 } 101 }
103} 102}
104 103
@@ -110,8 +109,7 @@ static void ThrowFatalError(Service::Interface* self) {
110 109
111 switch (errinfo->specifier) { 110 switch (errinfo->specifier) {
112 case ErrSpecifier0: 111 case ErrSpecifier0:
113 case ErrSpecifier1: 112 case ErrSpecifier1: {
114 {
115 const auto& errtype = errinfo->errtype1; 113 const auto& errtype = errinfo->errtype1;
116 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); 114 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
117 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); 115 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
@@ -119,15 +117,14 @@ static void ThrowFatalError(Service::Interface* self) {
119 LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address); 117 LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address);
120 118
121 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw); 119 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
122 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); 120 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
123 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value()); 121 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
124 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value()); 122 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
125 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value()); 123 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
126 break; 124 break;
127 } 125 }
128 126
129 case ErrSpecifier3: 127 case ErrSpecifier3: {
130 {
131 const auto& errtype = errinfo->errtype3; 128 const auto& errtype = errinfo->errtype3;
132 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); 129 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
133 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); 130 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
@@ -154,18 +151,17 @@ static void ThrowFatalError(Service::Interface* self) {
154 break; 151 break;
155 } 152 }
156 153
157 case ErrSpecifier4: 154 case ErrSpecifier4: {
158 {
159 const auto& errtype = errinfo->errtype4; 155 const auto& errtype = errinfo->errtype4;
160 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); 156 LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high);
161 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); 157 LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16));
162 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high); 158 LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high);
163 159
164 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw); 160 LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw);
165 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); 161 LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value());
166 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value()); 162 LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value());
167 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value()); 163 LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value());
168 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value()); 164 LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value());
169 165
170 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1); 166 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1);
171 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2); 167 LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2);
@@ -177,7 +173,7 @@ static void ThrowFatalError(Service::Interface* self) {
177} 173}
178 174
179const Interface::FunctionInfo FunctionTable[] = { 175const Interface::FunctionInfo FunctionTable[] = {
180 {0x00010800, ThrowFatalError, "ThrowFatalError"} 176 {0x00010800, ThrowFatalError, "ThrowFatalError"},
181}; 177};
182 178
183//////////////////////////////////////////////////////////////////////////////////////////////////// 179////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp
index 29d144365..fa5080535 100644
--- a/src/core/hle/service/frd/frd.cpp
+++ b/src/core/hle/service/frd/frd.cpp
@@ -3,11 +3,10 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/string_util.h" 5#include "common/string_util.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/frd/frd.h" 6#include "core/hle/service/frd/frd.h"
9#include "core/hle/service/frd/frd_a.h" 7#include "core/hle/service/frd/frd_a.h"
10#include "core/hle/service/frd/frd_u.h" 8#include "core/hle/service/frd/frd_u.h"
9#include "core/hle/service/service.h"
11 10
12namespace Service { 11namespace Service {
13namespace FRD { 12namespace FRD {
@@ -43,7 +42,7 @@ void GetFriendKeyList(Service::Interface* self) {
43 } 42 }
44 43
45 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 44 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
46 cmd_buff[2] = 0; // 0 friends 45 cmd_buff[2] = 0; // 0 friends
47 LOG_WARNING(Service_FRD, "(STUBBED) called, unknown=%d, frd_count=%d, frd_key_addr=0x%08X", 46 LOG_WARNING(Service_FRD, "(STUBBED) called, unknown=%d, frd_count=%d, frd_key_addr=0x%08X",
48 unknown, frd_count, frd_key_addr); 47 unknown, frd_count, frd_key_addr);
49} 48}
@@ -61,25 +60,27 @@ void GetFriendProfile(Service::Interface* self) {
61 } 60 }
62 61
63 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 62 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
64 LOG_WARNING(Service_FRD, "(STUBBED) called, count=%d, frd_key_addr=0x%08X, profiles_addr=0x%08X", 63 LOG_WARNING(Service_FRD,
65 count, frd_key_addr, profiles_addr); 64 "(STUBBED) called, count=%d, frd_key_addr=0x%08X, profiles_addr=0x%08X", count,
65 frd_key_addr, profiles_addr);
66} 66}
67 67
68void GetFriendAttributeFlags(Service::Interface* self) { 68void GetFriendAttributeFlags(Service::Interface* self) {
69 u32* cmd_buff = Kernel::GetCommandBuffer(); 69 u32* cmd_buff = Kernel::GetCommandBuffer();
70 70
71 u32 count = cmd_buff[1]; 71 u32 count = cmd_buff[1];
72 u32 frd_key_addr = cmd_buff[3]; 72 u32 frd_key_addr = cmd_buff[3];
73 u32 attr_flags_addr = cmd_buff[65]; 73 u32 attr_flags_addr = cmd_buff[65];
74 74
75 for (u32 i = 0; i < count; ++i) { 75 for (u32 i = 0; i < count; ++i) {
76 //TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte 76 // TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte
77 Memory::Write8(attr_flags_addr + i, 0); 77 Memory::Write8(attr_flags_addr + i, 0);
78 } 78 }
79 79
80 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 80 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
81 LOG_WARNING(Service_FRD, "(STUBBED) called, count=%d, frd_key_addr=0x%08X, attr_flags_addr=0x%08X", 81 LOG_WARNING(Service_FRD,
82 count, frd_key_addr, attr_flags_addr); 82 "(STUBBED) called, count=%d, frd_key_addr=0x%08X, attr_flags_addr=0x%08X", count,
83 frd_key_addr, attr_flags_addr);
83} 84}
84 85
85void GetMyFriendKey(Service::Interface* self) { 86void GetMyFriendKey(Service::Interface* self) {
@@ -106,8 +107,7 @@ void Init() {
106 AddService(new FRD_U_Interface); 107 AddService(new FRD_U_Interface);
107} 108}
108 109
109void Shutdown() { 110void Shutdown() {}
110}
111 111
112} // namespace FRD 112} // namespace FRD
113 113
diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp
index 818d610f3..cfc37210b 100644
--- a/src/core/hle/service/frd/frd_a.cpp
+++ b/src/core/hle/service/frd/frd_a.cpp
@@ -11,7 +11,7 @@ namespace FRD {
11// const Interface::FunctionInfo FunctionTable[] = { }; 11// const Interface::FunctionInfo FunctionTable[] = { };
12 12
13FRD_A_Interface::FRD_A_Interface() { 13FRD_A_Interface::FRD_A_Interface() {
14 //Register(FunctionTable); 14 // Register(FunctionTable);
15} 15}
16 16
17} // namespace FRD 17} // namespace FRD
diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp
index db8666416..bd1c9c16b 100644
--- a/src/core/hle/service/frd/frd_u.cpp
+++ b/src/core/hle/service/frd/frd_u.cpp
@@ -9,59 +9,59 @@ namespace Service {
9namespace FRD { 9namespace FRD {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010000, nullptr, "HasLoggedIn"}, 12 {0x00010000, nullptr, "HasLoggedIn"},
13 {0x00020000, nullptr, "IsOnline"}, 13 {0x00020000, nullptr, "IsOnline"},
14 {0x00030000, nullptr, "Login"}, 14 {0x00030000, nullptr, "Login"},
15 {0x00040000, nullptr, "Logout"}, 15 {0x00040000, nullptr, "Logout"},
16 {0x00050000, GetMyFriendKey, "GetMyFriendKey"}, 16 {0x00050000, GetMyFriendKey, "GetMyFriendKey"},
17 {0x00060000, nullptr, "GetMyPreference"}, 17 {0x00060000, nullptr, "GetMyPreference"},
18 {0x00070000, nullptr, "GetMyProfile"}, 18 {0x00070000, nullptr, "GetMyProfile"},
19 {0x00080000, GetMyPresence, "GetMyPresence"}, 19 {0x00080000, GetMyPresence, "GetMyPresence"},
20 {0x00090000, GetMyScreenName, "GetMyScreenName"}, 20 {0x00090000, GetMyScreenName, "GetMyScreenName"},
21 {0x000A0000, nullptr, "GetMyMii"}, 21 {0x000A0000, nullptr, "GetMyMii"},
22 {0x000B0000, nullptr, "GetMyLocalAccountId"}, 22 {0x000B0000, nullptr, "GetMyLocalAccountId"},
23 {0x000C0000, nullptr, "GetMyPlayingGame"}, 23 {0x000C0000, nullptr, "GetMyPlayingGame"},
24 {0x000D0000, nullptr, "GetMyFavoriteGame"}, 24 {0x000D0000, nullptr, "GetMyFavoriteGame"},
25 {0x000E0000, nullptr, "GetMyNcPrincipalId"}, 25 {0x000E0000, nullptr, "GetMyNcPrincipalId"},
26 {0x000F0000, nullptr, "GetMyComment"}, 26 {0x000F0000, nullptr, "GetMyComment"},
27 {0x00100040, nullptr, "GetMyPassword"}, 27 {0x00100040, nullptr, "GetMyPassword"},
28 {0x00110080, GetFriendKeyList, "GetFriendKeyList"}, 28 {0x00110080, GetFriendKeyList, "GetFriendKeyList"},
29 {0x00120042, nullptr, "GetFriendPresence"}, 29 {0x00120042, nullptr, "GetFriendPresence"},
30 {0x00130142, nullptr, "GetFriendScreenName"}, 30 {0x00130142, nullptr, "GetFriendScreenName"},
31 {0x00140044, nullptr, "GetFriendMii"}, 31 {0x00140044, nullptr, "GetFriendMii"},
32 {0x00150042, GetFriendProfile, "GetFriendProfile"}, 32 {0x00150042, GetFriendProfile, "GetFriendProfile"},
33 {0x00160042, nullptr, "GetFriendRelationship"}, 33 {0x00160042, nullptr, "GetFriendRelationship"},
34 {0x00170042, GetFriendAttributeFlags, "GetFriendAttributeFlags"}, 34 {0x00170042, GetFriendAttributeFlags, "GetFriendAttributeFlags"},
35 {0x00180044, nullptr, "GetFriendPlayingGame"}, 35 {0x00180044, nullptr, "GetFriendPlayingGame"},
36 {0x00190042, nullptr, "GetFriendFavoriteGame"}, 36 {0x00190042, nullptr, "GetFriendFavoriteGame"},
37 {0x001A00C4, nullptr, "GetFriendInfo"}, 37 {0x001A00C4, nullptr, "GetFriendInfo"},
38 {0x001B0080, nullptr, "IsIncludedInFriendList"}, 38 {0x001B0080, nullptr, "IsIncludedInFriendList"},
39 {0x001C0042, nullptr, "UnscrambleLocalFriendCode"}, 39 {0x001C0042, nullptr, "UnscrambleLocalFriendCode"},
40 {0x001D0002, nullptr, "UpdateGameModeDescription"}, 40 {0x001D0002, nullptr, "UpdateGameModeDescription"},
41 {0x001E02C2, nullptr, "UpdateGameMode"}, 41 {0x001E02C2, nullptr, "UpdateGameMode"},
42 {0x001F0042, nullptr, "SendInvitation"}, 42 {0x001F0042, nullptr, "SendInvitation"},
43 {0x00200002, nullptr, "AttachToEventNotification"}, 43 {0x00200002, nullptr, "AttachToEventNotification"},
44 {0x00210040, nullptr, "SetNotificationMask"}, 44 {0x00210040, nullptr, "SetNotificationMask"},
45 {0x00220040, nullptr, "GetEventNotification"}, 45 {0x00220040, nullptr, "GetEventNotification"},
46 {0x00230000, nullptr, "GetLastResponseResult"}, 46 {0x00230000, nullptr, "GetLastResponseResult"},
47 {0x00240040, nullptr, "PrincipalIdToFriendCode"}, 47 {0x00240040, nullptr, "PrincipalIdToFriendCode"},
48 {0x00250080, nullptr, "FriendCodeToPrincipalId"}, 48 {0x00250080, nullptr, "FriendCodeToPrincipalId"},
49 {0x00260080, nullptr, "IsValidFriendCode"}, 49 {0x00260080, nullptr, "IsValidFriendCode"},
50 {0x00270040, nullptr, "ResultToErrorCode"}, 50 {0x00270040, nullptr, "ResultToErrorCode"},
51 {0x00280244, nullptr, "RequestGameAuthentication"}, 51 {0x00280244, nullptr, "RequestGameAuthentication"},
52 {0x00290000, nullptr, "GetGameAuthenticationData"}, 52 {0x00290000, nullptr, "GetGameAuthenticationData"},
53 {0x002A0204, nullptr, "RequestServiceLocator"}, 53 {0x002A0204, nullptr, "RequestServiceLocator"},
54 {0x002B0000, nullptr, "GetServiceLocatorData"}, 54 {0x002B0000, nullptr, "GetServiceLocatorData"},
55 {0x002C0002, nullptr, "DetectNatProperties"}, 55 {0x002C0002, nullptr, "DetectNatProperties"},
56 {0x002D0000, nullptr, "GetNatProperties"}, 56 {0x002D0000, nullptr, "GetNatProperties"},
57 {0x002E0000, nullptr, "GetServerTimeInterval"}, 57 {0x002E0000, nullptr, "GetServerTimeInterval"},
58 {0x002F0040, nullptr, "AllowHalfAwake"}, 58 {0x002F0040, nullptr, "AllowHalfAwake"},
59 {0x00300000, nullptr, "GetServerTypes"}, 59 {0x00300000, nullptr, "GetServerTypes"},
60 {0x00310082, nullptr, "GetFriendComment"}, 60 {0x00310082, nullptr, "GetFriendComment"},
61 {0x00320042, nullptr, "SetClientSdkVersion"}, 61 {0x00320042, nullptr, "SetClientSdkVersion"},
62 {0x00330000, nullptr, "GetMyApproachContext"}, 62 {0x00330000, nullptr, "GetMyApproachContext"},
63 {0x00340046, nullptr, "AddFriendWithApproach"}, 63 {0x00340046, nullptr, "AddFriendWithApproach"},
64 {0x00350082, nullptr, "DecryptApproachContext"}, 64 {0x00350082, nullptr, "DecryptApproachContext"},
65}; 65};
66 66
67FRD_U_Interface::FRD_U_Interface() { 67FRD_U_Interface::FRD_U_Interface() {
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 4c7aaa7f2..4dc7e1e3c 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -3,19 +3,16 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstddef> 5#include <cstddef>
6#include <memory>
6#include <system_error> 7#include <system_error>
7#include <type_traits> 8#include <type_traits>
8#include <memory>
9#include <unordered_map> 9#include <unordered_map>
10#include <utility> 10#include <utility>
11
12#include <boost/container/flat_map.hpp> 11#include <boost/container/flat_map.hpp>
13
14#include "common/assert.h" 12#include "common/assert.h"
15#include "common/common_types.h" 13#include "common/common_types.h"
16#include "common/file_util.h" 14#include "common/file_util.h"
17#include "common/logging/log.h" 15#include "common/logging/log.h"
18
19#include "core/file_sys/archive_backend.h" 16#include "core/file_sys/archive_backend.h"
20#include "core/file_sys/archive_extsavedata.h" 17#include "core/file_sys/archive_extsavedata.h"
21#include "core/file_sys/archive_savedata.h" 18#include "core/file_sys/archive_savedata.h"
@@ -25,25 +22,25 @@
25#include "core/file_sys/directory_backend.h" 22#include "core/file_sys/directory_backend.h"
26#include "core/file_sys/file_backend.h" 23#include "core/file_sys/file_backend.h"
27#include "core/hle/hle.h" 24#include "core/hle/hle.h"
28#include "core/hle/service/service.h" 25#include "core/hle/result.h"
29#include "core/hle/service/fs/archive.h" 26#include "core/hle/service/fs/archive.h"
30#include "core/hle/service/fs/fs_user.h" 27#include "core/hle/service/fs/fs_user.h"
31#include "core/hle/result.h" 28#include "core/hle/service/service.h"
32#include "core/memory.h" 29#include "core/memory.h"
33 30
34// Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map. 31// Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map.
35// Workaroung for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 32// Workaroung for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970
36namespace std { 33namespace std {
37 template <> 34template <>
38 struct hash<Service::FS::ArchiveIdCode> { 35struct hash<Service::FS::ArchiveIdCode> {
39 typedef Service::FS::ArchiveIdCode argument_type; 36 typedef Service::FS::ArchiveIdCode argument_type;
40 typedef std::size_t result_type; 37 typedef std::size_t result_type;
41 38
42 result_type operator()(const argument_type& id_code) const { 39 result_type operator()(const argument_type& id_code) const {
43 typedef std::underlying_type<argument_type>::type Type; 40 typedef std::underlying_type<argument_type>::type Type;
44 return std::hash<Type>()(static_cast<Type>(id_code)); 41 return std::hash<Type>()(static_cast<Type>(id_code));
45 } 42 }
46 }; 43};
47} 44}
48 45
49/// TODO(Subv): Confirm length of these strings 46/// TODO(Subv): Confirm length of these strings
@@ -56,39 +53,40 @@ namespace FS {
56// TODO: Verify code 53// TODO: Verify code
57/// Returned when a function is passed an invalid handle. 54/// Returned when a function is passed an invalid handle.
58const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::FS, 55const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::FS,
59 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 56 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
60 57
61/// Returned when a function is passed an invalid archive handle. 58/// Returned when a function is passed an invalid archive handle.
62const ResultCode ERR_INVALID_ARCHIVE_HANDLE(ErrorDescription::FS_ArchiveNotMounted, ErrorModule::FS, 59const ResultCode ERR_INVALID_ARCHIVE_HANDLE(ErrorDescription::FS_ArchiveNotMounted, ErrorModule::FS,
63 ErrorSummary::NotFound, ErrorLevel::Status); // 0xC8804465 60 ErrorSummary::NotFound,
61 ErrorLevel::Status); // 0xC8804465
64 62
65// Command to access archive file 63// Command to access archive file
66enum class FileCommand : u32 { 64enum class FileCommand : u32 {
67 Dummy1 = 0x000100C6, 65 Dummy1 = 0x000100C6,
68 Control = 0x040100C4, 66 Control = 0x040100C4,
69 OpenSubFile = 0x08010100, 67 OpenSubFile = 0x08010100,
70 Read = 0x080200C2, 68 Read = 0x080200C2,
71 Write = 0x08030102, 69 Write = 0x08030102,
72 GetSize = 0x08040000, 70 GetSize = 0x08040000,
73 SetSize = 0x08050080, 71 SetSize = 0x08050080,
74 GetAttributes = 0x08060000, 72 GetAttributes = 0x08060000,
75 SetAttributes = 0x08070040, 73 SetAttributes = 0x08070040,
76 Close = 0x08080000, 74 Close = 0x08080000,
77 Flush = 0x08090000, 75 Flush = 0x08090000,
78 SetPriority = 0x080A0040, 76 SetPriority = 0x080A0040,
79 GetPriority = 0x080B0000, 77 GetPriority = 0x080B0000,
80 OpenLinkFile = 0x080C0000, 78 OpenLinkFile = 0x080C0000,
81}; 79};
82 80
83// Command to access directory 81// Command to access directory
84enum class DirectoryCommand : u32 { 82enum class DirectoryCommand : u32 {
85 Dummy1 = 0x000100C6, 83 Dummy1 = 0x000100C6,
86 Control = 0x040100C4, 84 Control = 0x040100C4,
87 Read = 0x08010042, 85 Read = 0x08010042,
88 Close = 0x08020000, 86 Close = 0x08020000,
89}; 87};
90 88
91File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path & path) 89File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
92 : path(path), priority(0), backend(std::move(backend)) {} 90 : path(path), priority(0), backend(std::move(backend)) {}
93 91
94File::~File() {} 92File::~File() {}
@@ -98,117 +96,110 @@ ResultVal<bool> File::SyncRequest() {
98 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); 96 FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]);
99 switch (cmd) { 97 switch (cmd) {
100 98
101 // Read from file... 99 // Read from file...
102 case FileCommand::Read: 100 case FileCommand::Read: {
103 { 101 u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32;
104 u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; 102 u32 length = cmd_buff[3];
105 u32 length = cmd_buff[3]; 103 u32 address = cmd_buff[5];
106 u32 address = cmd_buff[5]; 104 LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x",
107 LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", 105 GetTypeName().c_str(), GetName().c_str(), offset, length, address);
108 GetTypeName().c_str(), GetName().c_str(), offset, length, address); 106
109 107 if (offset + length > backend->GetSize()) {
110 if (offset + length > backend->GetSize()) { 108 LOG_ERROR(Service_FS,
111 LOG_ERROR(Service_FS, "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX", 109 "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX",
112 offset, length, backend->GetSize()); 110 offset, length, backend->GetSize());
113 }
114
115 std::vector<u8> data(length);
116 ResultVal<size_t> read = backend->Read(offset, data.size(), data.data());
117 if (read.Failed()) {
118 cmd_buff[1] = read.Code().raw;
119 return read.Code();
120 }
121 Memory::WriteBlock(address, data.data(), *read);
122 cmd_buff[2] = static_cast<u32>(*read);
123 break;
124 } 111 }
125 112
126 // Write to file... 113 std::vector<u8> data(length);
127 case FileCommand::Write: 114 ResultVal<size_t> read = backend->Read(offset, data.size(), data.data());
128 { 115 if (read.Failed()) {
129 u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; 116 cmd_buff[1] = read.Code().raw;
130 u32 length = cmd_buff[3]; 117 return read.Code();
131 u32 flush = cmd_buff[4];
132 u32 address = cmd_buff[6];
133 LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x",
134 GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush);
135
136 std::vector<u8> data(length);
137 Memory::ReadBlock(address, data.data(), data.size());
138 ResultVal<size_t> written = backend->Write(offset, data.size(), flush != 0, data.data());
139 if (written.Failed()) {
140 cmd_buff[1] = written.Code().raw;
141 return written.Code();
142 }
143 cmd_buff[2] = static_cast<u32>(*written);
144 break;
145 } 118 }
119 Memory::WriteBlock(address, data.data(), *read);
120 cmd_buff[2] = static_cast<u32>(*read);
121 break;
122 }
146 123
147 case FileCommand::GetSize: 124 // Write to file...
148 { 125 case FileCommand::Write: {
149 LOG_TRACE(Service_FS, "GetSize %s %s", GetTypeName().c_str(), GetName().c_str()); 126 u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32;
150 u64 size = backend->GetSize(); 127 u32 length = cmd_buff[3];
151 cmd_buff[2] = (u32)size; 128 u32 flush = cmd_buff[4];
152 cmd_buff[3] = size >> 32; 129 u32 address = cmd_buff[6];
153 break; 130 LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x",
131 GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush);
132
133 std::vector<u8> data(length);
134 Memory::ReadBlock(address, data.data(), data.size());
135 ResultVal<size_t> written = backend->Write(offset, data.size(), flush != 0, data.data());
136 if (written.Failed()) {
137 cmd_buff[1] = written.Code().raw;
138 return written.Code();
154 } 139 }
140 cmd_buff[2] = static_cast<u32>(*written);
141 break;
142 }
155 143
156 case FileCommand::SetSize: 144 case FileCommand::GetSize: {
157 { 145 LOG_TRACE(Service_FS, "GetSize %s %s", GetTypeName().c_str(), GetName().c_str());
158 u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); 146 u64 size = backend->GetSize();
159 LOG_TRACE(Service_FS, "SetSize %s %s size=%llu", 147 cmd_buff[2] = (u32)size;
160 GetTypeName().c_str(), GetName().c_str(), size); 148 cmd_buff[3] = size >> 32;
161 backend->SetSize(size); 149 break;
162 break; 150 }
163 }
164 151
165 case FileCommand::Close: 152 case FileCommand::SetSize: {
166 { 153 u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32);
167 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); 154 LOG_TRACE(Service_FS, "SetSize %s %s size=%llu", GetTypeName().c_str(), GetName().c_str(),
168 backend->Close(); 155 size);
169 break; 156 backend->SetSize(size);
170 } 157 break;
158 }
171 159
172 case FileCommand::Flush: 160 case FileCommand::Close: {
173 { 161 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str());
174 LOG_TRACE(Service_FS, "Flush"); 162 backend->Close();
175 backend->Flush(); 163 break;
176 break; 164 }
177 }
178 165
179 case FileCommand::OpenLinkFile: 166 case FileCommand::Flush: {
180 { 167 LOG_TRACE(Service_FS, "Flush");
181 LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); 168 backend->Flush();
182 cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE); 169 break;
183 break; 170 }
184 }
185 171
186 case FileCommand::SetPriority: 172 case FileCommand::OpenLinkFile: {
187 { 173 LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
188 priority = cmd_buff[1]; 174 cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE);
189 LOG_TRACE(Service_FS, "SetPriority %u", priority); 175 break;
190 break; 176 }
191 }
192 177
193 case FileCommand::GetPriority: 178 case FileCommand::SetPriority: {
194 { 179 priority = cmd_buff[1];
195 cmd_buff[2] = priority; 180 LOG_TRACE(Service_FS, "SetPriority %u", priority);
196 LOG_TRACE(Service_FS, "GetPriority"); 181 break;
197 break; 182 }
198 } 183
184 case FileCommand::GetPriority: {
185 cmd_buff[2] = priority;
186 LOG_TRACE(Service_FS, "GetPriority");
187 break;
188 }
199 189
200 // Unknown command... 190 // Unknown command...
201 default: 191 default:
202 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); 192 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
203 ResultCode error = UnimplementedFunction(ErrorModule::FS); 193 ResultCode error = UnimplementedFunction(ErrorModule::FS);
204 cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. 194 cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
205 return error; 195 return error;
206 } 196 }
207 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 197 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
208 return MakeResult<bool>(false); 198 return MakeResult<bool>(false);
209} 199}
210 200
211Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path & path) 201Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend,
202 const FileSys::Path& path)
212 : path(path), backend(std::move(backend)) {} 203 : path(path), backend(std::move(backend)) {}
213 204
214Directory::~Directory() {} 205Directory::~Directory() {}
@@ -218,35 +209,33 @@ ResultVal<bool> Directory::SyncRequest() {
218 DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); 209 DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]);
219 switch (cmd) { 210 switch (cmd) {
220 211
221 // Read from directory... 212 // Read from directory...
222 case DirectoryCommand::Read: 213 case DirectoryCommand::Read: {
223 { 214 u32 count = cmd_buff[1];
224 u32 count = cmd_buff[1]; 215 u32 address = cmd_buff[3];
225 u32 address = cmd_buff[3]; 216 std::vector<FileSys::Entry> entries(count);
226 std::vector<FileSys::Entry> entries(count); 217 LOG_TRACE(Service_FS, "Read %s %s: count=%d", GetTypeName().c_str(), GetName().c_str(),
227 LOG_TRACE(Service_FS, "Read %s %s: count=%d", 218 count);
228 GetTypeName().c_str(), GetName().c_str(), count); 219
229 220 // Number of entries actually read
230 // Number of entries actually read 221 u32 read = backend->Read(entries.size(), entries.data());
231 u32 read = backend->Read(entries.size(), entries.data()); 222 cmd_buff[2] = read;
232 cmd_buff[2] = read; 223 Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry));
233 Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry)); 224 break;
234 break; 225 }
235 }
236 226
237 case DirectoryCommand::Close: 227 case DirectoryCommand::Close: {
238 { 228 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str());
239 LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); 229 backend->Close();
240 backend->Close(); 230 break;
241 break; 231 }
242 }
243 232
244 // Unknown command... 233 // Unknown command...
245 default: 234 default:
246 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); 235 LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
247 ResultCode error = UnimplementedFunction(ErrorModule::FS); 236 ResultCode error = UnimplementedFunction(ErrorModule::FS);
248 cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. 237 cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that.
249 return MakeResult<bool>(false); 238 return MakeResult<bool>(false);
250 } 239 }
251 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 240 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
252 return MakeResult<bool>(false); 241 return MakeResult<bool>(false);
@@ -280,8 +269,8 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi
280 auto itr = id_code_map.find(id_code); 269 auto itr = id_code_map.find(id_code);
281 if (itr == id_code_map.end()) { 270 if (itr == id_code_map.end()) {
282 // TODO: Verify error against hardware 271 // TODO: Verify error against hardware
283 return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, 272 return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound,
284 ErrorSummary::NotFound, ErrorLevel::Permanent); 273 ErrorLevel::Permanent);
285 } 274 }
286 275
287 CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path)); 276 CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path));
@@ -303,19 +292,22 @@ ResultCode CloseArchive(ArchiveHandle handle) {
303 292
304// TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in 293// TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in
305// http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 294// http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22
306ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code) { 295ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory,
296 ArchiveIdCode id_code) {
307 auto result = id_code_map.emplace(id_code, std::move(factory)); 297 auto result = id_code_map.emplace(id_code, std::move(factory));
308 298
309 bool inserted = result.second; 299 bool inserted = result.second;
310 ASSERT_MSG(inserted, "Tried to register more than one archive with same id code"); 300 ASSERT_MSG(inserted, "Tried to register more than one archive with same id code");
311 301
312 auto& archive = result.first->second; 302 auto& archive = result.first->second;
313 LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), id_code); 303 LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(),
304 id_code);
314 return RESULT_SUCCESS; 305 return RESULT_SUCCESS;
315} 306}
316 307
317ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, 308ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle,
318 const FileSys::Path& path, const FileSys::Mode mode) { 309 const FileSys::Path& path,
310 const FileSys::Mode mode) {
319 ArchiveBackend* archive = GetArchive(archive_handle); 311 ArchiveBackend* archive = GetArchive(archive_handle);
320 if (archive == nullptr) 312 if (archive == nullptr)
321 return ERR_INVALID_ARCHIVE_HANDLE; 313 return ERR_INVALID_ARCHIVE_HANDLE;
@@ -336,8 +328,10 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa
336 return archive->DeleteFile(path); 328 return archive->DeleteFile(path);
337} 329}
338 330
339ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, 331ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle,
340 ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { 332 const FileSys::Path& src_path,
333 ArchiveHandle dest_archive_handle,
334 const FileSys::Path& dest_path) {
341 ArchiveBackend* src_archive = GetArchive(src_archive_handle); 335 ArchiveBackend* src_archive = GetArchive(src_archive_handle);
342 ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); 336 ArchiveBackend* dest_archive = GetArchive(dest_archive_handle);
343 if (src_archive == nullptr || dest_archive == nullptr) 337 if (src_archive == nullptr || dest_archive == nullptr)
@@ -368,7 +362,8 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
368 ErrorSummary::Canceled, ErrorLevel::Status); 362 ErrorSummary::Canceled, ErrorLevel::Status);
369} 363}
370 364
371ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size) { 365ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path,
366 u64 file_size) {
372 ArchiveBackend* archive = GetArchive(archive_handle); 367 ArchiveBackend* archive = GetArchive(archive_handle);
373 if (archive == nullptr) 368 if (archive == nullptr)
374 return ERR_INVALID_ARCHIVE_HANDLE; 369 return ERR_INVALID_ARCHIVE_HANDLE;
@@ -387,8 +382,10 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
387 ErrorSummary::Canceled, ErrorLevel::Status); 382 ErrorSummary::Canceled, ErrorLevel::Status);
388} 383}
389 384
390ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, 385ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle,
391 ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { 386 const FileSys::Path& src_path,
387 ArchiveHandle dest_archive_handle,
388 const FileSys::Path& dest_path) {
392 ArchiveBackend* src_archive = GetArchive(src_archive_handle); 389 ArchiveBackend* src_archive = GetArchive(src_archive_handle);
393 ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); 390 ArchiveBackend* dest_archive = GetArchive(dest_archive_handle);
394 if (src_archive == nullptr || dest_archive == nullptr) 391 if (src_archive == nullptr || dest_archive == nullptr)
@@ -409,15 +406,15 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons
409} 406}
410 407
411ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, 408ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle,
412 const FileSys::Path& path) { 409 const FileSys::Path& path) {
413 ArchiveBackend* archive = GetArchive(archive_handle); 410 ArchiveBackend* archive = GetArchive(archive_handle);
414 if (archive == nullptr) 411 if (archive == nullptr)
415 return ERR_INVALID_ARCHIVE_HANDLE; 412 return ERR_INVALID_ARCHIVE_HANDLE;
416 413
417 std::unique_ptr<FileSys::DirectoryBackend> backend = archive->OpenDirectory(path); 414 std::unique_ptr<FileSys::DirectoryBackend> backend = archive->OpenDirectory(path);
418 if (backend == nullptr) { 415 if (backend == nullptr) {
419 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, 416 return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound,
420 ErrorSummary::NotFound, ErrorLevel::Permanent); 417 ErrorLevel::Permanent);
421 } 418 }
422 419
423 auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path)); 420 auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path));
@@ -431,7 +428,8 @@ ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle) {
431 return MakeResult<u64>(archive->GetFreeBytes()); 428 return MakeResult<u64>(archive->GetFreeBytes());
432} 429}
433 430
434ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path) { 431ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info,
432 const FileSys::Path& path) {
435 auto archive_itr = id_code_map.find(id_code); 433 auto archive_itr = id_code_map.find(id_code);
436 if (archive_itr == id_code_map.end()) { 434 if (archive_itr == id_code_map.end()) {
437 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error 435 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
@@ -440,7 +438,8 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo
440 return archive_itr->second->Format(path, format_info); 438 return archive_itr->second->Format(path, format_info);
441} 439}
442 440
443ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path) { 441ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code,
442 FileSys::Path& archive_path) {
444 auto archive = id_code_map.find(id_code); 443 auto archive = id_code_map.find(id_code);
445 if (archive == id_code_map.end()) { 444 if (archive == id_code_map.end()) {
446 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error 445 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
@@ -449,11 +448,14 @@ ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code
449 return archive->second->GetFormatInfo(archive_path); 448 return archive->second->GetFormatInfo(archive_path);
450} 449}
451 450
452ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) { 451ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer,
452 u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) {
453 // Construct the binary path to the archive first 453 // Construct the binary path to the archive first
454 FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); 454 FileSys::Path path =
455 FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low);
455 456
456 auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData : ArchiveIdCode::ExtSaveData); 457 auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData
458 : ArchiveIdCode::ExtSaveData);
457 459
458 if (archive == id_code_map.end()) { 460 if (archive == id_code_map.end()) {
459 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error 461 return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
@@ -476,7 +478,8 @@ ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon
476 478
477ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { 479ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) {
478 // Construct the binary path to the archive first 480 // Construct the binary path to the archive first
479 FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); 481 FileSys::Path path =
482 FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low);
480 483
481 std::string media_type_directory; 484 std::string media_type_directory;
482 if (media_type == MediaType::NAND) { 485 if (media_type == MediaType::NAND) {
@@ -489,7 +492,8 @@ ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) {
489 } 492 }
490 493
491 // Delete all directories (/user, /boss) and the icon file. 494 // Delete all directories (/user, /boss) and the icon file.
492 std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); 495 std::string base_path =
496 FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND);
493 std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path); 497 std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path);
494 if (FileUtil::Exists(extsavedata_path) && !FileUtil::DeleteDirRecursively(extsavedata_path)) 498 if (FileUtil::Exists(extsavedata_path) && !FileUtil::DeleteDirRecursively(extsavedata_path))
495 return ResultCode(-1); // TODO(Subv): Find the right error code 499 return ResultCode(-1); // TODO(Subv): Find the right error code
@@ -530,30 +534,36 @@ void RegisterArchiveTypes() {
530 if (sdmc_factory->Initialize()) 534 if (sdmc_factory->Initialize())
531 RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC); 535 RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC);
532 else 536 else
533 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); 537 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s",
538 sdmc_directory.c_str());
534 539
535 // Create the SaveData archive 540 // Create the SaveData archive
536 auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); 541 auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory);
537 RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); 542 RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData);
538 543
539 auto extsavedata_factory = std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false); 544 auto extsavedata_factory =
545 std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false);
540 if (extsavedata_factory->Initialize()) 546 if (extsavedata_factory->Initialize())
541 RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData); 547 RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData);
542 else 548 else
543 LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_factory->GetMountPoint().c_str()); 549 LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s",
550 extsavedata_factory->GetMountPoint().c_str());
544 551
545 auto sharedextsavedata_factory = std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true); 552 auto sharedextsavedata_factory =
553 std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true);
546 if (sharedextsavedata_factory->Initialize()) 554 if (sharedextsavedata_factory->Initialize())
547 RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData); 555 RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData);
548 else 556 else
549 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", 557 LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
550 sharedextsavedata_factory->GetMountPoint().c_str()); 558 sharedextsavedata_factory->GetMountPoint().c_str());
551 559
552 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive 560 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
553 auto savedatacheck_factory = std::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); 561 auto savedatacheck_factory =
562 std::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory);
554 RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck); 563 RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck);
555 564
556 auto systemsavedata_factory = std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); 565 auto systemsavedata_factory =
566 std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory);
557 RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData); 567 RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData);
558} 568}
559 569
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index f7a50a3a7..533be34a4 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -6,9 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/file_sys/archive_backend.h" 10#include "core/file_sys/archive_backend.h"
13#include "core/hle/kernel/session.h" 11#include "core/hle/kernel/session.h"
14#include "core/hle/result.h" 12#include "core/hle/result.h"
@@ -28,21 +26,18 @@ namespace FS {
28 26
29/// Supported archive types 27/// Supported archive types
30enum class ArchiveIdCode : u32 { 28enum class ArchiveIdCode : u32 {
31 RomFS = 0x00000003, 29 RomFS = 0x00000003,
32 SaveData = 0x00000004, 30 SaveData = 0x00000004,
33 ExtSaveData = 0x00000006, 31 ExtSaveData = 0x00000006,
34 SharedExtSaveData = 0x00000007, 32 SharedExtSaveData = 0x00000007,
35 SystemSaveData = 0x00000008, 33 SystemSaveData = 0x00000008,
36 SDMC = 0x00000009, 34 SDMC = 0x00000009,
37 SDMCWriteOnly = 0x0000000A, 35 SDMCWriteOnly = 0x0000000A,
38 SaveDataCheck = 0x2345678A, 36 SaveDataCheck = 0x2345678A,
39}; 37};
40 38
41/// Media types for the archives 39/// Media types for the archives
42enum class MediaType : u32 { 40enum class MediaType : u32 { NAND = 0, SDMC = 1 };
43 NAND = 0,
44 SDMC = 1
45};
46 41
47typedef u64 ArchiveHandle; 42typedef u64 ArchiveHandle;
48 43
@@ -51,11 +46,13 @@ public:
51 File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); 46 File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path);
52 ~File(); 47 ~File();
53 48
54 std::string GetName() const override { return "Path: " + path.DebugStr(); } 49 std::string GetName() const override {
50 return "Path: " + path.DebugStr();
51 }
55 ResultVal<bool> SyncRequest() override; 52 ResultVal<bool> SyncRequest() override;
56 53
57 FileSys::Path path; ///< Path of the file 54 FileSys::Path path; ///< Path of the file
58 u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means 55 u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
59 std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface 56 std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
60}; 57};
61 58
@@ -64,10 +61,12 @@ public:
64 Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); 61 Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path);
65 ~Directory(); 62 ~Directory();
66 63
67 std::string GetName() const override { return "Directory: " + path.DebugStr(); } 64 std::string GetName() const override {
65 return "Directory: " + path.DebugStr();
66 }
68 ResultVal<bool> SyncRequest() override; 67 ResultVal<bool> SyncRequest() override;
69 68
70 FileSys::Path path; ///< Path of the directory 69 FileSys::Path path; ///< Path of the directory
71 std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface 70 std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface
72}; 71};
73 72
@@ -90,7 +89,8 @@ ResultCode CloseArchive(ArchiveHandle handle);
90 * @param factory File system backend interface to the archive 89 * @param factory File system backend interface to the archive
91 * @param id_code Id code used to access this type of archive 90 * @param id_code Id code used to access this type of archive
92 */ 91 */
93ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code); 92ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory,
93 ArchiveIdCode id_code);
94 94
95/** 95/**
96 * Open a File from an Archive 96 * Open a File from an Archive
@@ -100,7 +100,8 @@ ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factor
100 * @return The opened File object as a Session 100 * @return The opened File object as a Session
101 */ 101 */
102ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, 102ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle,
103 const FileSys::Path& path, const FileSys::Mode mode); 103 const FileSys::Path& path,
104 const FileSys::Mode mode);
104 105
105/** 106/**
106 * Delete a File from an Archive 107 * Delete a File from an Archive
@@ -118,8 +119,10 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa
118 * @param dest_path Path to the File inside of the destination Archive 119 * @param dest_path Path to the File inside of the destination Archive
119 * @return Whether rename succeeded 120 * @return Whether rename succeeded
120 */ 121 */
121ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, 122ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle,
122 ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path); 123 const FileSys::Path& src_path,
124 ArchiveHandle dest_archive_handle,
125 const FileSys::Path& dest_path);
123 126
124/** 127/**
125 * Delete a Directory from an Archive 128 * Delete a Directory from an Archive
@@ -136,7 +139,8 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
136 * @param file_size The size of the new file, filled with zeroes 139 * @param file_size The size of the new file, filled with zeroes
137 * @return File creation result code 140 * @return File creation result code
138 */ 141 */
139ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size); 142ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path,
143 u64 file_size);
140 144
141/** 145/**
142 * Create a Directory from an Archive 146 * Create a Directory from an Archive
@@ -154,8 +158,10 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
154 * @param dest_path Path to the Directory inside of the destination Archive 158 * @param dest_path Path to the Directory inside of the destination Archive
155 * @return Whether rename succeeded 159 * @return Whether rename succeeded
156 */ 160 */
157ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, 161ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle,
158 ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path); 162 const FileSys::Path& src_path,
163 ArchiveHandle dest_archive_handle,
164 const FileSys::Path& dest_path);
159 165
160/** 166/**
161 * Open a Directory from an Archive 167 * Open a Directory from an Archive
@@ -164,7 +170,7 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons
164 * @return The opened Directory object as a Session 170 * @return The opened Directory object as a Session
165 */ 171 */
166ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, 172ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle,
167 const FileSys::Path& path); 173 const FileSys::Path& path);
168 174
169/** 175/**
170 * Get the free space in an Archive 176 * Get the free space in an Archive
@@ -181,7 +187,8 @@ ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle);
181 * @param path The path to the archive, if relevant. 187 * @param path The path to the archive, if relevant.
182 * @return ResultCode 0 on success or the corresponding code on error 188 * @return ResultCode 0 on success or the corresponding code on error
183 */ 189 */
184ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path = FileSys::Path()); 190ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info,
191 const FileSys::Path& path = FileSys::Path());
185 192
186/** 193/**
187 * Retrieves the format info about the archive of the specified type and path. 194 * Retrieves the format info about the archive of the specified type and path.
@@ -190,7 +197,8 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo
190 * @param archive_path The path of the archive, if relevant 197 * @param archive_path The path of the archive, if relevant
191 * @return The format info of the archive, or the corresponding error code if failed. 198 * @return The format info of the archive, or the corresponding error code if failed.
192 */ 199 */
193ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path); 200ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code,
201 FileSys::Path& archive_path);
194 202
195/** 203/**
196 * Creates a blank SharedExtSaveData archive for the specified extdata ID 204 * Creates a blank SharedExtSaveData archive for the specified extdata ID
@@ -202,7 +210,8 @@ ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code
202 * @param format_info Format information about the new archive 210 * @param format_info Format information about the new archive
203 * @return ResultCode 0 on success or the corresponding code on error 211 * @return ResultCode 0 on success or the corresponding code on error
204 */ 212 */
205ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info); 213ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer,
214 u32 icon_size, const FileSys::ArchiveFormatInfo& format_info);
206 215
207/** 216/**
208 * Deletes the SharedExtSaveData archive for the specified extdata ID 217 * Deletes the SharedExtSaveData archive for the specified extdata ID
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index 937868747..94f053dc2 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -8,7 +8,6 @@
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/scope_exit.h" 9#include "common/scope_exit.h"
10#include "common/string_util.h" 10#include "common/string_util.h"
11
12#include "core/hle/result.h" 11#include "core/hle/result.h"
13#include "core/hle/service/fs/archive.h" 12#include "core/hle/service/fs/archive.h"
14#include "core/hle/service/fs/fs_user.h" 13#include "core/hle/service/fs/fs_user.h"
@@ -57,14 +56,16 @@ static void OpenFile(Service::Interface* self) {
57 u32* cmd_buff = Kernel::GetCommandBuffer(); 56 u32* cmd_buff = Kernel::GetCommandBuffer();
58 57
59 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); 58 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
60 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 59 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
61 u32 filename_size = cmd_buff[5]; 60 u32 filename_size = cmd_buff[5];
62 FileSys::Mode mode; mode.hex = cmd_buff[6]; 61 FileSys::Mode mode;
63 u32 attributes = cmd_buff[7]; // TODO(Link Mauve): do something with those attributes. 62 mode.hex = cmd_buff[6];
64 u32 filename_ptr = cmd_buff[9]; 63 u32 attributes = cmd_buff[7]; // TODO(Link Mauve): do something with those attributes.
64 u32 filename_ptr = cmd_buff[9];
65 FileSys::Path file_path(filename_type, filename_size, filename_ptr); 65 FileSys::Path file_path(filename_type, filename_size, filename_ptr);
66 66
67 LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); 67 LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex,
68 attributes);
68 69
69 ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); 70 ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(archive_handle, file_path, mode);
70 cmd_buff[1] = file_res.Code().raw; 71 cmd_buff[1] = file_res.Code().raw;
@@ -98,24 +99,27 @@ static void OpenFile(Service::Interface* self) {
98static void OpenFileDirectly(Service::Interface* self) { 99static void OpenFileDirectly(Service::Interface* self) {
99 u32* cmd_buff = Kernel::GetCommandBuffer(); 100 u32* cmd_buff = Kernel::GetCommandBuffer();
100 101
101 auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[2]); 102 auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[2]);
102 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]); 103 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]);
103 u32 archivename_size = cmd_buff[4]; 104 u32 archivename_size = cmd_buff[4];
104 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[5]); 105 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[5]);
105 u32 filename_size = cmd_buff[6]; 106 u32 filename_size = cmd_buff[6];
106 FileSys::Mode mode; mode.hex = cmd_buff[7]; 107 FileSys::Mode mode;
107 u32 attributes = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes. 108 mode.hex = cmd_buff[7];
108 u32 archivename_ptr = cmd_buff[10]; 109 u32 attributes = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes.
109 u32 filename_ptr = cmd_buff[12]; 110 u32 archivename_ptr = cmd_buff[10];
111 u32 filename_ptr = cmd_buff[12];
110 FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); 112 FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr);
111 FileSys::Path file_path(filename_type, filename_size, filename_ptr); 113 FileSys::Path file_path(filename_type, filename_size, filename_ptr);
112 114
113 LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s file_path=%s, mode=%u attributes=%d", 115 LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s file_path=%s, mode=%u attributes=%d",
114 archive_id, archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes); 116 archive_id, archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex,
117 attributes);
115 118
116 ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path); 119 ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path);
117 if (archive_handle.Failed()) { 120 if (archive_handle.Failed()) {
118 LOG_ERROR(Service_FS, "failed to get a handle for archive archive_id=0x%08X archive_path=%s", 121 LOG_ERROR(Service_FS,
122 "failed to get a handle for archive archive_id=0x%08X archive_path=%s",
119 archive_id, archive_path.DebugStr().c_str()); 123 archive_id, archive_path.DebugStr().c_str());
120 cmd_buff[1] = archive_handle.Code().raw; 124 cmd_buff[1] = archive_handle.Code().raw;
121 cmd_buff[3] = 0; 125 cmd_buff[3] = 0;
@@ -149,14 +153,14 @@ static void DeleteFile(Service::Interface* self) {
149 u32* cmd_buff = Kernel::GetCommandBuffer(); 153 u32* cmd_buff = Kernel::GetCommandBuffer();
150 154
151 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); 155 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
152 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 156 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
153 u32 filename_size = cmd_buff[5]; 157 u32 filename_size = cmd_buff[5];
154 u32 filename_ptr = cmd_buff[7]; 158 u32 filename_ptr = cmd_buff[7];
155 159
156 FileSys::Path file_path(filename_type, filename_size, filename_ptr); 160 FileSys::Path file_path(filename_type, filename_size, filename_ptr);
157 161
158 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", 162 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", filename_type, filename_size,
159 filename_type, filename_size, file_path.DebugStr().c_str()); 163 file_path.DebugStr().c_str());
160 164
161 cmd_buff[1] = DeleteFileFromArchive(archive_handle, file_path).raw; 165 cmd_buff[1] = DeleteFileFromArchive(archive_handle, file_path).raw;
162} 166}
@@ -181,22 +185,26 @@ static void RenameFile(Service::Interface* self) {
181 u32* cmd_buff = Kernel::GetCommandBuffer(); 185 u32* cmd_buff = Kernel::GetCommandBuffer();
182 186
183 ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); 187 ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
184 auto src_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 188 auto src_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
185 u32 src_filename_size = cmd_buff[5]; 189 u32 src_filename_size = cmd_buff[5];
186 ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]);; 190 ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]);
187 auto dest_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); 191 ;
188 u32 dest_filename_size = cmd_buff[9]; 192 auto dest_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[8]);
189 u32 src_filename_ptr = cmd_buff[11]; 193 u32 dest_filename_size = cmd_buff[9];
190 u32 dest_filename_ptr = cmd_buff[13]; 194 u32 src_filename_ptr = cmd_buff[11];
195 u32 dest_filename_ptr = cmd_buff[13];
191 196
192 FileSys::Path src_file_path(src_filename_type, src_filename_size, src_filename_ptr); 197 FileSys::Path src_file_path(src_filename_type, src_filename_size, src_filename_ptr);
193 FileSys::Path dest_file_path(dest_filename_type, dest_filename_size, dest_filename_ptr); 198 FileSys::Path dest_file_path(dest_filename_type, dest_filename_size, dest_filename_ptr);
194 199
195 LOG_DEBUG(Service_FS, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", 200 LOG_DEBUG(Service_FS,
201 "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s",
196 src_filename_type, src_filename_size, src_file_path.DebugStr().c_str(), 202 src_filename_type, src_filename_size, src_file_path.DebugStr().c_str(),
197 dest_filename_type, dest_filename_size, dest_file_path.DebugStr().c_str()); 203 dest_filename_type, dest_filename_size, dest_file_path.DebugStr().c_str());
198 204
199 cmd_buff[1] = RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, dest_file_path).raw; 205 cmd_buff[1] = RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle,
206 dest_file_path)
207 .raw;
200} 208}
201 209
202/* 210/*
@@ -214,14 +222,14 @@ static void DeleteDirectory(Service::Interface* self) {
214 u32* cmd_buff = Kernel::GetCommandBuffer(); 222 u32* cmd_buff = Kernel::GetCommandBuffer();
215 223
216 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); 224 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
217 auto dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 225 auto dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
218 u32 dirname_size = cmd_buff[5]; 226 u32 dirname_size = cmd_buff[5];
219 u32 dirname_ptr = cmd_buff[7]; 227 u32 dirname_ptr = cmd_buff[7];
220 228
221 FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); 229 FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr);
222 230
223 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", 231 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size,
224 dirname_type, dirname_size, dir_path.DebugStr().c_str()); 232 dir_path.DebugStr().c_str());
225 233
226 cmd_buff[1] = DeleteDirectoryFromArchive(archive_handle, dir_path).raw; 234 cmd_buff[1] = DeleteDirectoryFromArchive(archive_handle, dir_path).raw;
227} 235}
@@ -243,14 +251,15 @@ static void CreateFile(Service::Interface* self) {
243 u32* cmd_buff = Kernel::GetCommandBuffer(); 251 u32* cmd_buff = Kernel::GetCommandBuffer();
244 252
245 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); 253 ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
246 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 254 auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
247 u32 filename_size = cmd_buff[5]; 255 u32 filename_size = cmd_buff[5];
248 u64 file_size = ((u64)cmd_buff[8] << 32) | cmd_buff[7]; 256 u64 file_size = ((u64)cmd_buff[8] << 32) | cmd_buff[7];
249 u32 filename_ptr = cmd_buff[10]; 257 u32 filename_ptr = cmd_buff[10];
250 258
251 FileSys::Path file_path(filename_type, filename_size, filename_ptr); 259 FileSys::Path file_path(filename_type, filename_size, filename_ptr);
252 260
253 LOG_DEBUG(Service_FS, "type=%d size=%llu data=%s", filename_type, file_size, file_path.DebugStr().c_str()); 261 LOG_DEBUG(Service_FS, "type=%d size=%llu data=%s", filename_type, file_size,
262 file_path.DebugStr().c_str());
254 263
255 cmd_buff[1] = CreateFileInArchive(archive_handle, file_path, file_size).raw; 264 cmd_buff[1] = CreateFileInArchive(archive_handle, file_path, file_size).raw;
256} 265}
@@ -276,7 +285,8 @@ static void CreateDirectory(Service::Interface* self) {
276 285
277 FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); 286 FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr);
278 287
279 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); 288 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size,
289 dir_path.DebugStr().c_str());
280 290
281 cmd_buff[1] = CreateDirectoryFromArchive(archive_handle, dir_path).raw; 291 cmd_buff[1] = CreateDirectoryFromArchive(archive_handle, dir_path).raw;
282} 292}
@@ -301,22 +311,25 @@ static void RenameDirectory(Service::Interface* self) {
301 u32* cmd_buff = Kernel::GetCommandBuffer(); 311 u32* cmd_buff = Kernel::GetCommandBuffer();
302 312
303 ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); 313 ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]);
304 auto src_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); 314 auto src_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]);
305 u32 src_dirname_size = cmd_buff[5]; 315 u32 src_dirname_size = cmd_buff[5];
306 ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]); 316 ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]);
307 auto dest_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); 317 auto dest_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[8]);
308 u32 dest_dirname_size = cmd_buff[9]; 318 u32 dest_dirname_size = cmd_buff[9];
309 u32 src_dirname_ptr = cmd_buff[11]; 319 u32 src_dirname_ptr = cmd_buff[11];
310 u32 dest_dirname_ptr = cmd_buff[13]; 320 u32 dest_dirname_ptr = cmd_buff[13];
311 321
312 FileSys::Path src_dir_path(src_dirname_type, src_dirname_size, src_dirname_ptr); 322 FileSys::Path src_dir_path(src_dirname_type, src_dirname_size, src_dirname_ptr);
313 FileSys::Path dest_dir_path(dest_dirname_type, dest_dirname_size, dest_dirname_ptr); 323 FileSys::Path dest_dir_path(dest_dirname_type, dest_dirname_size, dest_dirname_ptr);
314 324
315 LOG_DEBUG(Service_FS, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", 325 LOG_DEBUG(Service_FS,
326 "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s",
316 src_dirname_type, src_dirname_size, src_dir_path.DebugStr().c_str(), 327 src_dirname_type, src_dirname_size, src_dir_path.DebugStr().c_str(),
317 dest_dirname_type, dest_dirname_size, dest_dir_path.DebugStr().c_str()); 328 dest_dirname_type, dest_dirname_size, dest_dir_path.DebugStr().c_str());
318 329
319 cmd_buff[1] = RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw; 330 cmd_buff[1] = RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path,
331 dest_archive_handle, dest_dir_path)
332 .raw;
320} 333}
321 334
322/** 335/**
@@ -342,7 +355,8 @@ static void OpenDirectory(Service::Interface* self) {
342 355
343 FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); 356 FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr);
344 357
345 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); 358 LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size,
359 dir_path.DebugStr().c_str());
346 360
347 ResultVal<SharedPtr<Directory>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); 361 ResultVal<SharedPtr<Directory>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path);
348 cmd_buff[1] = dir_res.Code().raw; 362 cmd_buff[1] = dir_res.Code().raw;
@@ -370,13 +384,14 @@ static void OpenDirectory(Service::Interface* self) {
370static void OpenArchive(Service::Interface* self) { 384static void OpenArchive(Service::Interface* self) {
371 u32* cmd_buff = Kernel::GetCommandBuffer(); 385 u32* cmd_buff = Kernel::GetCommandBuffer();
372 386
373 auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[1]); 387 auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[1]);
374 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]); 388 auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]);
375 u32 archivename_size = cmd_buff[3]; 389 u32 archivename_size = cmd_buff[3];
376 u32 archivename_ptr = cmd_buff[5]; 390 u32 archivename_ptr = cmd_buff[5];
377 FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); 391 FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr);
378 392
379 LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s", archive_id, archive_path.DebugStr().c_str()); 393 LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s", archive_id,
394 archive_path.DebugStr().c_str());
380 395
381 ResultVal<ArchiveHandle> handle = OpenArchive(archive_id, archive_path); 396 ResultVal<ArchiveHandle> handle = OpenArchive(archive_id, archive_path);
382 cmd_buff[1] = handle.Code().raw; 397 cmd_buff[1] = handle.Code().raw;
@@ -385,7 +400,8 @@ static void OpenArchive(Service::Interface* self) {
385 cmd_buff[3] = (*handle >> 32) & 0xFFFFFFFF; 400 cmd_buff[3] = (*handle >> 32) & 0xFFFFFFFF;
386 } else { 401 } else {
387 cmd_buff[2] = cmd_buff[3] = 0; 402 cmd_buff[2] = cmd_buff[3] = 0;
388 LOG_ERROR(Service_FS, "failed to get a handle for archive archive_id=0x%08X archive_path=%s", 403 LOG_ERROR(Service_FS,
404 "failed to get a handle for archive archive_id=0x%08X archive_path=%s",
389 archive_id, archive_path.DebugStr().c_str()); 405 archive_id, archive_path.DebugStr().c_str());
390 } 406 }
391} 407}
@@ -471,7 +487,8 @@ static void FormatSaveData(Service::Interface* self) {
471 if (archive_id != FS::ArchiveIdCode::SaveData) { 487 if (archive_id != FS::ArchiveIdCode::SaveData) {
472 LOG_ERROR(Service_FS, "tried to format an archive different than SaveData, %u", archive_id); 488 LOG_ERROR(Service_FS, "tried to format an archive different than SaveData, %u", archive_id);
473 cmd_buff[1] = ResultCode(ErrorDescription::FS_InvalidPath, ErrorModule::FS, 489 cmd_buff[1] = ResultCode(ErrorDescription::FS_InvalidPath, ErrorModule::FS,
474 ErrorSummary::InvalidArgument, ErrorLevel::Usage).raw; 490 ErrorSummary::InvalidArgument, ErrorLevel::Usage)
491 .raw;
475 return; 492 return;
476 } 493 }
477 494
@@ -571,18 +588,21 @@ static void CreateExtSaveData(Service::Interface* self) {
571 u32 icon_size = cmd_buff[9]; 588 u32 icon_size = cmd_buff[9];
572 VAddr icon_buffer = cmd_buff[11]; 589 VAddr icon_buffer = cmd_buff[11];
573 590
574 LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " 591 LOG_WARNING(
575 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " 592 Service_FS,
576 "icon_size=%08X icon_descriptor=%08X icon_buffer=%08X", save_high, save_low, 593 "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
577 cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], cmd_buff[8], icon_size, 594 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
578 cmd_buff[10], icon_buffer); 595 "icon_size=%08X icon_descriptor=%08X icon_buffer=%08X",
596 save_high, save_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7],
597 cmd_buff[8], icon_size, cmd_buff[10], icon_buffer);
579 598
580 FileSys::ArchiveFormatInfo format_info; 599 FileSys::ArchiveFormatInfo format_info;
581 format_info.number_directories = cmd_buff[5]; 600 format_info.number_directories = cmd_buff[5];
582 format_info.number_files = cmd_buff[6]; 601 format_info.number_files = cmd_buff[6];
583 format_info.duplicate_data = false; 602 format_info.duplicate_data = false;
584 format_info.total_size = 0; 603 format_info.total_size = 0;
585 cmd_buff[1] = CreateExtSaveData(media_type, save_high, save_low, icon_buffer, icon_size, format_info).raw; 604 cmd_buff[1] =
605 CreateExtSaveData(media_type, save_high, save_low, icon_buffer, icon_size, format_info).raw;
586} 606}
587 607
588/** 608/**
@@ -604,7 +624,7 @@ static void DeleteExtSaveData(Service::Interface* self) {
604 u32 unknown = cmd_buff[4]; // TODO(Subv): Figure out what this is 624 u32 unknown = cmd_buff[4]; // TODO(Subv): Figure out what this is
605 625
606 LOG_WARNING(Service_FS, "(STUBBED) save_low=%08X save_high=%08X media_type=%08X unknown=%08X", 626 LOG_WARNING(Service_FS, "(STUBBED) save_low=%08X save_high=%08X media_type=%08X unknown=%08X",
607 save_low, save_high, cmd_buff[1] & 0xFF, unknown); 627 save_low, save_high, cmd_buff[1] & 0xFF, unknown);
608 628
609 cmd_buff[1] = DeleteExtSaveData(media_type, save_high, save_low).raw; 629 cmd_buff[1] = DeleteExtSaveData(media_type, save_high, save_low).raw;
610} 630}
@@ -662,10 +682,13 @@ static void CreateSystemSaveData(Service::Interface* self) {
662 u32 savedata_high = cmd_buff[1]; 682 u32 savedata_high = cmd_buff[1];
663 u32 savedata_low = cmd_buff[2]; 683 u32 savedata_low = cmd_buff[2];
664 684
665 LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " 685 LOG_WARNING(
666 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " 686 Service_FS,
667 "cmd_buff[9]=%08X", savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], 687 "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X "
668 cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9]); 688 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
689 "cmd_buff[9]=%08X",
690 savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6],
691 cmd_buff[7], cmd_buff[8], cmd_buff[9]);
669 692
670 cmd_buff[1] = CreateSystemSaveData(savedata_high, savedata_low).raw; 693 cmd_buff[1] = CreateSystemSaveData(savedata_high, savedata_low).raw;
671} 694}
@@ -692,10 +715,13 @@ static void CreateLegacySystemSaveData(Service::Interface* self) {
692 u32* cmd_buff = Kernel::GetCommandBuffer(); 715 u32* cmd_buff = Kernel::GetCommandBuffer();
693 u32 savedata_id = cmd_buff[1]; 716 u32 savedata_id = cmd_buff[1];
694 717
695 LOG_WARNING(Service_FS, "(STUBBED) savedata_id=%08X cmd_buff[3]=%08X " 718 LOG_WARNING(
696 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " 719 Service_FS,
697 "cmd_buff[9]=%08X", savedata_id, cmd_buff[3], cmd_buff[4], cmd_buff[5], 720 "(STUBBED) savedata_id=%08X cmd_buff[3]=%08X "
698 cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9]); 721 "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X "
722 "cmd_buff[9]=%08X",
723 savedata_id, cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], cmd_buff[8],
724 cmd_buff[9]);
699 725
700 cmd_buff[0] = IPC::MakeHeader(0x810, 0x1, 0); 726 cmd_buff[0] = IPC::MakeHeader(0x810, 0x1, 0);
701 // With this command, the SystemSaveData always has save_high = 0 (Always created in the NAND) 727 // With this command, the SystemSaveData always has save_high = 0 (Always created in the NAND)
@@ -721,8 +747,8 @@ static void InitializeWithSdkVersion(Service::Interface* self) {
721 747
722 cmd_buff[1] = RESULT_SUCCESS.raw; 748 cmd_buff[1] = RESULT_SUCCESS.raw;
723 749
724 LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X", 750 LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X", unk1, unk2,
725 unk1, unk2, unk3); 751 unk3);
726} 752}
727 753
728/** 754/**
@@ -834,114 +860,114 @@ static void GetFormatInfo(Service::Interface* self) {
834} 860}
835 861
836const Interface::FunctionInfo FunctionTable[] = { 862const Interface::FunctionInfo FunctionTable[] = {
837 {0x000100C6, nullptr, "Dummy1"}, 863 {0x000100C6, nullptr, "Dummy1"},
838 {0x040100C4, nullptr, "Control"}, 864 {0x040100C4, nullptr, "Control"},
839 {0x08010002, Initialize, "Initialize"}, 865 {0x08010002, Initialize, "Initialize"},
840 {0x080201C2, OpenFile, "OpenFile"}, 866 {0x080201C2, OpenFile, "OpenFile"},
841 {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, 867 {0x08030204, OpenFileDirectly, "OpenFileDirectly"},
842 {0x08040142, DeleteFile, "DeleteFile"}, 868 {0x08040142, DeleteFile, "DeleteFile"},
843 {0x08050244, RenameFile, "RenameFile"}, 869 {0x08050244, RenameFile, "RenameFile"},
844 {0x08060142, DeleteDirectory, "DeleteDirectory"}, 870 {0x08060142, DeleteDirectory, "DeleteDirectory"},
845 {0x08070142, nullptr, "DeleteDirectoryRecursively"}, 871 {0x08070142, nullptr, "DeleteDirectoryRecursively"},
846 {0x08080202, CreateFile, "CreateFile"}, 872 {0x08080202, CreateFile, "CreateFile"},
847 {0x08090182, CreateDirectory, "CreateDirectory"}, 873 {0x08090182, CreateDirectory, "CreateDirectory"},
848 {0x080A0244, RenameDirectory, "RenameDirectory"}, 874 {0x080A0244, RenameDirectory, "RenameDirectory"},
849 {0x080B0102, OpenDirectory, "OpenDirectory"}, 875 {0x080B0102, OpenDirectory, "OpenDirectory"},
850 {0x080C00C2, OpenArchive, "OpenArchive"}, 876 {0x080C00C2, OpenArchive, "OpenArchive"},
851 {0x080D0144, nullptr, "ControlArchive"}, 877 {0x080D0144, nullptr, "ControlArchive"},
852 {0x080E0080, CloseArchive, "CloseArchive"}, 878 {0x080E0080, CloseArchive, "CloseArchive"},
853 {0x080F0180, FormatThisUserSaveData, "FormatThisUserSaveData"}, 879 {0x080F0180, FormatThisUserSaveData, "FormatThisUserSaveData"},
854 {0x08100200, CreateLegacySystemSaveData, "CreateLegacySystemSaveData"}, 880 {0x08100200, CreateLegacySystemSaveData, "CreateLegacySystemSaveData"},
855 {0x08110040, nullptr, "DeleteSystemSaveData"}, 881 {0x08110040, nullptr, "DeleteSystemSaveData"},
856 {0x08120080, GetFreeBytes, "GetFreeBytes"}, 882 {0x08120080, GetFreeBytes, "GetFreeBytes"},
857 {0x08130000, nullptr, "GetCardType"}, 883 {0x08130000, nullptr, "GetCardType"},
858 {0x08140000, nullptr, "GetSdmcArchiveResource"}, 884 {0x08140000, nullptr, "GetSdmcArchiveResource"},
859 {0x08150000, nullptr, "GetNandArchiveResource"}, 885 {0x08150000, nullptr, "GetNandArchiveResource"},
860 {0x08160000, nullptr, "GetSdmcFatfsError"}, 886 {0x08160000, nullptr, "GetSdmcFatfsError"},
861 {0x08170000, IsSdmcDetected, "IsSdmcDetected"}, 887 {0x08170000, IsSdmcDetected, "IsSdmcDetected"},
862 {0x08180000, IsSdmcWriteable, "IsSdmcWritable"}, 888 {0x08180000, IsSdmcWriteable, "IsSdmcWritable"},
863 {0x08190042, nullptr, "GetSdmcCid"}, 889 {0x08190042, nullptr, "GetSdmcCid"},
864 {0x081A0042, nullptr, "GetNandCid"}, 890 {0x081A0042, nullptr, "GetNandCid"},
865 {0x081B0000, nullptr, "GetSdmcSpeedInfo"}, 891 {0x081B0000, nullptr, "GetSdmcSpeedInfo"},
866 {0x081C0000, nullptr, "GetNandSpeedInfo"}, 892 {0x081C0000, nullptr, "GetNandSpeedInfo"},
867 {0x081D0042, nullptr, "GetSdmcLog"}, 893 {0x081D0042, nullptr, "GetSdmcLog"},
868 {0x081E0042, nullptr, "GetNandLog"}, 894 {0x081E0042, nullptr, "GetNandLog"},
869 {0x081F0000, nullptr, "ClearSdmcLog"}, 895 {0x081F0000, nullptr, "ClearSdmcLog"},
870 {0x08200000, nullptr, "ClearNandLog"}, 896 {0x08200000, nullptr, "ClearNandLog"},
871 {0x08210000, CardSlotIsInserted, "CardSlotIsInserted"}, 897 {0x08210000, CardSlotIsInserted, "CardSlotIsInserted"},
872 {0x08220000, nullptr, "CardSlotPowerOn"}, 898 {0x08220000, nullptr, "CardSlotPowerOn"},
873 {0x08230000, nullptr, "CardSlotPowerOff"}, 899 {0x08230000, nullptr, "CardSlotPowerOff"},
874 {0x08240000, nullptr, "CardSlotGetCardIFPowerStatus"}, 900 {0x08240000, nullptr, "CardSlotGetCardIFPowerStatus"},
875 {0x08250040, nullptr, "CardNorDirectCommand"}, 901 {0x08250040, nullptr, "CardNorDirectCommand"},
876 {0x08260080, nullptr, "CardNorDirectCommandWithAddress"}, 902 {0x08260080, nullptr, "CardNorDirectCommandWithAddress"},
877 {0x08270082, nullptr, "CardNorDirectRead"}, 903 {0x08270082, nullptr, "CardNorDirectRead"},
878 {0x082800C2, nullptr, "CardNorDirectReadWithAddress"}, 904 {0x082800C2, nullptr, "CardNorDirectReadWithAddress"},
879 {0x08290082, nullptr, "CardNorDirectWrite"}, 905 {0x08290082, nullptr, "CardNorDirectWrite"},
880 {0x082A00C2, nullptr, "CardNorDirectWriteWithAddress"}, 906 {0x082A00C2, nullptr, "CardNorDirectWriteWithAddress"},
881 {0x082B00C2, nullptr, "CardNorDirectRead_4xIO"}, 907 {0x082B00C2, nullptr, "CardNorDirectRead_4xIO"},
882 {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"}, 908 {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"},
883 {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"}, 909 {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"},
884 {0x082E0040, nullptr, "GetProductInfo"}, 910 {0x082E0040, nullptr, "GetProductInfo"},
885 {0x082F0040, nullptr, "GetProgramLaunchInfo"}, 911 {0x082F0040, nullptr, "GetProgramLaunchInfo"},
886 {0x08300182, nullptr, "CreateExtSaveData"}, 912 {0x08300182, nullptr, "CreateExtSaveData"},
887 {0x08310180, nullptr, "CreateSharedExtSaveData"}, 913 {0x08310180, nullptr, "CreateSharedExtSaveData"},
888 {0x08320102, nullptr, "ReadExtSaveDataIcon"}, 914 {0x08320102, nullptr, "ReadExtSaveDataIcon"},
889 {0x08330082, nullptr, "EnumerateExtSaveData"}, 915 {0x08330082, nullptr, "EnumerateExtSaveData"},
890 {0x08340082, nullptr, "EnumerateSharedExtSaveData"}, 916 {0x08340082, nullptr, "EnumerateSharedExtSaveData"},
891 {0x08350080, nullptr, "DeleteExtSaveData"}, 917 {0x08350080, nullptr, "DeleteExtSaveData"},
892 {0x08360080, nullptr, "DeleteSharedExtSaveData"}, 918 {0x08360080, nullptr, "DeleteSharedExtSaveData"},
893 {0x08370040, nullptr, "SetCardSpiBaudRate"}, 919 {0x08370040, nullptr, "SetCardSpiBaudRate"},
894 {0x08380040, nullptr, "SetCardSpiBusMode"}, 920 {0x08380040, nullptr, "SetCardSpiBusMode"},
895 {0x08390000, nullptr, "SendInitializeInfoTo9"}, 921 {0x08390000, nullptr, "SendInitializeInfoTo9"},
896 {0x083A0100, nullptr, "GetSpecialContentIndex"}, 922 {0x083A0100, nullptr, "GetSpecialContentIndex"},
897 {0x083B00C2, nullptr, "GetLegacyRomHeader"}, 923 {0x083B00C2, nullptr, "GetLegacyRomHeader"},
898 {0x083C00C2, nullptr, "GetLegacyBannerData"}, 924 {0x083C00C2, nullptr, "GetLegacyBannerData"},
899 {0x083D0100, nullptr, "CheckAuthorityToAccessExtSaveData"}, 925 {0x083D0100, nullptr, "CheckAuthorityToAccessExtSaveData"},
900 {0x083E00C2, nullptr, "QueryTotalQuotaSize"}, 926 {0x083E00C2, nullptr, "QueryTotalQuotaSize"},
901 {0x083F00C0, nullptr, "GetExtDataBlockSize"}, 927 {0x083F00C0, nullptr, "GetExtDataBlockSize"},
902 {0x08400040, nullptr, "AbnegateAccessRight"}, 928 {0x08400040, nullptr, "AbnegateAccessRight"},
903 {0x08410000, nullptr, "DeleteSdmcRoot"}, 929 {0x08410000, nullptr, "DeleteSdmcRoot"},
904 {0x08420040, nullptr, "DeleteAllExtSaveDataOnNand"}, 930 {0x08420040, nullptr, "DeleteAllExtSaveDataOnNand"},
905 {0x08430000, nullptr, "InitializeCtrFileSystem"}, 931 {0x08430000, nullptr, "InitializeCtrFileSystem"},
906 {0x08440000, nullptr, "CreateSeed"}, 932 {0x08440000, nullptr, "CreateSeed"},
907 {0x084500C2, GetFormatInfo, "GetFormatInfo"}, 933 {0x084500C2, GetFormatInfo, "GetFormatInfo"},
908 {0x08460102, nullptr, "GetLegacyRomHeader2"}, 934 {0x08460102, nullptr, "GetLegacyRomHeader2"},
909 {0x08470180, nullptr, "FormatCtrCardUserSaveData"}, 935 {0x08470180, nullptr, "FormatCtrCardUserSaveData"},
910 {0x08480042, nullptr, "GetSdmcCtrRootPath"}, 936 {0x08480042, nullptr, "GetSdmcCtrRootPath"},
911 {0x08490040, GetArchiveResource, "GetArchiveResource"}, 937 {0x08490040, GetArchiveResource, "GetArchiveResource"},
912 {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"}, 938 {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"},
913 {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"}, 939 {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"},
914 {0x084C0242, FormatSaveData, "FormatSaveData"}, 940 {0x084C0242, FormatSaveData, "FormatSaveData"},
915 {0x084D0102, nullptr, "GetLegacySubBannerData"}, 941 {0x084D0102, nullptr, "GetLegacySubBannerData"},
916 {0x084E0342, nullptr, "UpdateSha256Context"}, 942 {0x084E0342, nullptr, "UpdateSha256Context"},
917 {0x084F0102, nullptr, "ReadSpecialFile"}, 943 {0x084F0102, nullptr, "ReadSpecialFile"},
918 {0x08500040, nullptr, "GetSpecialFileSize"}, 944 {0x08500040, nullptr, "GetSpecialFileSize"},
919 {0x08510242, CreateExtSaveData, "CreateExtSaveData"}, 945 {0x08510242, CreateExtSaveData, "CreateExtSaveData"},
920 {0x08520100, DeleteExtSaveData, "DeleteExtSaveData"}, 946 {0x08520100, DeleteExtSaveData, "DeleteExtSaveData"},
921 {0x08530142, nullptr, "ReadExtSaveDataIcon"}, 947 {0x08530142, nullptr, "ReadExtSaveDataIcon"},
922 {0x085400C0, nullptr, "GetExtDataBlockSize"}, 948 {0x085400C0, nullptr, "GetExtDataBlockSize"},
923 {0x08550102, nullptr, "EnumerateExtSaveData"}, 949 {0x08550102, nullptr, "EnumerateExtSaveData"},
924 {0x08560240, CreateSystemSaveData, "CreateSystemSaveData"}, 950 {0x08560240, CreateSystemSaveData, "CreateSystemSaveData"},
925 {0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"}, 951 {0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"},
926 {0x08580000, nullptr, "StartDeviceMoveAsSource"}, 952 {0x08580000, nullptr, "StartDeviceMoveAsSource"},
927 {0x08590200, nullptr, "StartDeviceMoveAsDestination"}, 953 {0x08590200, nullptr, "StartDeviceMoveAsDestination"},
928 {0x085A00C0, nullptr, "SetArchivePriority"}, 954 {0x085A00C0, nullptr, "SetArchivePriority"},
929 {0x085B0080, nullptr, "GetArchivePriority"}, 955 {0x085B0080, nullptr, "GetArchivePriority"},
930 {0x085C00C0, nullptr, "SetCtrCardLatencyParameter"}, 956 {0x085C00C0, nullptr, "SetCtrCardLatencyParameter"},
931 {0x085D01C0, nullptr, "SetFsCompatibilityInfo"}, 957 {0x085D01C0, nullptr, "SetFsCompatibilityInfo"},
932 {0x085E0040, nullptr, "ResetCardCompatibilityParameter"}, 958 {0x085E0040, nullptr, "ResetCardCompatibilityParameter"},
933 {0x085F0040, nullptr, "SwitchCleanupInvalidSaveData"}, 959 {0x085F0040, nullptr, "SwitchCleanupInvalidSaveData"},
934 {0x08600042, nullptr, "EnumerateSystemSaveData"}, 960 {0x08600042, nullptr, "EnumerateSystemSaveData"},
935 {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"}, 961 {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"},
936 {0x08620040, SetPriority, "SetPriority"}, 962 {0x08620040, SetPriority, "SetPriority"},
937 {0x08630000, GetPriority, "GetPriority"}, 963 {0x08630000, GetPriority, "GetPriority"},
938 {0x08640000, nullptr, "GetNandInfo"}, 964 {0x08640000, nullptr, "GetNandInfo"},
939 {0x08650140, nullptr, "SetSaveDataSecureValue"}, 965 {0x08650140, nullptr, "SetSaveDataSecureValue"},
940 {0x086600C0, nullptr, "GetSaveDataSecureValue"}, 966 {0x086600C0, nullptr, "GetSaveDataSecureValue"},
941 {0x086700C4, nullptr, "ControlSecureSave"}, 967 {0x086700C4, nullptr, "ControlSecureSave"},
942 {0x08680000, nullptr, "GetMediaType"}, 968 {0x08680000, nullptr, "GetMediaType"},
943 {0x08690000, nullptr, "GetNandEraseCount"}, 969 {0x08690000, nullptr, "GetNandEraseCount"},
944 {0x086A0082, nullptr, "ReadNandReport"} 970 {0x086A0082, nullptr, "ReadNandReport"},
945}; 971};
946 972
947//////////////////////////////////////////////////////////////////////////////////////////////////// 973////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index ec565f46d..710e0e485 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -4,19 +4,16 @@
4 4
5#include "common/bit_field.h" 5#include "common/bit_field.h"
6#include "common/microprofile.h" 6#include "common/microprofile.h"
7
8#include "core/memory.h"
9#include "core/hle/kernel/event.h" 7#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/shared_memory.h" 8#include "core/hle/kernel/shared_memory.h"
11#include "core/hle/result.h" 9#include "core/hle/result.h"
12#include "core/hw/hw.h"
13#include "core/hw/gpu.h" 10#include "core/hw/gpu.h"
11#include "core/hw/hw.h"
14#include "core/hw/lcd.h" 12#include "core/hw/lcd.h"
15 13#include "core/memory.h"
16#include "video_core/gpu_debugger.h"
17#include "video_core/debug_utils/debug_utils.h"
18
19#include "gsp_gpu.h" 14#include "gsp_gpu.h"
15#include "video_core/debug_utils/debug_utils.h"
16#include "video_core/gpu_debugger.h"
20 17
21// Main graphics debugger object - TODO: Here is probably not the best place for this 18// Main graphics debugger object - TODO: Here is probably not the best place for this
22GraphicsDebugger g_debugger; 19GraphicsDebugger g_debugger;
@@ -29,12 +26,15 @@ const static u32 REGS_BEGIN = 0x1EB00000;
29 26
30namespace GSP_GPU { 27namespace GSP_GPU {
31 28
32const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED(ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, 29const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED(
33 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02A01 30 ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, ErrorSummary::InvalidArgument,
31 ErrorLevel::Usage); // 0xE0E02A01
34const ResultCode ERR_GSP_REGS_MISALIGNED(ErrorDescription::MisalignedSize, ErrorModule::GX, 32const ResultCode ERR_GSP_REGS_MISALIGNED(ErrorDescription::MisalignedSize, ErrorModule::GX,
35 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02BF2 33 ErrorSummary::InvalidArgument,
34 ErrorLevel::Usage); // 0xE0E02BF2
36const ResultCode ERR_GSP_REGS_INVALID_SIZE(ErrorDescription::InvalidSize, ErrorModule::GX, 35const ResultCode ERR_GSP_REGS_INVALID_SIZE(ErrorDescription::InvalidSize, ErrorModule::GX,
37 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02BEC 36 ErrorSummary::InvalidArgument,
37 ErrorLevel::Usage); // 0xE0E02BEC
38 38
39/// Event triggered when GSP interrupt has been signalled 39/// Event triggered when GSP interrupt has been signalled
40Kernel::SharedPtr<Kernel::Event> g_interrupt_event; 40Kernel::SharedPtr<Kernel::Event> g_interrupt_event;
@@ -73,7 +73,8 @@ static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) {
73 * @param data Data to be written 73 * @param data Data to be written
74 */ 74 */
75static void WriteSingleHWReg(u32 base_address, u32 data) { 75static void WriteSingleHWReg(u32 base_address, u32 data) {
76 DEBUG_ASSERT_MSG((base_address & 3) == 0 && base_address < 0x420000, "Write address out of range or misaligned"); 76 DEBUG_ASSERT_MSG((base_address & 3) == 0 && base_address < 0x420000,
77 "Write address out of range or misaligned");
77 HW::Write<u32>(base_address + REGS_BEGIN, data); 78 HW::Write<u32>(base_address + REGS_BEGIN, data);
78} 79}
79 80
@@ -90,7 +91,8 @@ static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, VAddr data_va
90 const u32 max_size_in_bytes = 0x80; 91 const u32 max_size_in_bytes = 0x80;
91 92
92 if (base_address & 3 || base_address >= 0x420000) { 93 if (base_address & 3 || base_address >= 0x420000) {
93 LOG_ERROR(Service_GSP, "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)", 94 LOG_ERROR(Service_GSP,
95 "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)",
94 base_address, size_in_bytes); 96 base_address, size_in_bytes);
95 return ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED; 97 return ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED;
96 } else if (size_in_bytes <= max_size_in_bytes) { 98 } else if (size_in_bytes <= max_size_in_bytes) {
@@ -124,12 +126,14 @@ static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, VAddr data_va
124 * @param masks A pointer to the masks 126 * @param masks A pointer to the masks
125 * @return RESULT_SUCCESS if the parameters are valid, error code otherwise 127 * @return RESULT_SUCCESS if the parameters are valid, error code otherwise
126 */ 128 */
127static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr data_vaddr, VAddr masks_vaddr) { 129static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr data_vaddr,
130 VAddr masks_vaddr) {
128 // This magic number is verified to be done by the gsp module 131 // This magic number is verified to be done by the gsp module
129 const u32 max_size_in_bytes = 0x80; 132 const u32 max_size_in_bytes = 0x80;
130 133
131 if (base_address & 3 || base_address >= 0x420000) { 134 if (base_address & 3 || base_address >= 0x420000) {
132 LOG_ERROR(Service_GSP, "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)", 135 LOG_ERROR(Service_GSP,
136 "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)",
133 base_address, size_in_bytes); 137 base_address, size_in_bytes);
134 return ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED; 138 return ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED;
135 } else if (size_in_bytes <= max_size_in_bytes) { 139 } else if (size_in_bytes <= max_size_in_bytes) {
@@ -214,7 +218,8 @@ static void ReadHWRegs(Service::Interface* self) {
214 218
215 // TODO: Return proper error codes 219 // TODO: Return proper error codes
216 if (reg_addr + size >= 0x420000) { 220 if (reg_addr + size >= 0x420000) {
217 LOG_ERROR(Service_GSP, "Read address out of range! (address=0x%08x, size=0x%08x)", reg_addr, size); 221 LOG_ERROR(Service_GSP, "Read address out of range! (address=0x%08x, size=0x%08x)", reg_addr,
222 size);
218 return; 223 return;
219 } 224 }
220 225
@@ -243,22 +248,34 @@ ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
243 PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left); 248 PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left);
244 PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right); 249 PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right);
245 if (info.active_fb == 0) { 250 if (info.active_fb == 0) {
246 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), 251 WriteSingleHWReg(
247 phys_address_left); 252 base_address +
248 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), 253 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)),
249 phys_address_right); 254 phys_address_left);
255 WriteSingleHWReg(
256 base_address +
257 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)),
258 phys_address_right);
250 } else { 259 } else {
251 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), 260 WriteSingleHWReg(
252 phys_address_left); 261 base_address +
253 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), 262 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)),
254 phys_address_right); 263 phys_address_left);
264 WriteSingleHWReg(
265 base_address +
266 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)),
267 phys_address_right);
255 } 268 }
256 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), 269 WriteSingleHWReg(base_address +
270 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)),
257 info.stride); 271 info.stride);
258 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)), 272 WriteSingleHWReg(
259 info.format); 273 base_address +
260 WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), 274 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)),
261 info.shown_fb); 275 info.format);
276 WriteSingleHWReg(
277 base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)),
278 info.shown_fb);
262 279
263 if (Pica::g_debug_context) 280 if (Pica::g_debug_context)
264 Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); 281 Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr);
@@ -305,15 +322,15 @@ static void SetBufferSwap(Service::Interface* self) {
305static void FlushDataCache(Service::Interface* self) { 322static void FlushDataCache(Service::Interface* self) {
306 u32* cmd_buff = Kernel::GetCommandBuffer(); 323 u32* cmd_buff = Kernel::GetCommandBuffer();
307 u32 address = cmd_buff[1]; 324 u32 address = cmd_buff[1];
308 u32 size = cmd_buff[2]; 325 u32 size = cmd_buff[2];
309 u32 process = cmd_buff[4]; 326 u32 process = cmd_buff[4];
310 327
311 // TODO(purpasmart96): Verify return header on HW 328 // TODO(purpasmart96): Verify return header on HW
312 329
313 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 330 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
314 331
315 LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X", 332 LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X", address,
316 address, size, process); 333 size, process);
317} 334}
318 335
319/** 336/**
@@ -356,11 +373,12 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
356 // This specific code is required for a successful initialization, rather than 0 373 // This specific code is required for a successful initialization, rather than 0
357 first_initialization = false; 374 first_initialization = false;
358 cmd_buff[1] = ResultCode(ErrorDescription::GPU_FirstInitialization, ErrorModule::GX, 375 cmd_buff[1] = ResultCode(ErrorDescription::GPU_FirstInitialization, ErrorModule::GX,
359 ErrorSummary::Success, ErrorLevel::Success).raw; 376 ErrorSummary::Success, ErrorLevel::Success)
377 .raw;
360 } else { 378 } else {
361 cmd_buff[1] = RESULT_SUCCESS.raw; 379 cmd_buff[1] = RESULT_SUCCESS.raw;
362 } 380 }
363 cmd_buff[2] = g_thread_id++; // Thread ID 381 cmd_buff[2] = g_thread_id++; // Thread ID
364 cmd_buff[4] = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); // GSP shared memory 382 cmd_buff[4] = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); // GSP shared memory
365 383
366 g_interrupt_event->Signal(); // TODO(bunnei): Is this correct? 384 g_interrupt_event->Signal(); // TODO(bunnei): Is this correct?
@@ -416,7 +434,8 @@ void SignalInterrupt(InterruptId interrupt_id) {
416 // Update framebuffer information if requested 434 // Update framebuffer information if requested
417 // TODO(yuriks): Confirm where this code should be called. It is definitely updated without 435 // TODO(yuriks): Confirm where this code should be called. It is definitely updated without
418 // executing any GSP commands, only waiting on the event. 436 // executing any GSP commands, only waiting on the event.
419 int screen_id = (interrupt_id == InterruptId::PDC0) ? 0 : (interrupt_id == InterruptId::PDC1) ? 1 : -1; 437 int screen_id =
438 (interrupt_id == InterruptId::PDC0) ? 0 : (interrupt_id == InterruptId::PDC1) ? 1 : -1;
420 if (screen_id != -1) { 439 if (screen_id != -1) {
421 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); 440 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
422 if (info->is_dirty) { 441 if (info->is_dirty) {
@@ -440,25 +459,27 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
440 switch (command.id) { 459 switch (command.id) {
441 460
442 // GX request DMA - typically used for copying memory from GSP heap to VRAM 461 // GX request DMA - typically used for copying memory from GSP heap to VRAM
443 case CommandId::REQUEST_DMA: 462 case CommandId::REQUEST_DMA: {
444 {
445 MICROPROFILE_SCOPE(GPU_GSP_DMA); 463 MICROPROFILE_SCOPE(GPU_GSP_DMA);
446 464
447 // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever possible/likely 465 // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever
448 Memory::RasterizerFlushRegion(Memory::VirtualToPhysicalAddress(command.dma_request.source_address), 466 // possible/likely
449 command.dma_request.size); 467 Memory::RasterizerFlushRegion(
450 Memory::RasterizerFlushAndInvalidateRegion(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), 468 Memory::VirtualToPhysicalAddress(command.dma_request.source_address),
451 command.dma_request.size); 469 command.dma_request.size);
470 Memory::RasterizerFlushAndInvalidateRegion(
471 Memory::VirtualToPhysicalAddress(command.dma_request.dest_address),
472 command.dma_request.size);
452 473
453 // TODO(Subv): These memory accesses should not go through the application's memory mapping. 474 // TODO(Subv): These memory accesses should not go through the application's memory mapping.
454 // They should go through the GSP module's memory mapping. 475 // They should go through the GSP module's memory mapping.
455 Memory::CopyBlock(command.dma_request.dest_address, command.dma_request.source_address, command.dma_request.size); 476 Memory::CopyBlock(command.dma_request.dest_address, command.dma_request.source_address,
477 command.dma_request.size);
456 SignalInterrupt(InterruptId::DMA); 478 SignalInterrupt(InterruptId::DMA);
457 break; 479 break;
458 } 480 }
459 // TODO: This will need some rework in the future. (why?) 481 // TODO: This will need some rework in the future. (why?)
460 case CommandId::SUBMIT_GPU_CMDLIST: 482 case CommandId::SUBMIT_GPU_CMDLIST: {
461 {
462 auto& params = command.submit_gpu_cmdlist; 483 auto& params = command.submit_gpu_cmdlist;
463 484
464 if (params.do_flush) { 485 if (params.do_flush) {
@@ -468,10 +489,12 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
468 } 489 }
469 490
470 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), 491 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)),
471 Memory::VirtualToPhysicalAddress(params.address) >> 3); 492 Memory::VirtualToPhysicalAddress(params.address) >> 3);
472 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.size)), params.size); 493 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.size)),
494 params.size);
473 495
474 // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though 496 // TODO: Not sure if we are supposed to always write this .. seems to trigger processing
497 // though
475 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1); 498 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1);
476 499
477 // TODO(yuriks): Figure out the meaning of the `flags` field. 500 // TODO(yuriks): Figure out the meaning of the `flags` field.
@@ -481,67 +504,70 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
481 504
482 // It's assumed that the two "blocks" behave equivalently. 505 // It's assumed that the two "blocks" behave equivalently.
483 // Presumably this is done simply to allow two memory fills to run in parallel. 506 // Presumably this is done simply to allow two memory fills to run in parallel.
484 case CommandId::SET_MEMORY_FILL: 507 case CommandId::SET_MEMORY_FILL: {
485 {
486 auto& params = command.memory_fill; 508 auto& params = command.memory_fill;
487 509
488 if (params.start1 != 0) { 510 if (params.start1 != 0) {
489 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)), 511 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)),
490 Memory::VirtualToPhysicalAddress(params.start1) >> 3); 512 Memory::VirtualToPhysicalAddress(params.start1) >> 3);
491 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)), 513 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)),
492 Memory::VirtualToPhysicalAddress(params.end1) >> 3); 514 Memory::VirtualToPhysicalAddress(params.end1) >> 3);
493 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), params.value1); 515 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)),
494 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), params.control1); 516 params.value1);
517 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)),
518 params.control1);
495 } 519 }
496 520
497 if (params.start2 != 0) { 521 if (params.start2 != 0) {
498 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)), 522 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)),
499 Memory::VirtualToPhysicalAddress(params.start2) >> 3); 523 Memory::VirtualToPhysicalAddress(params.start2) >> 3);
500 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)), 524 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)),
501 Memory::VirtualToPhysicalAddress(params.end2) >> 3); 525 Memory::VirtualToPhysicalAddress(params.end2) >> 3);
502 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), params.value2); 526 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)),
503 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), params.control2); 527 params.value2);
528 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)),
529 params.control2);
504 } 530 }
505 break; 531 break;
506 } 532 }
507 533
508 case CommandId::SET_DISPLAY_TRANSFER: 534 case CommandId::SET_DISPLAY_TRANSFER: {
509 {
510 auto& params = command.display_transfer; 535 auto& params = command.display_transfer;
511 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_address)), 536 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_address)),
512 Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); 537 Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3);
513 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_address)), 538 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_address)),
514 Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); 539 Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3);
515 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_size)), params.in_buffer_size); 540 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_size)),
516 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_size)), params.out_buffer_size); 541 params.in_buffer_size);
517 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.flags)), params.flags); 542 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_size)),
543 params.out_buffer_size);
544 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.flags)),
545 params.flags);
518 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.trigger)), 1); 546 WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.trigger)), 1);
519 break; 547 break;
520 } 548 }
521 549
522 case CommandId::SET_TEXTURE_COPY: 550 case CommandId::SET_TEXTURE_COPY: {
523 {
524 auto& params = command.texture_copy; 551 auto& params = command.texture_copy;
525 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.input_address), 552 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.input_address),
526 Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); 553 Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3);
527 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.output_address), 554 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.output_address),
528 Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); 555 Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3);
529 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.size), 556 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.size),
530 params.size); 557 params.size);
531 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.input_size), 558 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.input_size),
532 params.in_width_gap); 559 params.in_width_gap);
533 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.output_size), 560 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.output_size),
534 params.out_width_gap); 561 params.out_width_gap);
535 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.flags), 562 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.flags), params.flags);
536 params.flags);
537 563
538 // NOTE: Actual GSP ORs 1 with current register instead of overwriting. Doesn't seem to matter. 564 // NOTE: Actual GSP ORs 1 with current register instead of overwriting. Doesn't seem to
565 // matter.
539 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.trigger), 1); 566 WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.trigger), 1);
540 break; 567 break;
541 } 568 }
542 569
543 case CommandId::CACHE_FLUSH: 570 case CommandId::CACHE_FLUSH: {
544 {
545 // NOTE: Rasterizer flushing handled elsewhere in CPU read/write and other GPU handlers 571 // NOTE: Rasterizer flushing handled elsewhere in CPU read/write and other GPU handlers
546 // Use command.cache_flush.regions to implement this handler 572 // Use command.cache_flush.regions to implement this handler
547 break; 573 break;
@@ -552,7 +578,8 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
552 } 578 }
553 579
554 if (Pica::g_debug_context) 580 if (Pica::g_debug_context)
555 Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, (void*)&command); 581 Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed,
582 (void*)&command);
556} 583}
557 584
558/** 585/**
@@ -575,7 +602,7 @@ static void SetLcdForceBlack(Service::Interface* self) {
575 // the color to black (all zero). 602 // the color to black (all zero).
576 data.is_enabled.Assign(enable_black); 603 data.is_enabled.Assign(enable_black);
577 604
578 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD 605 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD
579 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD 606 LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD
580 607
581 cmd_buff[1] = RESULT_SUCCESS.raw; 608 cmd_buff[1] = RESULT_SUCCESS.raw;
@@ -679,37 +706,37 @@ static void ReleaseRight(Service::Interface* self) {
679} 706}
680 707
681const Interface::FunctionInfo FunctionTable[] = { 708const Interface::FunctionInfo FunctionTable[] = {
682 {0x00010082, WriteHWRegs, "WriteHWRegs"}, 709 {0x00010082, WriteHWRegs, "WriteHWRegs"},
683 {0x00020084, WriteHWRegsWithMask, "WriteHWRegsWithMask"}, 710 {0x00020084, WriteHWRegsWithMask, "WriteHWRegsWithMask"},
684 {0x00030082, nullptr, "WriteHWRegRepeat"}, 711 {0x00030082, nullptr, "WriteHWRegRepeat"},
685 {0x00040080, ReadHWRegs, "ReadHWRegs"}, 712 {0x00040080, ReadHWRegs, "ReadHWRegs"},
686 {0x00050200, SetBufferSwap, "SetBufferSwap"}, 713 {0x00050200, SetBufferSwap, "SetBufferSwap"},
687 {0x00060082, nullptr, "SetCommandList"}, 714 {0x00060082, nullptr, "SetCommandList"},
688 {0x000700C2, nullptr, "RequestDma"}, 715 {0x000700C2, nullptr, "RequestDma"},
689 {0x00080082, FlushDataCache, "FlushDataCache"}, 716 {0x00080082, FlushDataCache, "FlushDataCache"},
690 {0x00090082, nullptr, "InvalidateDataCache"}, 717 {0x00090082, nullptr, "InvalidateDataCache"},
691 {0x000A0044, nullptr, "RegisterInterruptEvents"}, 718 {0x000A0044, nullptr, "RegisterInterruptEvents"},
692 {0x000B0040, SetLcdForceBlack, "SetLcdForceBlack"}, 719 {0x000B0040, SetLcdForceBlack, "SetLcdForceBlack"},
693 {0x000C0000, TriggerCmdReqQueue, "TriggerCmdReqQueue"}, 720 {0x000C0000, TriggerCmdReqQueue, "TriggerCmdReqQueue"},
694 {0x000D0140, nullptr, "SetDisplayTransfer"}, 721 {0x000D0140, nullptr, "SetDisplayTransfer"},
695 {0x000E0180, nullptr, "SetTextureCopy"}, 722 {0x000E0180, nullptr, "SetTextureCopy"},
696 {0x000F0200, nullptr, "SetMemoryFill"}, 723 {0x000F0200, nullptr, "SetMemoryFill"},
697 {0x00100040, SetAxiConfigQoSMode, "SetAxiConfigQoSMode"}, 724 {0x00100040, SetAxiConfigQoSMode, "SetAxiConfigQoSMode"},
698 {0x00110040, nullptr, "SetPerfLogMode"}, 725 {0x00110040, nullptr, "SetPerfLogMode"},
699 {0x00120000, nullptr, "GetPerfLog"}, 726 {0x00120000, nullptr, "GetPerfLog"},
700 {0x00130042, RegisterInterruptRelayQueue, "RegisterInterruptRelayQueue"}, 727 {0x00130042, RegisterInterruptRelayQueue, "RegisterInterruptRelayQueue"},
701 {0x00140000, UnregisterInterruptRelayQueue, "UnregisterInterruptRelayQueue"}, 728 {0x00140000, UnregisterInterruptRelayQueue, "UnregisterInterruptRelayQueue"},
702 {0x00150002, nullptr, "TryAcquireRight"}, 729 {0x00150002, nullptr, "TryAcquireRight"},
703 {0x00160042, AcquireRight, "AcquireRight"}, 730 {0x00160042, AcquireRight, "AcquireRight"},
704 {0x00170000, ReleaseRight, "ReleaseRight"}, 731 {0x00170000, ReleaseRight, "ReleaseRight"},
705 {0x00180000, ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"}, 732 {0x00180000, ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"},
706 {0x00190000, nullptr, "SaveVramSysArea"}, 733 {0x00190000, nullptr, "SaveVramSysArea"},
707 {0x001A0000, nullptr, "RestoreVramSysArea"}, 734 {0x001A0000, nullptr, "RestoreVramSysArea"},
708 {0x001B0000, nullptr, "ResetGpuCore"}, 735 {0x001B0000, nullptr, "ResetGpuCore"},
709 {0x001C0040, nullptr, "SetLedForceOff"}, 736 {0x001C0040, nullptr, "SetLedForceOff"},
710 {0x001D0040, nullptr, "SetTestCommand"}, 737 {0x001D0040, nullptr, "SetTestCommand"},
711 {0x001E0080, nullptr, "SetInternalPriorities"}, 738 {0x001E0080, nullptr, "SetInternalPriorities"},
712 {0x001F0082, nullptr, "StoreDataCache"}, 739 {0x001F0082, nullptr, "StoreDataCache"},
713}; 740};
714 741
715//////////////////////////////////////////////////////////////////////////////////////////////////// 742////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -721,9 +748,9 @@ Interface::Interface() {
721 g_interrupt_event = nullptr; 748 g_interrupt_event = nullptr;
722 749
723 using Kernel::MemoryPermission; 750 using Kernel::MemoryPermission;
724 g_shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000, 751 g_shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite,
725 MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, 752 MemoryPermission::ReadWrite, 0,
726 0, Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); 753 Kernel::MemoryRegion::BASE, "GSP:SharedMemory");
727 754
728 g_thread_id = 0; 755 g_thread_id = 0;
729 gpu_right_acquired = false; 756 gpu_right_acquired = false;
diff --git a/src/core/hle/service/gsp_gpu.h b/src/core/hle/service/gsp_gpu.h
index 3b4b678a3..79a72f77d 100644
--- a/src/core/hle/service/gsp_gpu.h
+++ b/src/core/hle/service/gsp_gpu.h
@@ -6,10 +6,8 @@
6 6
7#include <cstddef> 7#include <cstddef>
8#include <string> 8#include <string>
9
10#include "common/bit_field.h" 9#include "common/bit_field.h"
11#include "common/common_types.h" 10#include "common/common_types.h"
12
13#include "core/hle/result.h" 11#include "core/hle/result.h"
14#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
15 13
@@ -20,30 +18,30 @@ namespace GSP_GPU {
20 18
21/// GSP interrupt ID 19/// GSP interrupt ID
22enum class InterruptId : u8 { 20enum class InterruptId : u8 {
23 PSC0 = 0x00, 21 PSC0 = 0x00,
24 PSC1 = 0x01, 22 PSC1 = 0x01,
25 PDC0 = 0x02, // Seems called every vertical screen line 23 PDC0 = 0x02, // Seems called every vertical screen line
26 PDC1 = 0x03, // Seems called every frame 24 PDC1 = 0x03, // Seems called every frame
27 PPF = 0x04, 25 PPF = 0x04,
28 P3D = 0x05, 26 P3D = 0x05,
29 DMA = 0x06, 27 DMA = 0x06,
30}; 28};
31 29
32/// GSP command ID 30/// GSP command ID
33enum class CommandId : u32 { 31enum class CommandId : u32 {
34 REQUEST_DMA = 0x00, 32 REQUEST_DMA = 0x00,
35 /// Submits a commandlist for execution by the GPU. 33 /// Submits a commandlist for execution by the GPU.
36 SUBMIT_GPU_CMDLIST = 0x01, 34 SUBMIT_GPU_CMDLIST = 0x01,
37 35
38 // Fills a given memory range with a particular value 36 // Fills a given memory range with a particular value
39 SET_MEMORY_FILL = 0x02, 37 SET_MEMORY_FILL = 0x02,
40 38
41 // Copies an image and optionally performs color-conversion or scaling. 39 // Copies an image and optionally performs color-conversion or scaling.
42 // This is highly similar to the GameCube's EFB copy feature 40 // This is highly similar to the GameCube's EFB copy feature
43 SET_DISPLAY_TRANSFER = 0x03, 41 SET_DISPLAY_TRANSFER = 0x03,
44 42
45 // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path 43 // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path
46 SET_TEXTURE_COPY = 0x04, 44 SET_TEXTURE_COPY = 0x04,
47 /// Flushes up to 3 cache regions in a single command. 45 /// Flushes up to 3 cache regions in a single command.
48 CACHE_FLUSH = 0x05, 46 CACHE_FLUSH = 0x05,
49}; 47};
@@ -61,19 +59,18 @@ struct InterruptRelayQueue {
61 u32 missed_PDC0; 59 u32 missed_PDC0;
62 u32 missed_PDC1; 60 u32 missed_PDC1;
63 61
64 InterruptId slot[0x34]; ///< Interrupt ID slots 62 InterruptId slot[0x34]; ///< Interrupt ID slots
65}; 63};
66static_assert(sizeof(InterruptRelayQueue) == 0x40, 64static_assert(sizeof(InterruptRelayQueue) == 0x40, "InterruptRelayQueue struct has incorrect size");
67 "InterruptRelayQueue struct has incorrect size");
68 65
69struct FrameBufferInfo { 66struct FrameBufferInfo {
70 BitField<0, 1, u32> active_fb; // 0 = first, 1 = second 67 BitField<0, 1, u32> active_fb; // 0 = first, 1 = second
71 68
72 u32 address_left; 69 u32 address_left;
73 u32 address_right; 70 u32 address_right;
74 u32 stride; // maps to 0x1EF00X90 ? 71 u32 stride; // maps to 0x1EF00X90 ?
75 u32 format; // maps to 0x1EF00X70 ? 72 u32 format; // maps to 0x1EF00X70 ?
76 u32 shown_fb; // maps to 0x1EF00X78 ? 73 u32 shown_fb; // maps to 0x1EF00X78 ?
77 u32 unknown; 74 u32 unknown;
78}; 75};
79static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size"); 76static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size");
@@ -91,7 +88,8 @@ static_assert(sizeof(FrameBufferUpdate) == 0x40, "Struct has incorrect size");
91// TODO: Not sure if this padding is correct. 88// TODO: Not sure if this padding is correct.
92// Chances are the second block is stored at offset 0x24 rather than 0x20. 89// Chances are the second block is stored at offset 0x24 rather than 0x20.
93#ifndef _MSC_VER 90#ifndef _MSC_VER
94static_assert(offsetof(FrameBufferUpdate, framebuffer_info[1]) == 0x20, "FrameBufferInfo element has incorrect alignment"); 91static_assert(offsetof(FrameBufferUpdate, framebuffer_info[1]) == 0x20,
92 "FrameBufferInfo element has incorrect alignment");
95#endif 93#endif
96 94
97/// GSP command 95/// GSP command
@@ -163,13 +161,13 @@ struct CommandBuffer {
163 // Current command index. This index is updated by GSP module after loading the command 161 // Current command index. This index is updated by GSP module after loading the command
164 // data, right before the command is processed. When this index is updated by GSP module, 162 // data, right before the command is processed. When this index is updated by GSP module,
165 // the total commands field is decreased by one as well. 163 // the total commands field is decreased by one as well.
166 BitField<0,8,u32> index; 164 BitField<0, 8, u32> index;
167 165
168 // Total commands to process, must not be value 0 when GSP module handles commands. This 166 // Total commands to process, must not be value 0 when GSP module handles commands. This
169 // must be <=15 when writing a command to shared memory. This is incremented by the 167 // must be <=15 when writing a command to shared memory. This is incremented by the
170 // application when writing a command to shared memory, after increasing this value 168 // application when writing a command to shared memory, after increasing this value
171 // TriggerCmdReqQueue is only used if this field is value 1. 169 // TriggerCmdReqQueue is only used if this field is value 1.
172 BitField<8,8,u32> number_commands; 170 BitField<8, 8, u32> number_commands;
173 }; 171 };
174 172
175 u32 unk[7]; 173 u32 unk[7];
diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp
index c700c21c5..b916dd759 100644
--- a/src/core/hle/service/gsp_lcd.cpp
+++ b/src/core/hle/service/gsp_lcd.cpp
@@ -10,11 +10,13 @@
10namespace GSP_LCD { 10namespace GSP_LCD {
11 11
12const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
13 // clang-format off
13 {0x000F0000, nullptr, "PowerOnAllBacklights"}, 14 {0x000F0000, nullptr, "PowerOnAllBacklights"},
14 {0x00100000, nullptr, "PowerOffAllBacklights"}, 15 {0x00100000, nullptr, "PowerOffAllBacklights"},
15 {0x00110040, nullptr, "PowerOnBacklight"}, 16 {0x00110040, nullptr, "PowerOnBacklight"},
16 {0x00120040, nullptr, "PowerOffBacklight"}, 17 {0x00120040, nullptr, "PowerOffBacklight"},
17 {0x00130040, nullptr, "SetLedForceOff"} 18 {0x00130040, nullptr, "SetLedForceOff"},
19 // clang-format on
18}; 20};
19 21
20//////////////////////////////////////////////////////////////////////////////////////////////////// 22////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index cdec11388..99baded11 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -3,19 +3,15 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cmath> 5#include <cmath>
6
7#include "common/logging/log.h"
8#include "common/emu_window.h" 6#include "common/emu_window.h"
9 7#include "common/logging/log.h"
10#include "core/hle/service/service.h"
11#include "core/hle/service/hid/hid.h"
12#include "core/hle/service/hid/hid_spvr.h"
13#include "core/hle/service/hid/hid_user.h"
14
15#include "core/core_timing.h" 8#include "core/core_timing.h"
16#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
17#include "core/hle/kernel/shared_memory.h" 10#include "core/hle/kernel/shared_memory.h"
18 11#include "core/hle/service/hid/hid.h"
12#include "core/hle/service/hid/hid_spvr.h"
13#include "core/hle/service/hid/hid_user.h"
14#include "core/hle/service/service.h"
19#include "video_core/video_core.h" 15#include "video_core/video_core.h"
20 16
21namespace Service { 17namespace Service {
@@ -37,11 +33,13 @@ static u32 next_accelerometer_index;
37static u32 next_gyroscope_index; 33static u32 next_gyroscope_index;
38 34
39static int enable_accelerometer_count = 0; // positive means enabled 35static int enable_accelerometer_count = 0; // positive means enabled
40static int enable_gyroscope_count = 0; // positive means enabled 36static int enable_gyroscope_count = 0; // positive means enabled
41 37
42static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { 38static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
43 constexpr float TAN30 = 0.577350269, TAN60 = 1 / TAN30; // 30 degree and 60 degree are angular thresholds for directions 39 // 30 degree and 60 degree are angular thresholds for directions
44 constexpr int CIRCLE_PAD_THRESHOLD_SQUARE = 40 * 40; // a circle pad radius greater than 40 will trigger circle pad direction 40 constexpr float TAN30 = 0.577350269, TAN60 = 1 / TAN30;
41 // a circle pad radius greater than 40 will trigger circle pad direction
42 constexpr int CIRCLE_PAD_THRESHOLD_SQUARE = 40 * 40;
45 PadState state; 43 PadState state;
46 state.hex = 0; 44 state.hex = 0;
47 45
@@ -90,7 +88,7 @@ void Update() {
90 PadState old_state = mem->pad.entries[last_entry_index].current_state; 88 PadState old_state = mem->pad.entries[last_entry_index].current_state;
91 89
92 // Compute bitmask with 1s for bits different from the old state 90 // Compute bitmask with 1s for bits different from the old state
93 PadState changed = { { (state.hex ^ old_state.hex) } }; 91 PadState changed = {{(state.hex ^ old_state.hex)}};
94 92
95 // Get the current Pad entry 93 // Get the current Pad entry
96 PadDataEntry& pad_entry = mem->pad.entries[mem->pad.index]; 94 PadDataEntry& pad_entry = mem->pad.entries[mem->pad.index];
@@ -135,11 +133,13 @@ void Update() {
135 // Update accelerometer 133 // Update accelerometer
136 if (enable_accelerometer_count > 0) { 134 if (enable_accelerometer_count > 0) {
137 mem->accelerometer.index = next_accelerometer_index; 135 mem->accelerometer.index = next_accelerometer_index;
138 next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); 136 next_accelerometer_index =
137 (next_accelerometer_index + 1) % mem->accelerometer.entries.size();
139 138
140 AccelerometerDataEntry& accelerometer_entry = mem->accelerometer.entries[mem->accelerometer.index]; 139 AccelerometerDataEntry& accelerometer_entry =
141 std::tie(accelerometer_entry.x, accelerometer_entry.y, accelerometer_entry.z) 140 mem->accelerometer.entries[mem->accelerometer.index];
142 = VideoCore::g_emu_window->GetAccelerometerState(); 141 std::tie(accelerometer_entry.x, accelerometer_entry.y, accelerometer_entry.z) =
142 VideoCore::g_emu_window->GetAccelerometerState();
143 143
144 // Make up "raw" entry 144 // Make up "raw" entry
145 // TODO(wwylele): 145 // TODO(wwylele):
@@ -167,8 +167,8 @@ void Update() {
167 next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size(); 167 next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size();
168 168
169 GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; 169 GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index];
170 std::tie(gyroscope_entry.x, gyroscope_entry.y, gyroscope_entry.z) 170 std::tie(gyroscope_entry.x, gyroscope_entry.y, gyroscope_entry.z) =
171 = VideoCore::g_emu_window->GetGyroscopeState(); 171 VideoCore::g_emu_window->GetGyroscopeState();
172 172
173 // Make up "raw" entry 173 // Make up "raw" entry
174 mem->gyroscope.raw_entry.x = gyroscope_entry.x; 174 mem->gyroscope.raw_entry.x = gyroscope_entry.x;
@@ -188,7 +188,7 @@ void Update() {
188void GetIPCHandles(Service::Interface* self) { 188void GetIPCHandles(Service::Interface* self) {
189 u32* cmd_buff = Kernel::GetCommandBuffer(); 189 u32* cmd_buff = Kernel::GetCommandBuffer();
190 190
191 cmd_buff[1] = 0; // No error 191 cmd_buff[1] = 0; // No error
192 cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header 192 cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header
193 // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) 193 // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
194 cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).MoveFrom(); 194 cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).MoveFrom();
@@ -259,9 +259,7 @@ void GetGyroscopeLowCalibrateParam(Service::Interface* self) {
259 259
260 const s16 param_unit = 6700; // an approximate value taken from hw 260 const s16 param_unit = 6700; // an approximate value taken from hw
261 GyroscopeCalibrateParam param = { 261 GyroscopeCalibrateParam param = {
262 { 0, param_unit, -param_unit }, 262 {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit},
263 { 0, param_unit, -param_unit },
264 { 0, param_unit, -param_unit },
265 }; 263 };
266 memcpy(&cmd_buff[2], &param, sizeof(param)); 264 memcpy(&cmd_buff[2], &param, sizeof(param));
267 265
@@ -286,9 +284,9 @@ void Init() {
286 AddService(new HID_SPVR_Interface); 284 AddService(new HID_SPVR_Interface);
287 285
288 using Kernel::MemoryPermission; 286 using Kernel::MemoryPermission;
289 shared_mem = SharedMemory::Create(nullptr, 0x1000, 287 shared_mem =
290 MemoryPermission::ReadWrite, MemoryPermission::Read, 288 SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read,
291 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); 289 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
292 290
293 next_pad_index = 0; 291 next_pad_index = 0;
294 next_touch_index = 0; 292 next_touch_index = 0;
@@ -296,9 +294,9 @@ void Init() {
296 // Create event handles 294 // Create event handles
297 event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1"); 295 event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1");
298 event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2"); 296 event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2");
299 event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); 297 event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer");
300 event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); 298 event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope");
301 event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); 299 event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad");
302} 300}
303 301
304void Shutdown() { 302void Shutdown() {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 669b1f723..7904e7355 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -5,14 +5,13 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8
9#ifndef _MSC_VER 8#ifndef _MSC_VER
10#include <cstddef> 9#include <cstddef>
11#endif 10#endif
12#include "core/settings.h"
13#include "common/bit_field.h" 11#include "common/bit_field.h"
14#include "common/common_funcs.h" 12#include "common/common_funcs.h"
15#include "common/common_types.h" 13#include "common/common_types.h"
14#include "core/settings.h"
16 15
17namespace Service { 16namespace Service {
18 17
@@ -103,7 +102,7 @@ struct SharedMem {
103 struct { 102 struct {
104 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 103 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
105 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` 104 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
106 u32 index; ///< Index of the last updated pad state entry 105 u32 index; ///< Index of the last updated pad state entry
107 106
108 INSERT_PADDING_WORDS(0x2); 107 INSERT_PADDING_WORDS(0x2);
109 108
@@ -121,7 +120,7 @@ struct SharedMem {
121 struct { 120 struct {
122 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 121 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
123 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` 122 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
124 u32 index; ///< Index of the last updated touch entry 123 u32 index; ///< Index of the last updated touch entry
125 124
126 INSERT_PADDING_WORDS(0x1); 125 INSERT_PADDING_WORDS(0x1);
127 126
@@ -135,7 +134,7 @@ struct SharedMem {
135 struct { 134 struct {
136 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 135 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
137 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` 136 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
138 u32 index; ///< Index of the last updated accelerometer entry 137 u32 index; ///< Index of the last updated accelerometer entry
139 138
140 INSERT_PADDING_WORDS(0x1); 139 INSERT_PADDING_WORDS(0x1);
141 140
@@ -149,7 +148,7 @@ struct SharedMem {
149 struct { 148 struct {
150 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 149 s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0
151 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` 150 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks`
152 u32 index; ///< Index of the last updated accelerometer entry 151 u32 index; ///< Index of the last updated accelerometer entry
153 152
154 INSERT_PADDING_WORDS(0x1); 153 INSERT_PADDING_WORDS(0x1);
155 154
@@ -176,9 +175,9 @@ struct GyroscopeCalibrateParam {
176// is technically allowed since C++11. This macro should be enabled once MSVC adds 175// is technically allowed since C++11. This macro should be enabled once MSVC adds
177// support for that. 176// support for that.
178#ifndef _MSC_VER 177#ifndef _MSC_VER
179#define ASSERT_REG_POSITION(field_name, position) \ 178#define ASSERT_REG_POSITION(field_name, position) \
180 static_assert(offsetof(SharedMem, field_name) == position * 4, \ 179 static_assert(offsetof(SharedMem, field_name) == position * 4, \
181 "Field "#field_name" has invalid position") 180 "Field " #field_name " has invalid position")
182 181
183ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0); 182ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0);
184ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A); 183ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A);
@@ -187,33 +186,33 @@ ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A);
187#endif // !defined(_MSC_VER) 186#endif // !defined(_MSC_VER)
188 187
189// Pre-defined PadStates for single button presses 188// Pre-defined PadStates for single button presses
190const PadState PAD_NONE = {{0}}; 189const PadState PAD_NONE = {{0}};
191const PadState PAD_A = {{1u << 0}}; 190const PadState PAD_A = {{1u << 0}};
192const PadState PAD_B = {{1u << 1}}; 191const PadState PAD_B = {{1u << 1}};
193const PadState PAD_SELECT = {{1u << 2}}; 192const PadState PAD_SELECT = {{1u << 2}};
194const PadState PAD_START = {{1u << 3}}; 193const PadState PAD_START = {{1u << 3}};
195const PadState PAD_RIGHT = {{1u << 4}}; 194const PadState PAD_RIGHT = {{1u << 4}};
196const PadState PAD_LEFT = {{1u << 5}}; 195const PadState PAD_LEFT = {{1u << 5}};
197const PadState PAD_UP = {{1u << 6}}; 196const PadState PAD_UP = {{1u << 6}};
198const PadState PAD_DOWN = {{1u << 7}}; 197const PadState PAD_DOWN = {{1u << 7}};
199const PadState PAD_R = {{1u << 8}}; 198const PadState PAD_R = {{1u << 8}};
200const PadState PAD_L = {{1u << 9}}; 199const PadState PAD_L = {{1u << 9}};
201const PadState PAD_X = {{1u << 10}}; 200const PadState PAD_X = {{1u << 10}};
202const PadState PAD_Y = {{1u << 11}}; 201const PadState PAD_Y = {{1u << 11}};
203 202
204const PadState PAD_ZL = {{1u << 14}}; 203const PadState PAD_ZL = {{1u << 14}};
205const PadState PAD_ZR = {{1u << 15}}; 204const PadState PAD_ZR = {{1u << 15}};
206 205
207const PadState PAD_TOUCH = {{1u << 20}}; 206const PadState PAD_TOUCH = {{1u << 20}};
208 207
209const PadState PAD_C_RIGHT = {{1u << 24}}; 208const PadState PAD_C_RIGHT = {{1u << 24}};
210const PadState PAD_C_LEFT = {{1u << 25}}; 209const PadState PAD_C_LEFT = {{1u << 25}};
211const PadState PAD_C_UP = {{1u << 26}}; 210const PadState PAD_C_UP = {{1u << 26}};
212const PadState PAD_C_DOWN = {{1u << 27}}; 211const PadState PAD_C_DOWN = {{1u << 27}};
213const PadState PAD_CIRCLE_RIGHT = {{1u << 28}}; 212const PadState PAD_CIRCLE_RIGHT = {{1u << 28}};
214const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; 213const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
215const PadState PAD_CIRCLE_UP = {{1u << 30}}; 214const PadState PAD_CIRCLE_UP = {{1u << 30}};
216const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; 215const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
217 216
218/** 217/**
219 * HID::GetIPCHandles service function 218 * HID::GetIPCHandles service function
@@ -305,6 +304,5 @@ void Init();
305 304
306/// Shutdown HID service 305/// Shutdown HID service
307void Shutdown(); 306void Shutdown();
308
309} 307}
310} 308}
diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp
index 046e65b11..09007e304 100644
--- a/src/core/hle/service/hid/hid_spvr.cpp
+++ b/src/core/hle/service/hid/hid_spvr.cpp
@@ -9,16 +9,16 @@ namespace Service {
9namespace HID { 9namespace HID {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x000A0000, GetIPCHandles, "GetIPCHandles"}, 12 {0x000A0000, GetIPCHandles, "GetIPCHandles"},
13 {0x000B0000, nullptr, "StartAnalogStickCalibration"}, 13 {0x000B0000, nullptr, "StartAnalogStickCalibration"},
14 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, 14 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"},
15 {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, 15 {0x00110000, EnableAccelerometer, "EnableAccelerometer"},
16 {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, 16 {0x00120000, DisableAccelerometer, "DisableAccelerometer"},
17 {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, 17 {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"},
18 {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, 18 {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"},
19 {0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"}, 19 {0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"},
20 {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, 20 {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"},
21 {0x00170000, GetSoundVolume, "GetSoundVolume"}, 21 {0x00170000, GetSoundVolume, "GetSoundVolume"},
22}; 22};
23 23
24HID_SPVR_Interface::HID_SPVR_Interface() { 24HID_SPVR_Interface::HID_SPVR_Interface() {
diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp
index bb157b83d..42591543c 100644
--- a/src/core/hle/service/hid/hid_user.cpp
+++ b/src/core/hle/service/hid/hid_user.cpp
@@ -9,16 +9,16 @@ namespace Service {
9namespace HID { 9namespace HID {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x000A0000, GetIPCHandles, "GetIPCHandles"}, 12 {0x000A0000, GetIPCHandles, "GetIPCHandles"},
13 {0x000B0000, nullptr, "StartAnalogStickCalibration"}, 13 {0x000B0000, nullptr, "StartAnalogStickCalibration"},
14 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, 14 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"},
15 {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, 15 {0x00110000, EnableAccelerometer, "EnableAccelerometer"},
16 {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, 16 {0x00120000, DisableAccelerometer, "DisableAccelerometer"},
17 {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, 17 {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"},
18 {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, 18 {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"},
19 {0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"}, 19 {0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"},
20 {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, 20 {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"},
21 {0x00170000, GetSoundVolume, "GetSoundVolume"}, 21 {0x00170000, GetSoundVolume, "GetSoundVolume"},
22}; 22};
23 23
24HID_U_Interface::HID_U_Interface() { 24HID_U_Interface::HID_U_Interface() {
diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp
index 0855ab227..3cf62a4b8 100644
--- a/src/core/hle/service/http_c.cpp
+++ b/src/core/hle/service/http_c.cpp
@@ -10,56 +10,56 @@
10namespace HTTP_C { 10namespace HTTP_C {
11 11
12const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010044, nullptr, "Initialize"}, 13 {0x00010044, nullptr, "Initialize"},
14 {0x00020082, nullptr, "CreateContext"}, 14 {0x00020082, nullptr, "CreateContext"},
15 {0x00030040, nullptr, "CloseContext"}, 15 {0x00030040, nullptr, "CloseContext"},
16 {0x00040040, nullptr, "CancelConnection"}, 16 {0x00040040, nullptr, "CancelConnection"},
17 {0x00050040, nullptr, "GetRequestState"}, 17 {0x00050040, nullptr, "GetRequestState"},
18 {0x00060040, nullptr, "GetDownloadSizeState"}, 18 {0x00060040, nullptr, "GetDownloadSizeState"},
19 {0x00070040, nullptr, "GetRequestError"}, 19 {0x00070040, nullptr, "GetRequestError"},
20 {0x00080042, nullptr, "InitializeConnectionSession"}, 20 {0x00080042, nullptr, "InitializeConnectionSession"},
21 {0x00090040, nullptr, "BeginRequest"}, 21 {0x00090040, nullptr, "BeginRequest"},
22 {0x000A0040, nullptr, "BeginRequestAsync"}, 22 {0x000A0040, nullptr, "BeginRequestAsync"},
23 {0x000B0082, nullptr, "ReceiveData"}, 23 {0x000B0082, nullptr, "ReceiveData"},
24 {0x000C0102, nullptr, "ReceiveDataTimeout"}, 24 {0x000C0102, nullptr, "ReceiveDataTimeout"},
25 {0x000D0146, nullptr, "SetProxy"}, 25 {0x000D0146, nullptr, "SetProxy"},
26 {0x000E0040, nullptr, "SetProxyDefault"}, 26 {0x000E0040, nullptr, "SetProxyDefault"},
27 {0x000F00C4, nullptr, "SetBasicAuthorization"}, 27 {0x000F00C4, nullptr, "SetBasicAuthorization"},
28 {0x00100080, nullptr, "SetSocketBufferSize"}, 28 {0x00100080, nullptr, "SetSocketBufferSize"},
29 {0x001100C4, nullptr, "AddRequestHeader"}, 29 {0x001100C4, nullptr, "AddRequestHeader"},
30 {0x001200C4, nullptr, "AddPostDataAscii"}, 30 {0x001200C4, nullptr, "AddPostDataAscii"},
31 {0x001300C4, nullptr, "AddPostDataBinary"}, 31 {0x001300C4, nullptr, "AddPostDataBinary"},
32 {0x00140082, nullptr, "AddPostDataRaw"}, 32 {0x00140082, nullptr, "AddPostDataRaw"},
33 {0x00150080, nullptr, "SetPostDataType"}, 33 {0x00150080, nullptr, "SetPostDataType"},
34 {0x001600C4, nullptr, "SendPostDataAscii"}, 34 {0x001600C4, nullptr, "SendPostDataAscii"},
35 {0x00170144, nullptr, "SendPostDataAsciiTimeout"}, 35 {0x00170144, nullptr, "SendPostDataAsciiTimeout"},
36 {0x001800C4, nullptr, "SendPostDataBinary"}, 36 {0x001800C4, nullptr, "SendPostDataBinary"},
37 {0x00190144, nullptr, "SendPostDataBinaryTimeout"}, 37 {0x00190144, nullptr, "SendPostDataBinaryTimeout"},
38 {0x001A0082, nullptr, "SendPostDataRaw"}, 38 {0x001A0082, nullptr, "SendPostDataRaw"},
39 {0x001B0102, nullptr, "SendPOSTDataRawTimeout"}, 39 {0x001B0102, nullptr, "SendPOSTDataRawTimeout"},
40 {0x001C0080, nullptr, "SetPostDataEncoding"}, 40 {0x001C0080, nullptr, "SetPostDataEncoding"},
41 {0x001D0040, nullptr, "NotifyFinishSendPostData"}, 41 {0x001D0040, nullptr, "NotifyFinishSendPostData"},
42 {0x001E00C4, nullptr, "GetResponseHeader"}, 42 {0x001E00C4, nullptr, "GetResponseHeader"},
43 {0x001F0144, nullptr, "GetResponseHeaderTimeout"}, 43 {0x001F0144, nullptr, "GetResponseHeaderTimeout"},
44 {0x00200082, nullptr, "GetResponseData"}, 44 {0x00200082, nullptr, "GetResponseData"},
45 {0x00210102, nullptr, "GetResponseDataTimeout"}, 45 {0x00210102, nullptr, "GetResponseDataTimeout"},
46 {0x00220040, nullptr, "GetResponseStatusCode"}, 46 {0x00220040, nullptr, "GetResponseStatusCode"},
47 {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"}, 47 {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"},
48 {0x00240082, nullptr, "AddTrustedRootCA"}, 48 {0x00240082, nullptr, "AddTrustedRootCA"},
49 {0x00250080, nullptr, "AddDefaultCert"}, 49 {0x00250080, nullptr, "AddDefaultCert"},
50 {0x00260080, nullptr, "SelectRootCertChain"}, 50 {0x00260080, nullptr, "SelectRootCertChain"},
51 {0x002700C4, nullptr, "SetClientCert"}, 51 {0x002700C4, nullptr, "SetClientCert"},
52 {0x002B0080, nullptr, "SetSSLOpt"}, 52 {0x002B0080, nullptr, "SetSSLOpt"},
53 {0x002C0080, nullptr, "SetSSLClearOpt"}, 53 {0x002C0080, nullptr, "SetSSLClearOpt"},
54 {0x002D0000, nullptr, "CreateRootCertChain"}, 54 {0x002D0000, nullptr, "CreateRootCertChain"},
55 {0x002E0040, nullptr, "DestroyRootCertChain"}, 55 {0x002E0040, nullptr, "DestroyRootCertChain"},
56 {0x002F0082, nullptr, "RootCertChainAddCert"}, 56 {0x002F0082, nullptr, "RootCertChainAddCert"},
57 {0x00300080, nullptr, "RootCertChainAddDefaultCert"}, 57 {0x00300080, nullptr, "RootCertChainAddDefaultCert"},
58 {0x00350186, nullptr, "SetDefaultProxy"}, 58 {0x00350186, nullptr, "SetDefaultProxy"},
59 {0x00360000, nullptr, "ClearDNSCache"}, 59 {0x00360000, nullptr, "ClearDNSCache"},
60 {0x00370080, nullptr, "SetKeepAlive"}, 60 {0x00370080, nullptr, "SetKeepAlive"},
61 {0x003800C0, nullptr, "SetPostDataTypeSize"}, 61 {0x003800C0, nullptr, "SetPostDataTypeSize"},
62 {0x00390000, nullptr, "Finalize"}, 62 {0x00390000, nullptr, "Finalize"},
63}; 63};
64 64
65//////////////////////////////////////////////////////////////////////////////////////////////////// 65////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp
index 079a87e48..4d6639ded 100644
--- a/src/core/hle/service/ir/ir.cpp
+++ b/src/core/hle/service/ir/ir.cpp
@@ -4,12 +4,11 @@
4 4
5#include "core/hle/kernel/event.h" 5#include "core/hle/kernel/event.h"
6#include "core/hle/kernel/shared_memory.h" 6#include "core/hle/kernel/shared_memory.h"
7
8#include "core/hle/service/service.h"
9#include "core/hle/service/ir/ir.h" 7#include "core/hle/service/ir/ir.h"
10#include "core/hle/service/ir/ir_rst.h" 8#include "core/hle/service/ir/ir_rst.h"
11#include "core/hle/service/ir/ir_u.h" 9#include "core/hle/service/ir/ir_u.h"
12#include "core/hle/service/ir/ir_user.h" 10#include "core/hle/service/ir/ir_user.h"
11#include "core/hle/service/service.h"
13 12
14namespace Service { 13namespace Service {
15namespace IR { 14namespace IR {
@@ -32,14 +31,14 @@ void InitializeIrNopShared(Interface* self) {
32 u32* cmd_buff = Kernel::GetCommandBuffer(); 31 u32* cmd_buff = Kernel::GetCommandBuffer();
33 32
34 u32 transfer_buff_size = cmd_buff[1]; 33 u32 transfer_buff_size = cmd_buff[1];
35 u32 recv_buff_size = cmd_buff[2]; 34 u32 recv_buff_size = cmd_buff[2];
36 u32 unk1 = cmd_buff[3]; 35 u32 unk1 = cmd_buff[3];
37 u32 send_buff_size = cmd_buff[4]; 36 u32 send_buff_size = cmd_buff[4];
38 u32 unk2 = cmd_buff[5]; 37 u32 unk2 = cmd_buff[5];
39 u8 baud_rate = cmd_buff[6] & 0xFF; 38 u8 baud_rate = cmd_buff[6] & 0xFF;
40 Handle handle = cmd_buff[8]; 39 Handle handle = cmd_buff[8];
41 40
42 if(Kernel::g_handle_table.IsValid(handle)) { 41 if (Kernel::g_handle_table.IsValid(handle)) {
43 transfer_shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(handle); 42 transfer_shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(handle);
44 transfer_shared_memory->name = "IR:TransferSharedMemory"; 43 transfer_shared_memory->name = "IR:TransferSharedMemory";
45 } 44 }
@@ -47,7 +46,7 @@ void InitializeIrNopShared(Interface* self) {
47 cmd_buff[1] = RESULT_SUCCESS.raw; 46 cmd_buff[1] = RESULT_SUCCESS.raw;
48 47
49 LOG_WARNING(Service_IR, "(STUBBED) called, transfer_buff_size=%d, recv_buff_size=%d, " 48 LOG_WARNING(Service_IR, "(STUBBED) called, transfer_buff_size=%d, recv_buff_size=%d, "
50 "unk1=%d, send_buff_size=%d, unk2=%d, baud_rate=%u, handle=0x%08X", 49 "unk1=%d, send_buff_size=%d, unk2=%d, baud_rate=%u, handle=0x%08X",
51 transfer_buff_size, recv_buff_size, unk1, send_buff_size, unk2, baud_rate, handle); 50 transfer_buff_size, recv_buff_size, unk1, send_buff_size, unk2, baud_rate, handle);
52} 51}
53 52
@@ -94,13 +93,13 @@ void Init() {
94 AddService(new IR_User_Interface); 93 AddService(new IR_User_Interface);
95 94
96 using Kernel::MemoryPermission; 95 using Kernel::MemoryPermission;
97 shared_memory = SharedMemory::Create(nullptr, 0x1000, 96 shared_memory = SharedMemory::Create(nullptr, 0x1000, Kernel::MemoryPermission::ReadWrite,
98 Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::ReadWrite, 97 Kernel::MemoryPermission::ReadWrite, 0,
99 0, Kernel::MemoryRegion::BASE, "IR:SharedMemory"); 98 Kernel::MemoryRegion::BASE, "IR:SharedMemory");
100 transfer_shared_memory = nullptr; 99 transfer_shared_memory = nullptr;
101 100
102 // Create event handle(s) 101 // Create event handle(s)
103 handle_event = Event::Create(ResetType::OneShot, "IR:HandleEvent"); 102 handle_event = Event::Create(ResetType::OneShot, "IR:HandleEvent");
104 conn_status_event = Event::Create(ResetType::OneShot, "IR:ConnectionStatusEvent"); 103 conn_status_event = Event::Create(ResetType::OneShot, "IR:ConnectionStatusEvent");
105} 104}
106 105
diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp
index c0300f109..1f10ebd3d 100644
--- a/src/core/hle/service/ir/ir_rst.cpp
+++ b/src/core/hle/service/ir/ir_rst.cpp
@@ -9,10 +9,10 @@ namespace Service {
9namespace IR { 9namespace IR {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010000, GetHandles, "GetHandles"}, 12 {0x00010000, GetHandles, "GetHandles"},
13 {0x00020080, nullptr, "Initialize"}, 13 {0x00020080, nullptr, "Initialize"},
14 {0x00030000, nullptr, "Shutdown"}, 14 {0x00030000, nullptr, "Shutdown"},
15 {0x00090000, nullptr, "WriteToTwoFields"}, 15 {0x00090000, nullptr, "WriteToTwoFields"},
16}; 16};
17 17
18IR_RST_Interface::IR_RST_Interface() { 18IR_RST_Interface::IR_RST_Interface() {
diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp
index 96f76cb83..429615f31 100644
--- a/src/core/hle/service/ir/ir_u.cpp
+++ b/src/core/hle/service/ir/ir_u.cpp
@@ -8,24 +8,26 @@ namespace Service {
8namespace IR { 8namespace IR {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x00010000, nullptr, "Initialize"}, 11 // clang-format off
12 {0x00020000, nullptr, "Shutdown"}, 12 {0x00010000, nullptr, "Initialize"},
13 {0x00030042, nullptr, "StartSendTransfer"}, 13 {0x00020000, nullptr, "Shutdown"},
14 {0x00040000, nullptr, "WaitSendTransfer"}, 14 {0x00030042, nullptr, "StartSendTransfer"},
15 {0x000500C2, nullptr, "StartRecvTransfer"}, 15 {0x00040000, nullptr, "WaitSendTransfer"},
16 {0x00060000, nullptr, "WaitRecvTransfer"}, 16 {0x000500C2, nullptr, "StartRecvTransfer"},
17 {0x00070080, nullptr, "GetRecvTransferCount"}, 17 {0x00060000, nullptr, "WaitRecvTransfer"},
18 {0x00080000, nullptr, "GetSendState"}, 18 {0x00070080, nullptr, "GetRecvTransferCount"},
19 {0x00090040, nullptr, "SetBitRate"}, 19 {0x00080000, nullptr, "GetSendState"},
20 {0x000A0000, nullptr, "GetBitRate"}, 20 {0x00090040, nullptr, "SetBitRate"},
21 {0x000B0040, nullptr, "SetIRLEDState"}, 21 {0x000A0000, nullptr, "GetBitRate"},
22 {0x000C0000, nullptr, "GetIRLEDRecvState"}, 22 {0x000B0040, nullptr, "SetIRLEDState"},
23 {0x000D0000, nullptr, "GetSendFinishedEvent"}, 23 {0x000C0000, nullptr, "GetIRLEDRecvState"},
24 {0x000E0000, nullptr, "GetRecvFinishedEvent"}, 24 {0x000D0000, nullptr, "GetSendFinishedEvent"},
25 {0x000F0000, nullptr, "GetTransferState"}, 25 {0x000E0000, nullptr, "GetRecvFinishedEvent"},
26 {0x00100000, nullptr, "GetErrorStatus"}, 26 {0x000F0000, nullptr, "GetTransferState"},
27 {0x00110040, nullptr, "SetSleepModeActive"}, 27 {0x00100000, nullptr, "GetErrorStatus"},
28 {0x00120040, nullptr, "SetSleepModeState"}, 28 {0x00110040, nullptr, "SetSleepModeActive"},
29 {0x00120040, nullptr, "SetSleepModeState"},
30 // clang-format off
29}; 31};
30 32
31IR_U_Interface::IR_U_Interface() { 33IR_U_Interface::IR_U_Interface() {
diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp
index 06a601029..6cff1d544 100644
--- a/src/core/hle/service/ir/ir_user.cpp
+++ b/src/core/hle/service/ir/ir_user.cpp
@@ -9,32 +9,32 @@ namespace Service {
9namespace IR { 9namespace IR {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010182, nullptr, "InitializeIrNop"}, 12 {0x00010182, nullptr, "InitializeIrNop"},
13 {0x00020000, FinalizeIrNop, "FinalizeIrNop"}, 13 {0x00020000, FinalizeIrNop, "FinalizeIrNop"},
14 {0x00030000, nullptr, "ClearReceiveBuffer"}, 14 {0x00030000, nullptr, "ClearReceiveBuffer"},
15 {0x00040000, nullptr, "ClearSendBuffer"}, 15 {0x00040000, nullptr, "ClearSendBuffer"},
16 {0x000500C0, nullptr, "WaitConnection"}, 16 {0x000500C0, nullptr, "WaitConnection"},
17 {0x00060040, RequireConnection, "RequireConnection"}, 17 {0x00060040, RequireConnection, "RequireConnection"},
18 {0x000702C0, nullptr, "AutoConnection"}, 18 {0x000702C0, nullptr, "AutoConnection"},
19 {0x00080000, nullptr, "AnyConnection"}, 19 {0x00080000, nullptr, "AnyConnection"},
20 {0x00090000, Disconnect, "Disconnect"}, 20 {0x00090000, Disconnect, "Disconnect"},
21 {0x000A0000, nullptr, "GetReceiveEvent"}, 21 {0x000A0000, nullptr, "GetReceiveEvent"},
22 {0x000B0000, nullptr, "GetSendEvent"}, 22 {0x000B0000, nullptr, "GetSendEvent"},
23 {0x000C0000, GetConnectionStatusEvent, "GetConnectionStatusEvent"}, 23 {0x000C0000, GetConnectionStatusEvent, "GetConnectionStatusEvent"},
24 {0x000D0042, nullptr, "SendIrNop"}, 24 {0x000D0042, nullptr, "SendIrNop"},
25 {0x000E0042, nullptr, "SendIrNopLarge"}, 25 {0x000E0042, nullptr, "SendIrNopLarge"},
26 {0x000F0040, nullptr, "ReceiveIrnop"}, 26 {0x000F0040, nullptr, "ReceiveIrnop"},
27 {0x00100042, nullptr, "ReceiveIrnopLarge"}, 27 {0x00100042, nullptr, "ReceiveIrnopLarge"},
28 {0x00110040, nullptr, "GetLatestReceiveErrorResult"}, 28 {0x00110040, nullptr, "GetLatestReceiveErrorResult"},
29 {0x00120040, nullptr, "GetLatestSendErrorResult"}, 29 {0x00120040, nullptr, "GetLatestSendErrorResult"},
30 {0x00130000, nullptr, "GetConnectionStatus"}, 30 {0x00130000, nullptr, "GetConnectionStatus"},
31 {0x00140000, nullptr, "GetTryingToConnectStatus"}, 31 {0x00140000, nullptr, "GetTryingToConnectStatus"},
32 {0x00150000, nullptr, "GetReceiveSizeFreeAndUsed"}, 32 {0x00150000, nullptr, "GetReceiveSizeFreeAndUsed"},
33 {0x00160000, nullptr, "GetSendSizeFreeAndUsed"}, 33 {0x00160000, nullptr, "GetSendSizeFreeAndUsed"},
34 {0x00170000, nullptr, "GetConnectionRole"}, 34 {0x00170000, nullptr, "GetConnectionRole"},
35 {0x00180182, InitializeIrNopShared, "InitializeIrNopShared"}, 35 {0x00180182, InitializeIrNopShared, "InitializeIrNopShared"},
36 {0x00190040, nullptr, "ReleaseReceivedData"}, 36 {0x00190040, nullptr, "ReleaseReceivedData"},
37 {0x001A0040, nullptr, "SetOwnMachineId"}, 37 {0x001A0040, nullptr, "SetOwnMachineId"},
38}; 38};
39 39
40IR_User_Interface::IR_User_Interface() { 40IR_User_Interface::IR_User_Interface() {
diff --git a/src/core/hle/service/ldr_ro/cro_helper.cpp b/src/core/hle/service/ldr_ro/cro_helper.cpp
index 3d2a613ee..b7d250312 100644
--- a/src/core/hle/service/ldr_ro/cro_helper.cpp
+++ b/src/core/hle/service/ldr_ro/cro_helper.cpp
@@ -5,7 +5,6 @@
5#include "common/alignment.h" 5#include "common/alignment.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "common/scope_exit.h" 7#include "common/scope_exit.h"
8
9#include "core/hle/service/ldr_ro/cro_helper.h" 8#include "core/hle/service/ldr_ro/cro_helper.h"
10 9
11//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -14,37 +13,30 @@
14namespace LDR_RO { 13namespace LDR_RO {
15 14
16static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F 15static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F
17 ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 16 ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument,
17 ErrorLevel::Usage);
18 18
19static ResultCode CROFormatError(u32 description) { 19static ResultCode CROFormatError(u32 description) {
20 return ResultCode(static_cast<ErrorDescription>(description), ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 20 return ResultCode(static_cast<ErrorDescription>(description), ErrorModule::RO,
21 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
21} 22}
22 23
23const std::array<int, 17> CROHelper::ENTRY_SIZE {{ 24const std::array<int, 17> CROHelper::ENTRY_SIZE{{
24 1, // code 25 1, // code
25 1, // data 26 1, // data
26 1, // module name 27 1, // module name
27 sizeof(SegmentEntry), 28 sizeof(SegmentEntry), sizeof(ExportNamedSymbolEntry), sizeof(ExportIndexedSymbolEntry),
28 sizeof(ExportNamedSymbolEntry),
29 sizeof(ExportIndexedSymbolEntry),
30 1, // export strings 29 1, // export strings
31 sizeof(ExportTreeEntry), 30 sizeof(ExportTreeEntry), sizeof(ImportModuleEntry), sizeof(ExternalRelocationEntry),
32 sizeof(ImportModuleEntry), 31 sizeof(ImportNamedSymbolEntry), sizeof(ImportIndexedSymbolEntry),
33 sizeof(ExternalRelocationEntry),
34 sizeof(ImportNamedSymbolEntry),
35 sizeof(ImportIndexedSymbolEntry),
36 sizeof(ImportAnonymousSymbolEntry), 32 sizeof(ImportAnonymousSymbolEntry),
37 1, // import strings 33 1, // import strings
38 sizeof(StaticAnonymousSymbolEntry), 34 sizeof(StaticAnonymousSymbolEntry), sizeof(InternalRelocationEntry),
39 sizeof(InternalRelocationEntry), 35 sizeof(StaticRelocationEntry),
40 sizeof(StaticRelocationEntry)
41}}; 36}};
42 37
43const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS {{ 38const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS{{
44 Fix0Barrier, 39 Fix0Barrier, Fix1Barrier, Fix2Barrier, Fix3Barrier,
45 Fix1Barrier,
46 Fix2Barrier,
47 Fix3Barrier
48}}; 40}};
49 41
50VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { 42VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
@@ -63,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const {
63} 55}
64 56
65ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType relocation_type, 57ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType relocation_type,
66 u32 addend, u32 symbol_address, u32 target_future_address) { 58 u32 addend, u32 symbol_address, u32 target_future_address) {
67 59
68 switch (relocation_type) { 60 switch (relocation_type) {
69 case RelocationType::Nothing: 61 case RelocationType::Nothing:
@@ -124,7 +116,8 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool
124 return CROFormatError(0x12); 116 return CROFormatError(0x12);
125 } 117 }
126 118
127 ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, symbol_address, relocation_target); 119 ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend,
120 symbol_address, relocation_target);
128 if (result.IsError()) { 121 if (result.IsError()) {
129 LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); 122 LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw);
130 return result; 123 return result;
@@ -167,7 +160,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const {
167 160
168 if (test_byte >= len) { 161 if (test_byte >= len) {
169 next.raw = entry.left.raw; 162 next.raw = entry.left.raw;
170 } else if((name[test_byte] >> test_bit_in_byte) & 1) { 163 } else if ((name[test_byte] >> test_bit_in_byte) & 1) {
171 next.raw = entry.right.raw; 164 next.raw = entry.right.raw;
172 } else { 165 } else {
173 next.raw = entry.left.raw; 166 next.raw = entry.left.raw;
@@ -213,24 +206,12 @@ ResultCode CROHelper::RebaseHeader(u32 cro_size) {
213 206
214 // verifies that all offsets are in the correct order 207 // verifies that all offsets are in the correct order
215 constexpr std::array<HeaderField, 18> OFFSET_ORDER = {{ 208 constexpr std::array<HeaderField, 18> OFFSET_ORDER = {{
216 CodeOffset, 209 CodeOffset, ModuleNameOffset, SegmentTableOffset, ExportNamedSymbolTableOffset,
217 ModuleNameOffset, 210 ExportTreeTableOffset, ExportIndexedSymbolTableOffset, ExportStringsOffset,
218 SegmentTableOffset, 211 ImportModuleTableOffset, ExternalRelocationTableOffset, ImportNamedSymbolTableOffset,
219 ExportNamedSymbolTableOffset, 212 ImportIndexedSymbolTableOffset, ImportAnonymousSymbolTableOffset, ImportStringsOffset,
220 ExportTreeTableOffset, 213 StaticAnonymousSymbolTableOffset, InternalRelocationTableOffset,
221 ExportIndexedSymbolTableOffset, 214 StaticRelocationTableOffset, DataOffset, FileSize,
222 ExportStringsOffset,
223 ImportModuleTableOffset,
224 ExternalRelocationTableOffset,
225 ImportNamedSymbolTableOffset,
226 ImportIndexedSymbolTableOffset,
227 ImportAnonymousSymbolTableOffset,
228 ImportStringsOffset,
229 StaticAnonymousSymbolTableOffset,
230 InternalRelocationTableOffset,
231 StaticRelocationTableOffset,
232 DataOffset,
233 FileSize
234 }}; 215 }};
235 216
236 u32 prev_offset = GetField(OFFSET_ORDER[0]); 217 u32 prev_offset = GetField(OFFSET_ORDER[0]);
@@ -266,9 +247,9 @@ ResultCode CROHelper::RebaseHeader(u32 cro_size) {
266 return RESULT_SUCCESS; 247 return RESULT_SUCCESS;
267} 248}
268 249
269ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, 250ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_address,
270 VAddr data_segment_address, u32 data_segment_size, 251 u32 data_segment_size, VAddr bss_segment_address,
271 VAddr bss_segment_address, u32 bss_segment_size) { 252 u32 bss_segment_size) {
272 253
273 u32 prev_data_segment = 0; 254 u32 prev_data_segment = 0;
274 u32 segment_num = GetField(SegmentNum); 255 u32 segment_num = GetField(SegmentNum);
@@ -309,8 +290,8 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() {
309 290
310 if (entry.name_offset != 0) { 291 if (entry.name_offset != 0) {
311 entry.name_offset += module_address; 292 entry.name_offset += module_address;
312 if (entry.name_offset < export_strings_offset 293 if (entry.name_offset < export_strings_offset ||
313 || entry.name_offset >= export_strings_end) { 294 entry.name_offset >= export_strings_end) {
314 return CROFormatError(0x11); 295 return CROFormatError(0x11);
315 } 296 }
316 } 297 }
@@ -337,9 +318,13 @@ ResultCode CROHelper::RebaseImportModuleTable() {
337 VAddr import_strings_offset = GetField(ImportStringsOffset); 318 VAddr import_strings_offset = GetField(ImportStringsOffset);
338 VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize); 319 VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize);
339 VAddr import_indexed_symbol_table_offset = GetField(ImportIndexedSymbolTableOffset); 320 VAddr import_indexed_symbol_table_offset = GetField(ImportIndexedSymbolTableOffset);
340 VAddr index_import_table_end = import_indexed_symbol_table_offset + GetField(ImportIndexedSymbolNum) * sizeof(ImportIndexedSymbolEntry); 321 VAddr index_import_table_end =
322 import_indexed_symbol_table_offset +
323 GetField(ImportIndexedSymbolNum) * sizeof(ImportIndexedSymbolEntry);
341 VAddr import_anonymous_symbol_table_offset = GetField(ImportAnonymousSymbolTableOffset); 324 VAddr import_anonymous_symbol_table_offset = GetField(ImportAnonymousSymbolTableOffset);
342 VAddr offset_import_table_end = import_anonymous_symbol_table_offset + GetField(ImportAnonymousSymbolNum) * sizeof(ImportAnonymousSymbolEntry); 325 VAddr offset_import_table_end =
326 import_anonymous_symbol_table_offset +
327 GetField(ImportAnonymousSymbolNum) * sizeof(ImportAnonymousSymbolEntry);
343 328
344 u32 module_num = GetField(ImportModuleNum); 329 u32 module_num = GetField(ImportModuleNum);
345 for (u32 i = 0; i < module_num; ++i) { 330 for (u32 i = 0; i < module_num; ++i) {
@@ -348,24 +333,24 @@ ResultCode CROHelper::RebaseImportModuleTable() {
348 333
349 if (entry.name_offset != 0) { 334 if (entry.name_offset != 0) {
350 entry.name_offset += module_address; 335 entry.name_offset += module_address;
351 if (entry.name_offset < import_strings_offset 336 if (entry.name_offset < import_strings_offset ||
352 || entry.name_offset >= import_strings_end) { 337 entry.name_offset >= import_strings_end) {
353 return CROFormatError(0x18); 338 return CROFormatError(0x18);
354 } 339 }
355 } 340 }
356 341
357 if (entry.import_indexed_symbol_table_offset != 0) { 342 if (entry.import_indexed_symbol_table_offset != 0) {
358 entry.import_indexed_symbol_table_offset += module_address; 343 entry.import_indexed_symbol_table_offset += module_address;
359 if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset 344 if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset ||
360 || entry.import_indexed_symbol_table_offset > index_import_table_end) { 345 entry.import_indexed_symbol_table_offset > index_import_table_end) {
361 return CROFormatError(0x18); 346 return CROFormatError(0x18);
362 } 347 }
363 } 348 }
364 349
365 if (entry.import_anonymous_symbol_table_offset != 0) { 350 if (entry.import_anonymous_symbol_table_offset != 0) {
366 entry.import_anonymous_symbol_table_offset += module_address; 351 entry.import_anonymous_symbol_table_offset += module_address;
367 if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset 352 if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset ||
368 || entry.import_anonymous_symbol_table_offset > offset_import_table_end) { 353 entry.import_anonymous_symbol_table_offset > offset_import_table_end) {
369 return CROFormatError(0x18); 354 return CROFormatError(0x18);
370 } 355 }
371 } 356 }
@@ -379,25 +364,27 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
379 VAddr import_strings_offset = GetField(ImportStringsOffset); 364 VAddr import_strings_offset = GetField(ImportStringsOffset);
380 VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize); 365 VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize);
381 VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); 366 VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset);
382 VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); 367 VAddr external_relocation_table_end =
368 external_relocation_table_offset +
369 GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry);
383 370
384 u32 num = GetField(ImportNamedSymbolNum); 371 u32 num = GetField(ImportNamedSymbolNum);
385 for (u32 i = 0; i < num ; ++i) { 372 for (u32 i = 0; i < num; ++i) {
386 ImportNamedSymbolEntry entry; 373 ImportNamedSymbolEntry entry;
387 GetEntry(i, entry); 374 GetEntry(i, entry);
388 375
389 if (entry.name_offset != 0) { 376 if (entry.name_offset != 0) {
390 entry.name_offset += module_address; 377 entry.name_offset += module_address;
391 if (entry.name_offset < import_strings_offset 378 if (entry.name_offset < import_strings_offset ||
392 || entry.name_offset >= import_strings_end) { 379 entry.name_offset >= import_strings_end) {
393 return CROFormatError(0x1B); 380 return CROFormatError(0x1B);
394 } 381 }
395 } 382 }
396 383
397 if (entry.relocation_batch_offset != 0) { 384 if (entry.relocation_batch_offset != 0) {
398 entry.relocation_batch_offset += module_address; 385 entry.relocation_batch_offset += module_address;
399 if (entry.relocation_batch_offset < external_relocation_table_offset 386 if (entry.relocation_batch_offset < external_relocation_table_offset ||
400 || entry.relocation_batch_offset > external_relocation_table_end) { 387 entry.relocation_batch_offset > external_relocation_table_end) {
401 return CROFormatError(0x1B); 388 return CROFormatError(0x1B);
402 } 389 }
403 } 390 }
@@ -409,17 +396,19 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() {
409 396
410ResultCode CROHelper::RebaseImportIndexedSymbolTable() { 397ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
411 VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); 398 VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset);
412 VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); 399 VAddr external_relocation_table_end =
400 external_relocation_table_offset +
401 GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry);
413 402
414 u32 num = GetField(ImportIndexedSymbolNum); 403 u32 num = GetField(ImportIndexedSymbolNum);
415 for (u32 i = 0; i < num ; ++i) { 404 for (u32 i = 0; i < num; ++i) {
416 ImportIndexedSymbolEntry entry; 405 ImportIndexedSymbolEntry entry;
417 GetEntry(i, entry); 406 GetEntry(i, entry);
418 407
419 if (entry.relocation_batch_offset != 0) { 408 if (entry.relocation_batch_offset != 0) {
420 entry.relocation_batch_offset += module_address; 409 entry.relocation_batch_offset += module_address;
421 if (entry.relocation_batch_offset < external_relocation_table_offset 410 if (entry.relocation_batch_offset < external_relocation_table_offset ||
422 || entry.relocation_batch_offset > external_relocation_table_end) { 411 entry.relocation_batch_offset > external_relocation_table_end) {
423 return CROFormatError(0x14); 412 return CROFormatError(0x14);
424 } 413 }
425 } 414 }
@@ -431,17 +420,19 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() {
431 420
432ResultCode CROHelper::RebaseImportAnonymousSymbolTable() { 421ResultCode CROHelper::RebaseImportAnonymousSymbolTable() {
433 VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); 422 VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset);
434 VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); 423 VAddr external_relocation_table_end =
424 external_relocation_table_offset +
425 GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry);
435 426
436 u32 num = GetField(ImportAnonymousSymbolNum); 427 u32 num = GetField(ImportAnonymousSymbolNum);
437 for (u32 i = 0; i < num ; ++i) { 428 for (u32 i = 0; i < num; ++i) {
438 ImportAnonymousSymbolEntry entry; 429 ImportAnonymousSymbolEntry entry;
439 GetEntry(i, entry); 430 GetEntry(i, entry);
440 431
441 if (entry.relocation_batch_offset != 0) { 432 if (entry.relocation_batch_offset != 0) {
442 entry.relocation_batch_offset += module_address; 433 entry.relocation_batch_offset += module_address;
443 if (entry.relocation_batch_offset < external_relocation_table_offset 434 if (entry.relocation_batch_offset < external_relocation_table_offset ||
444 || entry.relocation_batch_offset > external_relocation_table_end) { 435 entry.relocation_batch_offset > external_relocation_table_end) {
445 return CROFormatError(0x17); 436 return CROFormatError(0x17);
446 } 437 }
447 } 438 }
@@ -475,7 +466,8 @@ ResultCode CROHelper::ResetExternalRelocations() {
475 return CROFormatError(0x12); 466 return CROFormatError(0x12);
476 } 467 }
477 468
478 ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, unresolved_symbol, relocation_target); 469 ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend,
470 unresolved_symbol, relocation_target);
479 if (result.IsError()) { 471 if (result.IsError()) {
480 LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); 472 LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw);
481 return result; 473 return result;
@@ -528,23 +520,27 @@ ResultCode CROHelper::ClearExternalRelocations() {
528 520
529ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) { 521ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) {
530 VAddr static_relocation_table_offset = GetField(StaticRelocationTableOffset); 522 VAddr static_relocation_table_offset = GetField(StaticRelocationTableOffset);
531 VAddr static_relocation_table_end = static_relocation_table_offset + GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry); 523 VAddr static_relocation_table_end =
524 static_relocation_table_offset +
525 GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry);
532 526
533 CROHelper crs(crs_address); 527 CROHelper crs(crs_address);
534 u32 offset_export_num = GetField(StaticAnonymousSymbolNum); 528 u32 offset_export_num = GetField(StaticAnonymousSymbolNum);
535 LOG_INFO(Service_LDR, "CRO \"%s\" exports %d static anonymous symbols", ModuleName().data(), offset_export_num); 529 LOG_INFO(Service_LDR, "CRO \"%s\" exports %d static anonymous symbols", ModuleName().data(),
530 offset_export_num);
536 for (u32 i = 0; i < offset_export_num; ++i) { 531 for (u32 i = 0; i < offset_export_num; ++i) {
537 StaticAnonymousSymbolEntry entry; 532 StaticAnonymousSymbolEntry entry;
538 GetEntry(i, entry); 533 GetEntry(i, entry);
539 u32 batch_address = entry.relocation_batch_offset + module_address; 534 u32 batch_address = entry.relocation_batch_offset + module_address;
540 535
541 if (batch_address < static_relocation_table_offset 536 if (batch_address < static_relocation_table_offset ||
542 || batch_address > static_relocation_table_end) { 537 batch_address > static_relocation_table_end) {
543 return CROFormatError(0x16); 538 return CROFormatError(0x16);
544 } 539 }
545 540
546 u32 symbol_address = SegmentTagToAddress(entry.symbol_position); 541 u32 symbol_address = SegmentTagToAddress(entry.symbol_position);
547 LOG_TRACE(Service_LDR, "CRO \"%s\" exports 0x%08X to the static module", ModuleName().data(), symbol_address); 542 LOG_TRACE(Service_LDR, "CRO \"%s\" exports 0x%08X to the static module",
543 ModuleName().data(), symbol_address);
548 ResultCode result = crs.ApplyRelocationBatch(batch_address, symbol_address); 544 ResultCode result = crs.ApplyRelocationBatch(batch_address, symbol_address);
549 if (result.IsError()) { 545 if (result.IsError()) {
550 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 546 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw);
@@ -571,7 +567,8 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
571 567
572 if (target_segment.type == SegmentType::Data) { 568 if (target_segment.type == SegmentType::Data) {
573 // If the relocation is to the .data segment, we need to relocate it in the old buffer 569 // If the relocation is to the .data segment, we need to relocate it in the old buffer
574 target_address = old_data_segment_address + relocation.target_position.offset_into_segment; 570 target_address =
571 old_data_segment_address + relocation.target_position.offset_into_segment;
575 } else { 572 } else {
576 target_address = target_addressB; 573 target_address = target_addressB;
577 } 574 }
@@ -582,8 +579,10 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) {
582 579
583 SegmentEntry symbol_segment; 580 SegmentEntry symbol_segment;
584 GetEntry(relocation.symbol_segment, symbol_segment); 581 GetEntry(relocation.symbol_segment, symbol_segment);
585 LOG_TRACE(Service_LDR, "Internally relocates 0x%08X with 0x%08X", target_address, symbol_segment.offset); 582 LOG_TRACE(Service_LDR, "Internally relocates 0x%08X with 0x%08X", target_address,
586 ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend, symbol_segment.offset, target_addressB); 583 symbol_segment.offset);
584 ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend,
585 symbol_segment.offset, target_addressB);
587 if (result.IsError()) { 586 if (result.IsError()) {
588 LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); 587 LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw);
589 return result; 588 return result;
@@ -734,25 +733,29 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) {
734 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); 733 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry));
735 734
736 if (!relocation_entry.is_batch_resolved) { 735 if (!relocation_entry.is_batch_resolved) {
737 ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { 736 ResultCode result =
738 std::string symbol_name = Memory::ReadCString(entry.name_offset, import_strings_size); 737 ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> {
739 u32 symbol_address = source.FindExportNamedSymbol(symbol_name); 738 std::string symbol_name =
740 739 Memory::ReadCString(entry.name_offset, import_strings_size);
741 if (symbol_address != 0) { 740 u32 symbol_address = source.FindExportNamedSymbol(symbol_name);
742 LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"", 741
743 ModuleName().data(), symbol_name.data(), source.ModuleName().data()); 742 if (symbol_address != 0) {
744 743 LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"",
745 ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); 744 ModuleName().data(), symbol_name.data(),
746 if (result.IsError()) { 745 source.ModuleName().data());
747 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 746
748 return result; 747 ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address);
748 if (result.IsError()) {
749 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X",
750 result.raw);
751 return result;
752 }
753
754 return MakeResult<bool>(false);
749 } 755 }
750 756
751 return MakeResult<bool>(false); 757 return MakeResult<bool>(true);
752 } 758 });
753
754 return MakeResult<bool>(true);
755 });
756 if (result.IsError()) { 759 if (result.IsError()) {
757 return result; 760 return result;
758 } 761 }
@@ -777,7 +780,6 @@ ResultCode CROHelper::ResetImportNamedSymbol() {
777 LOG_ERROR(Service_LDR, "Error reseting relocation batch %08X", result.raw); 780 LOG_ERROR(Service_LDR, "Error reseting relocation batch %08X", result.raw);
778 return result; 781 return result;
779 } 782 }
780
781 } 783 }
782 return RESULT_SUCCESS; 784 return RESULT_SUCCESS;
783} 785}
@@ -831,40 +833,47 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
831 GetEntry(i, entry); 833 GetEntry(i, entry);
832 std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size); 834 std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size);
833 835
834 ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { 836 ResultCode result =
835 if (want_cro_name == source.ModuleName()) { 837 ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> {
836 LOG_INFO(Service_LDR, "CRO \"%s\" imports %d indexed symbols from \"%s\"", 838 if (want_cro_name == source.ModuleName()) {
837 ModuleName().data(), entry.import_indexed_symbol_num, source.ModuleName().data()); 839 LOG_INFO(Service_LDR, "CRO \"%s\" imports %d indexed symbols from \"%s\"",
838 for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { 840 ModuleName().data(), entry.import_indexed_symbol_num,
839 ImportIndexedSymbolEntry im; 841 source.ModuleName().data());
840 entry.GetImportIndexedSymbolEntry(j, im); 842 for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
841 ExportIndexedSymbolEntry ex; 843 ImportIndexedSymbolEntry im;
842 source.GetEntry(im.index, ex); 844 entry.GetImportIndexedSymbolEntry(j, im);
843 u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position); 845 ExportIndexedSymbolEntry ex;
844 LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); 846 source.GetEntry(im.index, ex);
845 ResultCode result = ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); 847 u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position);
846 if (result.IsError()) { 848 LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address);
847 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 849 ResultCode result =
848 return result; 850 ApplyRelocationBatch(im.relocation_batch_offset, symbol_address);
851 if (result.IsError()) {
852 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X",
853 result.raw);
854 return result;
855 }
849 } 856 }
850 } 857 LOG_INFO(Service_LDR, "CRO \"%s\" imports %d anonymous symbols from \"%s\"",
851 LOG_INFO(Service_LDR, "CRO \"%s\" imports %d anonymous symbols from \"%s\"", 858 ModuleName().data(), entry.import_anonymous_symbol_num,
852 ModuleName().data(), entry.import_anonymous_symbol_num, source.ModuleName().data()); 859 source.ModuleName().data());
853 for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { 860 for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
854 ImportAnonymousSymbolEntry im; 861 ImportAnonymousSymbolEntry im;
855 entry.GetImportAnonymousSymbolEntry(j, im); 862 entry.GetImportAnonymousSymbolEntry(j, im);
856 u32 symbol_address = source.SegmentTagToAddress(im.symbol_position); 863 u32 symbol_address = source.SegmentTagToAddress(im.symbol_position);
857 LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); 864 LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address);
858 ResultCode result = ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); 865 ResultCode result =
859 if (result.IsError()) { 866 ApplyRelocationBatch(im.relocation_batch_offset, symbol_address);
860 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 867 if (result.IsError()) {
861 return result; 868 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X",
869 result.raw);
870 return result;
871 }
862 } 872 }
873 return MakeResult<bool>(false);
863 } 874 }
864 return MakeResult<bool>(false); 875 return MakeResult<bool>(true);
865 } 876 });
866 return MakeResult<bool>(true);
867 });
868 if (result.IsError()) { 877 if (result.IsError()) {
869 return result; 878 return result;
870 } 879 }
@@ -873,8 +882,8 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) {
873} 882}
874 883
875ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { 884ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
876 LOG_DEBUG(Service_LDR, "CRO \"%s\" exports named symbols to \"%s\"", 885 LOG_DEBUG(Service_LDR, "CRO \"%s\" exports named symbols to \"%s\"", ModuleName().data(),
877 ModuleName().data(), target.ModuleName().data()); 886 target.ModuleName().data());
878 u32 target_import_strings_size = target.GetField(ImportStringsSize); 887 u32 target_import_strings_size = target.GetField(ImportStringsSize);
879 u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum); 888 u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
880 for (u32 i = 0; i < target_symbol_import_num; ++i) { 889 for (u32 i = 0; i < target_symbol_import_num; ++i) {
@@ -885,7 +894,8 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
885 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); 894 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry));
886 895
887 if (!relocation_entry.is_batch_resolved) { 896 if (!relocation_entry.is_batch_resolved) {
888 std::string symbol_name = Memory::ReadCString(entry.name_offset, target_import_strings_size); 897 std::string symbol_name =
898 Memory::ReadCString(entry.name_offset, target_import_strings_size);
889 u32 symbol_address = FindExportNamedSymbol(symbol_name); 899 u32 symbol_address = FindExportNamedSymbol(symbol_name);
890 if (symbol_address != 0) { 900 if (symbol_address != 0) {
891 LOG_TRACE(Service_LDR, " exports symbol \"%s\"", symbol_name.data()); 901 LOG_TRACE(Service_LDR, " exports symbol \"%s\"", symbol_name.data());
@@ -901,8 +911,8 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) {
901} 911}
902 912
903ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { 913ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) {
904 LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports named symbols to \"%s\"", 914 LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports named symbols to \"%s\"", ModuleName().data(),
905 ModuleName().data(), target.ModuleName().data()); 915 target.ModuleName().data());
906 u32 unresolved_symbol = target.GetOnUnresolvedAddress(); 916 u32 unresolved_symbol = target.GetOnUnresolvedAddress();
907 u32 target_import_strings_size = target.GetField(ImportStringsSize); 917 u32 target_import_strings_size = target.GetField(ImportStringsSize);
908 u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum); 918 u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum);
@@ -914,11 +924,13 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) {
914 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); 924 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry));
915 925
916 if (relocation_entry.is_batch_resolved) { 926 if (relocation_entry.is_batch_resolved) {
917 std::string symbol_name = Memory::ReadCString(entry.name_offset, target_import_strings_size); 927 std::string symbol_name =
928 Memory::ReadCString(entry.name_offset, target_import_strings_size);
918 u32 symbol_address = FindExportNamedSymbol(symbol_name); 929 u32 symbol_address = FindExportNamedSymbol(symbol_name);
919 if (symbol_address != 0) { 930 if (symbol_address != 0) {
920 LOG_TRACE(Service_LDR, " unexports symbol \"%s\"", symbol_name.data()); 931 LOG_TRACE(Service_LDR, " unexports symbol \"%s\"", symbol_name.data());
921 ResultCode result = target.ApplyRelocationBatch(relocation_addr, unresolved_symbol, true); 932 ResultCode result =
933 target.ApplyRelocationBatch(relocation_addr, unresolved_symbol, true);
922 if (result.IsError()) { 934 if (result.IsError()) {
923 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 935 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw);
924 return result; 936 return result;
@@ -940,8 +952,8 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
940 if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) 952 if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name)
941 continue; 953 continue;
942 954
943 LOG_INFO(Service_LDR, "CRO \"%s\" exports %d indexed symbols to \"%s\"", 955 LOG_INFO(Service_LDR, "CRO \"%s\" exports %d indexed symbols to \"%s\"", module_name.data(),
944 module_name.data(), entry.import_indexed_symbol_num, target.ModuleName().data()); 956 entry.import_indexed_symbol_num, target.ModuleName().data());
945 for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { 957 for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
946 ImportIndexedSymbolEntry im; 958 ImportIndexedSymbolEntry im;
947 entry.GetImportIndexedSymbolEntry(j, im); 959 entry.GetImportIndexedSymbolEntry(j, im);
@@ -949,7 +961,8 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
949 GetEntry(im.index, ex); 961 GetEntry(im.index, ex);
950 u32 symbol_address = SegmentTagToAddress(ex.symbol_position); 962 u32 symbol_address = SegmentTagToAddress(ex.symbol_position);
951 LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address); 963 LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address);
952 ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); 964 ResultCode result =
965 target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address);
953 if (result.IsError()) { 966 if (result.IsError()) {
954 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 967 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw);
955 return result; 968 return result;
@@ -957,13 +970,14 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) {
957 } 970 }
958 971
959 LOG_INFO(Service_LDR, "CRO \"%s\" exports %d anonymous symbols to \"%s\"", 972 LOG_INFO(Service_LDR, "CRO \"%s\" exports %d anonymous symbols to \"%s\"",
960 module_name.data(), entry.import_anonymous_symbol_num, target.ModuleName().data()); 973 module_name.data(), entry.import_anonymous_symbol_num, target.ModuleName().data());
961 for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { 974 for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
962 ImportAnonymousSymbolEntry im; 975 ImportAnonymousSymbolEntry im;
963 entry.GetImportAnonymousSymbolEntry(j, im); 976 entry.GetImportAnonymousSymbolEntry(j, im);
964 u32 symbol_address = SegmentTagToAddress(im.symbol_position); 977 u32 symbol_address = SegmentTagToAddress(im.symbol_position);
965 LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address); 978 LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address);
966 ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); 979 ResultCode result =
980 target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address);
967 if (result.IsError()) { 981 if (result.IsError()) {
968 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 982 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw);
969 return result; 983 return result;
@@ -987,12 +1001,13 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
987 if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) 1001 if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name)
988 continue; 1002 continue;
989 1003
990 LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports indexed symbols to \"%s\"", 1004 LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports indexed symbols to \"%s\"", module_name.data(),
991 module_name.data(), target.ModuleName().data()); 1005 target.ModuleName().data());
992 for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { 1006 for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) {
993 ImportIndexedSymbolEntry im; 1007 ImportIndexedSymbolEntry im;
994 entry.GetImportIndexedSymbolEntry(j, im); 1008 entry.GetImportIndexedSymbolEntry(j, im);
995 ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); 1009 ResultCode result =
1010 target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
996 if (result.IsError()) { 1011 if (result.IsError()) {
997 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 1012 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw);
998 return result; 1013 return result;
@@ -1000,11 +1015,12 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) {
1000 } 1015 }
1001 1016
1002 LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports anonymous symbols to \"%s\"", 1017 LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports anonymous symbols to \"%s\"",
1003 module_name.data(), target.ModuleName().data()); 1018 module_name.data(), target.ModuleName().data());
1004 for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { 1019 for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) {
1005 ImportAnonymousSymbolEntry im; 1020 ImportAnonymousSymbolEntry im;
1006 entry.GetImportAnonymousSymbolEntry(j, im); 1021 entry.GetImportAnonymousSymbolEntry(j, im);
1007 ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); 1022 ResultCode result =
1023 target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true);
1008 if (result.IsError()) { 1024 if (result.IsError()) {
1009 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 1025 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw);
1010 return result; 1026 return result;
@@ -1025,25 +1041,27 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) {
1025 ExternalRelocationEntry relocation_entry; 1041 ExternalRelocationEntry relocation_entry;
1026 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); 1042 Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry));
1027 1043
1028 if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit"){ 1044 if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") {
1029 ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { 1045 ResultCode result =
1030 u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); 1046 ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> {
1047 u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_");
1031 1048
1032 if (symbol_address != 0) { 1049 if (symbol_address != 0) {
1033 LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"", 1050 LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"",
1034 ModuleName().data(), source.ModuleName().data()); 1051 ModuleName().data(), source.ModuleName().data());
1035 1052
1036 ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); 1053 ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address);
1037 if (result.IsError()) { 1054 if (result.IsError()) {
1038 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); 1055 LOG_ERROR(Service_LDR, "Error applying relocation batch %08X",
1039 return result; 1056 result.raw);
1040 } 1057 return result;
1058 }
1041 1059
1042 return MakeResult<bool>(false); 1060 return MakeResult<bool>(false);
1043 } 1061 }
1044 1062
1045 return MakeResult<bool>(true); 1063 return MakeResult<bool>(true);
1046 }); 1064 });
1047 if (result.IsError()) { 1065 if (result.IsError()) {
1048 LOG_ERROR(Service_LDR, "Error applying exit relocation %08X", result.raw); 1066 LOG_ERROR(Service_LDR, "Error applying exit relocation %08X", result.raw);
1049 return result; 1067 return result;
@@ -1070,9 +1088,9 @@ static ResultCode VerifyStringTableLength(VAddr address, u32 size) {
1070 return RESULT_SUCCESS; 1088 return RESULT_SUCCESS;
1071} 1089}
1072 1090
1073ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, 1091ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment_addresss,
1074 VAddr data_segment_addresss, u32 data_segment_size, 1092 u32 data_segment_size, VAddr bss_segment_address, u32 bss_segment_size,
1075 VAddr bss_segment_address, u32 bss_segment_size, bool is_crs) { 1093 bool is_crs) {
1076 1094
1077 ResultCode result = RebaseHeader(cro_size); 1095 ResultCode result = RebaseHeader(cro_size);
1078 if (result.IsError()) { 1096 if (result.IsError()) {
@@ -1088,9 +1106,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size,
1088 1106
1089 u32 prev_data_segment_address = 0; 1107 u32 prev_data_segment_address = 0;
1090 if (!is_crs) { 1108 if (!is_crs) {
1091 auto result_val = RebaseSegmentTable(cro_size, 1109 auto result_val = RebaseSegmentTable(cro_size, data_segment_addresss, data_segment_size,
1092 data_segment_addresss, data_segment_size, 1110 bss_segment_address, bss_segment_size);
1093 bss_segment_address, bss_segment_size);
1094 if (result_val.Failed()) { 1111 if (result_val.Failed()) {
1095 LOG_ERROR(Service_LDR, "Error rebasing segment table %08X", result_val.Code().raw); 1112 LOG_ERROR(Service_LDR, "Error rebasing segment table %08X", result_val.Code().raw);
1096 return result_val.Code(); 1113 return result_val.Code();
@@ -1374,7 +1391,8 @@ void CROHelper::Unregister(VAddr crs_address) {
1374 CROHelper next_head(crs.NextModule()), previous_head(crs.PreviousModule()); 1391 CROHelper next_head(crs.NextModule()), previous_head(crs.PreviousModule());
1375 CROHelper next(NextModule()), previous(PreviousModule()); 1392 CROHelper next(NextModule()), previous(PreviousModule());
1376 1393
1377 if (module_address == next_head.module_address || module_address == previous_head.module_address) { 1394 if (module_address == next_head.module_address ||
1395 module_address == previous_head.module_address) {
1378 // removing head 1396 // removing head
1379 if (next.module_address) { 1397 if (next.module_address) {
1380 // the next is new head 1398 // the next is new head
@@ -1400,7 +1418,8 @@ void CROHelper::Unregister(VAddr crs_address) {
1400 // let head's previous point to the new tail 1418 // let head's previous point to the new tail
1401 if (next_head.module_address && next_head.PreviousModule() == module_address) { 1419 if (next_head.module_address && next_head.PreviousModule() == module_address) {
1402 next_head.SetPreviousModule(previous.module_address); 1420 next_head.SetPreviousModule(previous.module_address);
1403 } else if (previous_head.module_address && previous_head.PreviousModule() == module_address) { 1421 } else if (previous_head.module_address &&
1422 previous_head.PreviousModule() == module_address) {
1404 previous_head.SetPreviousModule(previous.module_address); 1423 previous_head.SetPreviousModule(previous.module_address);
1405 } else { 1424 } else {
1406 UNREACHABLE(); 1425 UNREACHABLE();
@@ -1419,9 +1438,9 @@ u32 CROHelper::GetFixEnd(u32 fix_level) const {
1419 u32 entry_size_i = 2; 1438 u32 entry_size_i = 2;
1420 int field = ModuleNameOffset; 1439 int field = ModuleNameOffset;
1421 while (true) { 1440 while (true) {
1422 end = std::max<u32>(end, 1441 end = std::max<u32>(end, GetField(static_cast<HeaderField>(field)) +
1423 GetField(static_cast<HeaderField>(field)) + 1442 GetField(static_cast<HeaderField>(field + 1)) *
1424 GetField(static_cast<HeaderField>(field + 1)) * ENTRY_SIZE[entry_size_i]); 1443 ENTRY_SIZE[entry_size_i]);
1425 1444
1426 ++entry_size_i; 1445 ++entry_size_i;
1427 field += 2; 1446 field += 2;
diff --git a/src/core/hle/service/ldr_ro/cro_helper.h b/src/core/hle/service/ldr_ro/cro_helper.h
index 34e357afd..6a0d0d3bf 100644
--- a/src/core/hle/service/ldr_ro/cro_helper.h
+++ b/src/core/hle/service/ldr_ro/cro_helper.h
@@ -6,12 +6,10 @@
6 6
7#include <array> 7#include <array>
8#include <tuple> 8#include <tuple>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11#include "common/swap.h" 10#include "common/swap.h"
12
13#include "core/memory.h"
14#include "core/hle/result.h" 11#include "core/hle/result.h"
12#include "core/memory.h"
15 13
16//////////////////////////////////////////////////////////////////////////////////////////////////// 14////////////////////////////////////////////////////////////////////////////////////////////////////
17// Namespace LDR_RO 15// Namespace LDR_RO
@@ -21,14 +19,17 @@ namespace LDR_RO {
21// GCC versions < 5.0 do not implement std::is_trivially_copyable. 19// GCC versions < 5.0 do not implement std::is_trivially_copyable.
22// Excluding MSVC because it has weird behaviour for std::is_trivially_copyable. 20// Excluding MSVC because it has weird behaviour for std::is_trivially_copyable.
23#if (__GNUC__ >= 5) || defined(__clang__) 21#if (__GNUC__ >= 5) || defined(__clang__)
24 #define ASSERT_CRO_STRUCT(name, size) \ 22#define ASSERT_CRO_STRUCT(name, size) \
25 static_assert(std::is_standard_layout<name>::value, "CRO structure " #name " doesn't use standard layout"); \ 23 static_assert(std::is_standard_layout<name>::value, \
26 static_assert(std::is_trivially_copyable<name>::value, "CRO structure " #name " isn't trivially copyable"); \ 24 "CRO structure " #name " doesn't use standard layout"); \
27 static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) 25 static_assert(std::is_trivially_copyable<name>::value, \
26 "CRO structure " #name " isn't trivially copyable"); \
27 static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name)
28#else 28#else
29 #define ASSERT_CRO_STRUCT(name, size) \ 29#define ASSERT_CRO_STRUCT(name, size) \
30 static_assert(std::is_standard_layout<name>::value, "CRO structure " #name " doesn't use standard layout"); \ 30 static_assert(std::is_standard_layout<name>::value, \
31 static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) 31 "CRO structure " #name " doesn't use standard layout"); \
32 static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name)
32#endif 33#endif
33 34
34static constexpr u32 CRO_HEADER_SIZE = 0x138; 35static constexpr u32 CRO_HEADER_SIZE = 0x138;
@@ -37,8 +38,7 @@ static constexpr u32 CRO_HASH_SIZE = 0x80;
37/// Represents a loaded module (CRO) with interfaces manipulating it. 38/// Represents a loaded module (CRO) with interfaces manipulating it.
38class CROHelper final { 39class CROHelper final {
39public: 40public:
40 explicit CROHelper(VAddr cro_address) : module_address(cro_address) { 41 explicit CROHelper(VAddr cro_address) : module_address(cro_address) {}
41 }
42 42
43 std::string ModuleName() const { 43 std::string ModuleName() const {
44 return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); 44 return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize));
@@ -59,9 +59,9 @@ public:
59 * @param is_crs true if the module itself is the static module 59 * @param is_crs true if the module itself is the static module
60 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. 60 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code.
61 */ 61 */
62 ResultCode Rebase(VAddr crs_address, u32 cro_size, 62 ResultCode Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment_addresss,
63 VAddr data_segment_addresss, u32 data_segment_size, 63 u32 data_segment_size, VAddr bss_segment_address, u32 bss_segment_size,
64 VAddr bss_segment_address, u32 bss_segment_size, bool is_crs); 64 bool is_crs);
65 65
66 /** 66 /**
67 * Unrebases the module. 67 * Unrebases the module.
@@ -148,8 +148,9 @@ private:
148 const VAddr module_address; ///< the virtual address of this module 148 const VAddr module_address; ///< the virtual address of this module
149 149
150 /** 150 /**
151 * Each item in this enum represents a u32 field in the header begin from address+0x80, successively. 151 * Each item in this enum represents a u32 field in the header begin from address+0x80,
152 * We don't directly use a struct here, to avoid GetPointer, reinterpret_cast, or Read/WriteBlock repeatedly. 152 * successively. We don't directly use a struct here, to avoid GetPointer, reinterpret_cast, or
153 * Read/WriteBlock repeatedly.
153 */ 154 */
154 enum HeaderField { 155 enum HeaderField {
155 Magic = 0, 156 Magic = 0,
@@ -208,18 +209,20 @@ private:
208 Fix2Barrier = ImportModuleTableOffset, 209 Fix2Barrier = ImportModuleTableOffset,
209 Fix1Barrier = StaticAnonymousSymbolTableOffset, 210 Fix1Barrier = StaticAnonymousSymbolTableOffset,
210 }; 211 };
211 static_assert(Fix0Barrier == (CRO_HEADER_SIZE - CRO_HASH_SIZE) / 4, "CRO Header fields are wrong!"); 212 static_assert(Fix0Barrier == (CRO_HEADER_SIZE - CRO_HASH_SIZE) / 4,
213 "CRO Header fields are wrong!");
212 214
213 enum class SegmentType : u32 { 215 enum class SegmentType : u32 {
214 Code = 0, 216 Code = 0,
215 ROData = 1, 217 ROData = 1,
216 Data = 2, 218 Data = 2,
217 BSS = 3, 219 BSS = 3,
218 }; 220 };
219 221
220 /** 222 /**
221 * Identifies a program location inside of a segment. 223 * Identifies a program location inside of a segment.
222 * Required to refer to program locations because individual segments may be relocated independently of each other. 224 * Required to refer to program locations because individual segments may be relocated
225 * independently of each other.
223 */ 226 */
224 union SegmentTag { 227 union SegmentTag {
225 u32_le raw; 228 u32_le raw;
@@ -282,7 +285,7 @@ private:
282 285
283 /// Identifies an indexed symbol imported from another module. 286 /// Identifies an indexed symbol imported from another module.
284 struct ImportIndexedSymbolEntry { 287 struct ImportIndexedSymbolEntry {
285 u32_le index; // index of an ExportIndexedSymbolEntry in the exporting module 288 u32_le index; // index of an ExportIndexedSymbolEntry in the exporting module
286 u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable 289 u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable
287 290
288 static constexpr HeaderField TABLE_OFFSET_FIELD = ImportIndexedSymbolTableOffset; 291 static constexpr HeaderField TABLE_OFFSET_FIELD = ImportIndexedSymbolTableOffset;
@@ -291,8 +294,8 @@ private:
291 294
292 /// Identifies an anonymous symbol imported from another module. 295 /// Identifies an anonymous symbol imported from another module.
293 struct ImportAnonymousSymbolEntry { 296 struct ImportAnonymousSymbolEntry {
294 SegmentTag symbol_position; // in the exporting segment 297 SegmentTag symbol_position; // in the exporting segment
295 u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable 298 u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable
296 299
297 static constexpr HeaderField TABLE_OFFSET_FIELD = ImportAnonymousSymbolTableOffset; 300 static constexpr HeaderField TABLE_OFFSET_FIELD = ImportAnonymousSymbolTableOffset;
298 }; 301 };
@@ -300,42 +303,47 @@ private:
300 303
301 /// Information of a imported module and symbols imported from it. 304 /// Information of a imported module and symbols imported from it.
302 struct ImportModuleEntry { 305 struct ImportModuleEntry {
303 u32_le name_offset; // pointing to a substring in ImportStrings 306 u32_le name_offset; // pointing to a substring in ImportStrings
304 u32_le import_indexed_symbol_table_offset; // pointing to a subtable in ImportIndexedSymbolTable 307 u32_le import_indexed_symbol_table_offset; // pointing to a subtable in
308 // ImportIndexedSymbolTable
305 u32_le import_indexed_symbol_num; 309 u32_le import_indexed_symbol_num;
306 u32_le import_anonymous_symbol_table_offset; // pointing to a subtable in ImportAnonymousSymbolTable 310 u32_le import_anonymous_symbol_table_offset; // pointing to a subtable in
311 // ImportAnonymousSymbolTable
307 u32_le import_anonymous_symbol_num; 312 u32_le import_anonymous_symbol_num;
308 313
309 static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset; 314 static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset;
310 315
311 void GetImportIndexedSymbolEntry(u32 index, ImportIndexedSymbolEntry& entry) { 316 void GetImportIndexedSymbolEntry(u32 index, ImportIndexedSymbolEntry& entry) {
312 Memory::ReadBlock(import_indexed_symbol_table_offset + index * sizeof(ImportIndexedSymbolEntry), 317 Memory::ReadBlock(import_indexed_symbol_table_offset +
313 &entry, sizeof(ImportIndexedSymbolEntry)); 318 index * sizeof(ImportIndexedSymbolEntry),
319 &entry, sizeof(ImportIndexedSymbolEntry));
314 } 320 }
315 321
316 void GetImportAnonymousSymbolEntry(u32 index, ImportAnonymousSymbolEntry& entry) { 322 void GetImportAnonymousSymbolEntry(u32 index, ImportAnonymousSymbolEntry& entry) {
317 Memory::ReadBlock(import_anonymous_symbol_table_offset + index * sizeof(ImportAnonymousSymbolEntry), 323 Memory::ReadBlock(import_anonymous_symbol_table_offset +
318 &entry, sizeof(ImportAnonymousSymbolEntry)); 324 index * sizeof(ImportAnonymousSymbolEntry),
325 &entry, sizeof(ImportAnonymousSymbolEntry));
319 } 326 }
320 }; 327 };
321 ASSERT_CRO_STRUCT(ImportModuleEntry, 20); 328 ASSERT_CRO_STRUCT(ImportModuleEntry, 20);
322 329
323 enum class RelocationType : u8 { 330 enum class RelocationType : u8 {
324 Nothing = 0, 331 Nothing = 0,
325 AbsoluteAddress = 2, 332 AbsoluteAddress = 2,
326 RelativeAddress = 3, 333 RelativeAddress = 3,
327 ThumbBranch = 10, 334 ThumbBranch = 10,
328 ArmBranch = 28, 335 ArmBranch = 28,
329 ModifyArmBranch = 29, 336 ModifyArmBranch = 29,
330 AbsoluteAddress2 = 38, 337 AbsoluteAddress2 = 38,
331 AlignedRelativeAddress = 42, 338 AlignedRelativeAddress = 42,
332 }; 339 };
333 340
334 struct RelocationEntry { 341 struct RelocationEntry {
335 SegmentTag target_position; // to self's segment as an ExternalRelocationEntry; to static module segment as a StaticRelocationEntry 342 SegmentTag target_position; // to self's segment as an ExternalRelocationEntry; to static
343 // module segment as a StaticRelocationEntry
336 RelocationType type; 344 RelocationType type;
337 u8 is_batch_end; 345 u8 is_batch_end;
338 u8 is_batch_resolved; // set at a batch beginning if the batch is resolved 346 u8 is_batch_resolved; // set at a batch beginning if the batch is resolved
339 INSERT_PADDING_BYTES(1); 347 INSERT_PADDING_BYTES(1);
340 u32_le addend; 348 u32_le addend;
341 }; 349 };
@@ -366,8 +374,8 @@ private:
366 374
367 /// Identifies a special static anonymous symbol (no game is known using this). 375 /// Identifies a special static anonymous symbol (no game is known using this).
368 struct StaticAnonymousSymbolEntry { 376 struct StaticAnonymousSymbolEntry {
369 SegmentTag symbol_position; // to self's segment 377 SegmentTag symbol_position; // to self's segment
370 u32_le relocation_batch_offset; // pointing to a relocation batch in StaticRelocationTable 378 u32_le relocation_batch_offset; // pointing to a relocation batch in StaticRelocationTable
371 379
372 static constexpr HeaderField TABLE_OFFSET_FIELD = StaticAnonymousSymbolTableOffset; 380 static constexpr HeaderField TABLE_OFFSET_FIELD = StaticAnonymousSymbolTableOffset;
373 }; 381 };
@@ -446,12 +454,15 @@ private:
446 } 454 }
447 455
448 /** 456 /**
449 * A helper function iterating over all registered auto-link modules, including the static module. 457 * A helper function iterating over all registered auto-link modules, including the static
458 * module.
450 * @param crs_address the virtual address of the static module 459 * @param crs_address the virtual address of the static module
451 * @param func a function object to operate on a module. It accepts one parameter 460 * @param func a function object to operate on a module. It accepts one parameter
452 * CROHelper and returns ResultVal<bool>. It should return true to continue the iteration, 461 * CROHelper and returns ResultVal<bool>. It should return true to continue the
462 * iteration,
453 * false to stop the iteration, or an error code (which will also stop the iteration). 463 * false to stop the iteration, or an error code (which will also stop the iteration).
454 * @returns ResultCode indicating the result of the operation, RESULT_SUCCESS if all iteration success, 464 * @returns ResultCode indicating the result of the operation, RESULT_SUCCESS if all iteration
465 * success,
455 * otherwise error code of the last iteration. 466 * otherwise error code of the last iteration.
456 */ 467 */
457 template <typename FunctionObject> 468 template <typename FunctionObject>
@@ -477,8 +488,8 @@ private:
477 * Usually equals to target_address, but will be different for a target in .data segment 488 * Usually equals to target_address, but will be different for a target in .data segment
478 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. 489 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code.
479 */ 490 */
480 ResultCode ApplyRelocation(VAddr target_address, RelocationType relocation_type, 491 ResultCode ApplyRelocation(VAddr target_address, RelocationType relocation_type, u32 addend,
481 u32 addend, u32 symbol_address, u32 target_future_address); 492 u32 symbol_address, u32 target_future_address);
482 493
483 /** 494 /**
484 * Clears a relocation to zero 495 * Clears a relocation to zero
@@ -492,7 +503,8 @@ private:
492 * Applies or resets a batch of relocations 503 * Applies or resets a batch of relocations
493 * @param batch the virtual address of the first relocation in the batch 504 * @param batch the virtual address of the first relocation in the batch
494 * @param symbol_address the symbol address to be relocated with 505 * @param symbol_address the symbol address to be relocated with
495 * @param reset false to set the batch to resolved state, true to reset the batch to unresolved state 506 * @param reset false to set the batch to resolved state, true to reset the batch to unresolved
507 * state
496 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. 508 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code.
497 */ 509 */
498 ResultCode ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool reset = false); 510 ResultCode ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool reset = false);
@@ -507,7 +519,8 @@ private:
507 /** 519 /**
508 * Rebases offsets in module header according to module address. 520 * Rebases offsets in module header according to module address.
509 * @param cro_size the size of the CRO file 521 * @param cro_size the size of the CRO file
510 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. 522 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error
523 * code.
511 */ 524 */
512 ResultCode RebaseHeader(u32 cro_size); 525 ResultCode RebaseHeader(u32 cro_size);
513 526
@@ -520,43 +533,49 @@ private:
520 * @param bss_segment_size the buffer size for .bss segment 533 * @param bss_segment_size the buffer size for .bss segment
521 * @returns ResultVal<VAddr> with the virtual address of .data segment in CRO. 534 * @returns ResultVal<VAddr> with the virtual address of .data segment in CRO.
522 */ 535 */
523 ResultVal<VAddr> RebaseSegmentTable(u32 cro_size, 536 ResultVal<VAddr> RebaseSegmentTable(u32 cro_size, VAddr data_segment_address,
524 VAddr data_segment_address, u32 data_segment_size, 537 u32 data_segment_size, VAddr bss_segment_address,
525 VAddr bss_segment_address, u32 bss_segment_size); 538 u32 bss_segment_size);
526 539
527 /** 540 /**
528 * Rebases offsets in exported named symbol table according to module address. 541 * Rebases offsets in exported named symbol table according to module address.
529 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. 542 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error
543 * code.
530 */ 544 */
531 ResultCode RebaseExportNamedSymbolTable(); 545 ResultCode RebaseExportNamedSymbolTable();
532 546
533 /** 547 /**
534 * Verifies indices in export tree table. 548 * Verifies indices in export tree table.
535 * @returns ResultCode RESULT_SUCCESS if all indices are verified as valid, otherwise error code. 549 * @returns ResultCode RESULT_SUCCESS if all indices are verified as valid, otherwise error
550 * code.
536 */ 551 */
537 ResultCode VerifyExportTreeTable() const; 552 ResultCode VerifyExportTreeTable() const;
538 553
539 /** 554 /**
540 * Rebases offsets in exported module table according to module address. 555 * Rebases offsets in exported module table according to module address.
541 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. 556 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error
557 * code.
542 */ 558 */
543 ResultCode RebaseImportModuleTable(); 559 ResultCode RebaseImportModuleTable();
544 560
545 /** 561 /**
546 * Rebases offsets in imported named symbol table according to module address. 562 * Rebases offsets in imported named symbol table according to module address.
547 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. 563 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error
564 * code.
548 */ 565 */
549 ResultCode RebaseImportNamedSymbolTable(); 566 ResultCode RebaseImportNamedSymbolTable();
550 567
551 /** 568 /**
552 * Rebases offsets in imported indexed symbol table according to module address. 569 * Rebases offsets in imported indexed symbol table according to module address.
553 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. 570 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error
571 * code.
554 */ 572 */
555 ResultCode RebaseImportIndexedSymbolTable(); 573 ResultCode RebaseImportIndexedSymbolTable();
556 574
557 /** 575 /**
558 * Rebases offsets in imported anonymous symbol table according to module address. 576 * Rebases offsets in imported anonymous symbol table according to module address.
559 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. 577 * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error
578 * code.
560 */ 579 */
561 ResultCode RebaseImportAnonymousSymbolTable(); 580 ResultCode RebaseImportAnonymousSymbolTable();
562 581
@@ -621,7 +640,8 @@ private:
621 void UnrebaseHeader(); 640 void UnrebaseHeader();
622 641
623 /** 642 /**
624 * Looks up all imported named symbols of this module in all registered auto-link modules, and resolves them if found. 643 * Looks up all imported named symbols of this module in all registered auto-link modules, and
644 * resolves them if found.
625 * @param crs_address the virtual address of the static module 645 * @param crs_address the virtual address of the static module
626 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. 646 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code.
627 */ 647 */
@@ -646,7 +666,8 @@ private:
646 ResultCode ResetImportAnonymousSymbol(); 666 ResultCode ResetImportAnonymousSymbol();
647 667
648 /** 668 /**
649 * Finds registered auto-link modules that this module imports, and resolves indexed and anonymous symbols exported by them. 669 * Finds registered auto-link modules that this module imports, and resolves indexed and
670 * anonymous symbols exported by them.
650 * @param crs_address the virtual address of the static module 671 * @param crs_address the virtual address of the static module
651 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. 672 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code.
652 */ 673 */
@@ -667,7 +688,8 @@ private:
667 ResultCode ResetExportNamedSymbol(CROHelper target); 688 ResultCode ResetExportNamedSymbol(CROHelper target);
668 689
669 /** 690 /**
670 * Resolves imported indexed and anonymous symbols in the target module which imports this module. 691 * Resolves imported indexed and anonymous symbols in the target module which imports this
692 * module.
671 * @param target the module to resolve. 693 * @param target the module to resolve.
672 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. 694 * @returns ResultCode RESULT_SUCCESS on success, otherwise error code.
673 */ 695 */
diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp
index 8ba73ea8d..ec183d1f5 100644
--- a/src/core/hle/service/ldr_ro/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp
@@ -5,7 +5,6 @@
5#include "common/alignment.h" 5#include "common/alignment.h"
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8
9#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
10#include "core/hle/kernel/process.h" 9#include "core/hle/kernel/process.h"
11#include "core/hle/kernel/vm_manager.h" 10#include "core/hle/kernel/vm_manager.h"
@@ -18,24 +17,33 @@
18 17
19namespace LDR_RO { 18namespace LDR_RO {
20 19
21static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 20static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9
22 ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); 21 ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal,
23static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 22 ErrorLevel::Permanent);
24 ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); 23static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8
25static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F 24 ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal,
26 ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 25 ErrorLevel::Permanent);
27static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 26static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F
28 ResultCode(ErrorDescription::MisalignedAddress, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 27 ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument,
29static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2 28 ErrorLevel::Usage);
30 ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 29static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1
31static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F 30 ResultCode(ErrorDescription::MisalignedAddress, ErrorModule::RO, ErrorSummary::WrongArgument,
32 ResultCode(static_cast<ErrorDescription>(15), ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Usage); 31 ErrorLevel::Permanent);
33static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 32static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2
34 ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); 33 ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument,
35static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D 34 ErrorLevel::Permanent);
36 ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); 35static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F
37static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830 36 ResultCode(static_cast<ErrorDescription>(15), ErrorModule::RO, ErrorSummary::Internal,
38 ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent); 37 ErrorLevel::Usage);
38static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08
39 ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState,
40 ErrorLevel::Permanent);
41static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D
42 ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState,
43 ErrorLevel::Permanent);
44static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830
45 ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
46 ErrorSummary::WrongArgument, ErrorLevel::Permanent);
39 47
40static MemorySynchronizer memory_synchronizer; 48static MemorySynchronizer memory_synchronizer;
41 49
@@ -44,10 +52,10 @@ static VAddr loaded_crs; ///< the virtual address of the static module
44 52
45static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { 53static bool VerifyBufferState(VAddr buffer_ptr, u32 size) {
46 auto vma = Kernel::g_current_process->vm_manager.FindVMA(buffer_ptr); 54 auto vma = Kernel::g_current_process->vm_manager.FindVMA(buffer_ptr);
47 return vma != Kernel::g_current_process->vm_manager.vma_map.end() 55 return vma != Kernel::g_current_process->vm_manager.vma_map.end() &&
48 && vma->second.base + vma->second.size >= buffer_ptr + size 56 vma->second.base + vma->second.size >= buffer_ptr + size &&
49 && vma->second.permissions == Kernel::VMAPermission::ReadWrite 57 vma->second.permissions == Kernel::VMAPermission::ReadWrite &&
50 && vma->second.meminfo_state == Kernel::MemoryState::Private; 58 vma->second.meminfo_state == Kernel::MemoryState::Private;
51} 59}
52 60
53/** 61/**
@@ -66,13 +74,14 @@ static bool VerifyBufferState(VAddr buffer_ptr, u32 size) {
66static void Initialize(Service::Interface* self) { 74static void Initialize(Service::Interface* self) {
67 u32* cmd_buff = Kernel::GetCommandBuffer(); 75 u32* cmd_buff = Kernel::GetCommandBuffer();
68 VAddr crs_buffer_ptr = cmd_buff[1]; 76 VAddr crs_buffer_ptr = cmd_buff[1];
69 u32 crs_size = cmd_buff[2]; 77 u32 crs_size = cmd_buff[2];
70 VAddr crs_address = cmd_buff[3]; 78 VAddr crs_address = cmd_buff[3];
71 u32 descriptor = cmd_buff[4]; 79 u32 descriptor = cmd_buff[4];
72 u32 process = cmd_buff[5]; 80 u32 process = cmd_buff[5];
73 81
74 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, descriptor=0x%08X, process=0x%08X", 82 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, "
75 crs_buffer_ptr, crs_address, crs_size, descriptor, process); 83 "descriptor=0x%08X, process=0x%08X",
84 crs_buffer_ptr, crs_address, crs_size, descriptor, process);
76 85
77 if (descriptor != 0) { 86 if (descriptor != 0) {
78 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 87 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -119,7 +128,8 @@ static void Initialize(Service::Interface* self) {
119 return; 128 return;
120 } 129 }
121 130
122 if (crs_address < Memory::PROCESS_IMAGE_VADDR || crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) { 131 if (crs_address < Memory::PROCESS_IMAGE_VADDR ||
132 crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) {
123 LOG_ERROR(Service_LDR, "CRS mapping address is not in the process image region"); 133 LOG_ERROR(Service_LDR, "CRS mapping address is not in the process image region");
124 cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; 134 cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw;
125 return; 135 return;
@@ -131,14 +141,17 @@ static void Initialize(Service::Interface* self) {
131 // TODO(wwylele): should be memory aliasing 141 // TODO(wwylele): should be memory aliasing
132 std::shared_ptr<std::vector<u8>> crs_mem = std::make_shared<std::vector<u8>>(crs_size); 142 std::shared_ptr<std::vector<u8>> crs_mem = std::make_shared<std::vector<u8>>(crs_size);
133 Memory::ReadBlock(crs_buffer_ptr, crs_mem->data(), crs_size); 143 Memory::ReadBlock(crs_buffer_ptr, crs_mem->data(), crs_size);
134 result = Kernel::g_current_process->vm_manager.MapMemoryBlock(crs_address, crs_mem, 0, crs_size, Kernel::MemoryState::Code).Code(); 144 result = Kernel::g_current_process->vm_manager
145 .MapMemoryBlock(crs_address, crs_mem, 0, crs_size, Kernel::MemoryState::Code)
146 .Code();
135 if (result.IsError()) { 147 if (result.IsError()) {
136 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); 148 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw);
137 cmd_buff[1] = result.raw; 149 cmd_buff[1] = result.raw;
138 return; 150 return;
139 } 151 }
140 152
141 result = Kernel::g_current_process->vm_manager.ReprotectRange(crs_address, crs_size, Kernel::VMAPermission::Read); 153 result = Kernel::g_current_process->vm_manager.ReprotectRange(crs_address, crs_size,
154 Kernel::VMAPermission::Read);
142 if (result.IsError()) { 155 if (result.IsError()) {
143 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); 156 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw);
144 cmd_buff[1] = result.raw; 157 cmd_buff[1] = result.raw;
@@ -186,9 +199,9 @@ static void Initialize(Service::Interface* self) {
186static void LoadCRR(Service::Interface* self) { 199static void LoadCRR(Service::Interface* self) {
187 u32* cmd_buff = Kernel::GetCommandBuffer(); 200 u32* cmd_buff = Kernel::GetCommandBuffer();
188 u32 crr_buffer_ptr = cmd_buff[1]; 201 u32 crr_buffer_ptr = cmd_buff[1];
189 u32 crr_size = cmd_buff[2]; 202 u32 crr_size = cmd_buff[2];
190 u32 descriptor = cmd_buff[3]; 203 u32 descriptor = cmd_buff[3];
191 u32 process = cmd_buff[4]; 204 u32 process = cmd_buff[4];
192 205
193 if (descriptor != 0) { 206 if (descriptor != 0) {
194 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 207 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -200,7 +213,8 @@ static void LoadCRR(Service::Interface* self) {
200 cmd_buff[0] = IPC::MakeHeader(2, 1, 0); 213 cmd_buff[0] = IPC::MakeHeader(2, 1, 0);
201 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 214 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
202 215
203 LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, descriptor=0x%08X, process=0x%08X", 216 LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, "
217 "descriptor=0x%08X, process=0x%08X",
204 crr_buffer_ptr, crr_size, descriptor, process); 218 crr_buffer_ptr, crr_size, descriptor, process);
205} 219}
206 220
@@ -218,8 +232,8 @@ static void LoadCRR(Service::Interface* self) {
218static void UnloadCRR(Service::Interface* self) { 232static void UnloadCRR(Service::Interface* self) {
219 u32* cmd_buff = Kernel::GetCommandBuffer(); 233 u32* cmd_buff = Kernel::GetCommandBuffer();
220 u32 crr_buffer_ptr = cmd_buff[1]; 234 u32 crr_buffer_ptr = cmd_buff[1];
221 u32 descriptor = cmd_buff[2]; 235 u32 descriptor = cmd_buff[2];
222 u32 process = cmd_buff[3]; 236 u32 process = cmd_buff[3];
223 237
224 if (descriptor != 0) { 238 if (descriptor != 0) {
225 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 239 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -231,7 +245,8 @@ static void UnloadCRR(Service::Interface* self) {
231 cmd_buff[0] = IPC::MakeHeader(3, 1, 0); 245 cmd_buff[0] = IPC::MakeHeader(3, 1, 0);
232 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 246 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
233 247
234 LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", 248 LOG_WARNING(Service_LDR,
249 "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X",
235 crr_buffer_ptr, descriptor, process); 250 crr_buffer_ptr, descriptor, process);
236} 251}
237 252
@@ -263,27 +278,28 @@ static void UnloadCRR(Service::Interface* self) {
263 */ 278 */
264static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { 279static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
265 u32* cmd_buff = Kernel::GetCommandBuffer(); 280 u32* cmd_buff = Kernel::GetCommandBuffer();
266 VAddr cro_buffer_ptr = cmd_buff[1]; 281 VAddr cro_buffer_ptr = cmd_buff[1];
267 VAddr cro_address = cmd_buff[2]; 282 VAddr cro_address = cmd_buff[2];
268 u32 cro_size = cmd_buff[3]; 283 u32 cro_size = cmd_buff[3];
269 VAddr data_segment_address = cmd_buff[4]; 284 VAddr data_segment_address = cmd_buff[4];
270 u32 zero = cmd_buff[5]; 285 u32 zero = cmd_buff[5];
271 u32 data_segment_size = cmd_buff[6]; 286 u32 data_segment_size = cmd_buff[6];
272 u32 bss_segment_address = cmd_buff[7]; 287 u32 bss_segment_address = cmd_buff[7];
273 u32 bss_segment_size = cmd_buff[8]; 288 u32 bss_segment_size = cmd_buff[8];
274 bool auto_link = (cmd_buff[9] & 0xFF) != 0; 289 bool auto_link = (cmd_buff[9] & 0xFF) != 0;
275 u32 fix_level = cmd_buff[10]; 290 u32 fix_level = cmd_buff[10];
276 VAddr crr_address = cmd_buff[11]; 291 VAddr crr_address = cmd_buff[11];
277 u32 descriptor = cmd_buff[12]; 292 u32 descriptor = cmd_buff[12];
278 u32 process = cmd_buff[13]; 293 u32 process = cmd_buff[13];
279 294
280 LOG_DEBUG(Service_LDR, "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, " 295 LOG_DEBUG(Service_LDR,
281 "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, bss_segment_address=0x%08X, bss_segment_size=0x%X, " 296 "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, "
282 "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X", 297 "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, "
283 link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size, 298 "bss_segment_address=0x%08X, bss_segment_size=0x%X, "
284 data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size, 299 "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X",
285 auto_link ? "true" : "false", fix_level, crr_address, descriptor, process 300 link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size,
286 ); 301 data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size,
302 auto_link ? "true" : "false", fix_level, crr_address, descriptor, process);
287 303
288 if (descriptor != 0) { 304 if (descriptor != 0) {
289 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 305 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -330,8 +346,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
330 return; 346 return;
331 } 347 }
332 348
333 if (cro_address < Memory::PROCESS_IMAGE_VADDR 349 if (cro_address < Memory::PROCESS_IMAGE_VADDR ||
334 || cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) { 350 cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) {
335 LOG_ERROR(Service_LDR, "CRO mapping address is not in the process image region"); 351 LOG_ERROR(Service_LDR, "CRO mapping address is not in the process image region");
336 cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; 352 cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw;
337 return; 353 return;
@@ -339,7 +355,9 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
339 355
340 if (zero) { 356 if (zero) {
341 LOG_ERROR(Service_LDR, "Zero is not zero %d", zero); 357 LOG_ERROR(Service_LDR, "Zero is not zero %d", zero);
342 cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Usage).raw; 358 cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO,
359 ErrorSummary::Internal, ErrorLevel::Usage)
360 .raw;
343 return; 361 return;
344 } 362 }
345 363
@@ -349,14 +367,17 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
349 // TODO(wwylele): should be memory aliasing 367 // TODO(wwylele): should be memory aliasing
350 std::shared_ptr<std::vector<u8>> cro_mem = std::make_shared<std::vector<u8>>(cro_size); 368 std::shared_ptr<std::vector<u8>> cro_mem = std::make_shared<std::vector<u8>>(cro_size);
351 Memory::ReadBlock(cro_buffer_ptr, cro_mem->data(), cro_size); 369 Memory::ReadBlock(cro_buffer_ptr, cro_mem->data(), cro_size);
352 result = Kernel::g_current_process->vm_manager.MapMemoryBlock(cro_address, cro_mem, 0, cro_size, Kernel::MemoryState::Code).Code(); 370 result = Kernel::g_current_process->vm_manager
371 .MapMemoryBlock(cro_address, cro_mem, 0, cro_size, Kernel::MemoryState::Code)
372 .Code();
353 if (result.IsError()) { 373 if (result.IsError()) {
354 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); 374 LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw);
355 cmd_buff[1] = result.raw; 375 cmd_buff[1] = result.raw;
356 return; 376 return;
357 } 377 }
358 378
359 result = Kernel::g_current_process->vm_manager.ReprotectRange(cro_address, cro_size, Kernel::VMAPermission::Read); 379 result = Kernel::g_current_process->vm_manager.ReprotectRange(cro_address, cro_size,
380 Kernel::VMAPermission::Read);
360 if (result.IsError()) { 381 if (result.IsError()) {
361 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); 382 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw);
362 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 383 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
@@ -384,7 +405,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
384 return; 405 return;
385 } 406 }
386 407
387 result = cro.Rebase(loaded_crs, cro_size, data_segment_address, data_segment_size, bss_segment_address, bss_segment_size, false); 408 result = cro.Rebase(loaded_crs, cro_size, data_segment_address, data_segment_size,
409 bss_segment_address, bss_segment_size, false);
388 if (result.IsError()) { 410 if (result.IsError()) {
389 LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw); 411 LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw);
390 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 412 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
@@ -409,7 +431,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
409 // TODO(wwylele): verify the behaviour when buffer_ptr == address 431 // TODO(wwylele): verify the behaviour when buffer_ptr == address
410 if (cro_buffer_ptr != cro_address) { 432 if (cro_buffer_ptr != cro_address) {
411 if (fix_size != cro_size) { 433 if (fix_size != cro_size) {
412 result = Kernel::g_current_process->vm_manager.UnmapRange(cro_address + fix_size, cro_size - fix_size); 434 result = Kernel::g_current_process->vm_manager.UnmapRange(cro_address + fix_size,
435 cro_size - fix_size);
413 if (result.IsError()) { 436 if (result.IsError()) {
414 LOG_ERROR(Service_LDR, "Error unmapping memory block %08X", result.raw); 437 LOG_ERROR(Service_LDR, "Error unmapping memory block %08X", result.raw);
415 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); 438 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size);
@@ -426,7 +449,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
426 u32 exe_size; 449 u32 exe_size;
427 std::tie(exe_begin, exe_size) = cro.GetExecutablePages(); 450 std::tie(exe_begin, exe_size) = cro.GetExecutablePages();
428 if (exe_begin) { 451 if (exe_begin) {
429 result = Kernel::g_current_process->vm_manager.ReprotectRange(exe_begin, exe_size, Kernel::VMAPermission::ReadExecute); 452 result = Kernel::g_current_process->vm_manager.ReprotectRange(
453 exe_begin, exe_size, Kernel::VMAPermission::ReadExecute);
430 if (result.IsError()) { 454 if (result.IsError()) {
431 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); 455 LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw);
432 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, fix_size); 456 Kernel::g_current_process->vm_manager.UnmapRange(cro_address, fix_size);
@@ -437,8 +461,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) {
437 461
438 Core::g_app_core->ClearInstructionCache(); 462 Core::g_app_core->ClearInstructionCache();
439 463
440 LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", 464 LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(),
441 cro.ModuleName().data(), cro_address, cro_address+fix_size); 465 cro_address, cro_address + fix_size);
442 466
443 cmd_buff[1] = RESULT_SUCCESS.raw; 467 cmd_buff[1] = RESULT_SUCCESS.raw;
444 cmd_buff[2] = fix_size; 468 cmd_buff[2] = fix_size;
@@ -464,14 +488,15 @@ static void LoadCRO(Service::Interface* self) {
464 */ 488 */
465static void UnloadCRO(Service::Interface* self) { 489static void UnloadCRO(Service::Interface* self) {
466 u32* cmd_buff = Kernel::GetCommandBuffer(); 490 u32* cmd_buff = Kernel::GetCommandBuffer();
467 VAddr cro_address = cmd_buff[1]; 491 VAddr cro_address = cmd_buff[1];
468 u32 zero = cmd_buff[2]; 492 u32 zero = cmd_buff[2];
469 VAddr cro_buffer_ptr = cmd_buff[3]; 493 VAddr cro_buffer_ptr = cmd_buff[3];
470 u32 descriptor = cmd_buff[4]; 494 u32 descriptor = cmd_buff[4];
471 u32 process = cmd_buff[5]; 495 u32 process = cmd_buff[5];
472 496
473 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", 497 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, "
474 cro_address, zero, cro_buffer_ptr, descriptor, process); 498 "descriptor=0x%08X, process=0x%08X",
499 cro_address, zero, cro_buffer_ptr, descriptor, process);
475 500
476 if (descriptor != 0) { 501 if (descriptor != 0) {
477 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 502 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -558,11 +583,11 @@ static void UnloadCRO(Service::Interface* self) {
558static void LinkCRO(Service::Interface* self) { 583static void LinkCRO(Service::Interface* self) {
559 u32* cmd_buff = Kernel::GetCommandBuffer(); 584 u32* cmd_buff = Kernel::GetCommandBuffer();
560 VAddr cro_address = cmd_buff[1]; 585 VAddr cro_address = cmd_buff[1];
561 u32 descriptor = cmd_buff[2]; 586 u32 descriptor = cmd_buff[2];
562 u32 process = cmd_buff[3]; 587 u32 process = cmd_buff[3];
563 588
564 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X", 589 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X",
565 cro_address, descriptor, process); 590 cro_address, descriptor, process);
566 591
567 if (descriptor != 0) { 592 if (descriptor != 0) {
568 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 593 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -620,11 +645,11 @@ static void LinkCRO(Service::Interface* self) {
620static void UnlinkCRO(Service::Interface* self) { 645static void UnlinkCRO(Service::Interface* self) {
621 u32* cmd_buff = Kernel::GetCommandBuffer(); 646 u32* cmd_buff = Kernel::GetCommandBuffer();
622 VAddr cro_address = cmd_buff[1]; 647 VAddr cro_address = cmd_buff[1];
623 u32 descriptor = cmd_buff[2]; 648 u32 descriptor = cmd_buff[2];
624 u32 process = cmd_buff[3]; 649 u32 process = cmd_buff[3];
625 650
626 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X", 651 LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X",
627 cro_address, descriptor, process); 652 cro_address, descriptor, process);
628 653
629 if (descriptor != 0) { 654 if (descriptor != 0) {
630 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 655 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -682,11 +707,11 @@ static void UnlinkCRO(Service::Interface* self) {
682static void Shutdown(Service::Interface* self) { 707static void Shutdown(Service::Interface* self) {
683 u32* cmd_buff = Kernel::GetCommandBuffer(); 708 u32* cmd_buff = Kernel::GetCommandBuffer();
684 VAddr crs_buffer_ptr = cmd_buff[1]; 709 VAddr crs_buffer_ptr = cmd_buff[1];
685 u32 descriptor = cmd_buff[2]; 710 u32 descriptor = cmd_buff[2];
686 u32 process = cmd_buff[3]; 711 u32 process = cmd_buff[3];
687 712
688 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", 713 LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X",
689 crs_buffer_ptr, descriptor, process); 714 crs_buffer_ptr, descriptor, process);
690 715
691 if (descriptor != 0) { 716 if (descriptor != 0) {
692 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); 717 LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor);
@@ -724,15 +749,17 @@ static void Shutdown(Service::Interface* self) {
724} 749}
725 750
726const Interface::FunctionInfo FunctionTable[] = { 751const Interface::FunctionInfo FunctionTable[] = {
727 {0x000100C2, Initialize, "Initialize"}, 752 // clang-format off
728 {0x00020082, LoadCRR, "LoadCRR"}, 753 {0x000100C2, Initialize, "Initialize"},
729 {0x00030042, UnloadCRR, "UnloadCRR"}, 754 {0x00020082, LoadCRR, "LoadCRR"},
730 {0x000402C2, LoadCRO<false>, "LoadCRO"}, 755 {0x00030042, UnloadCRR, "UnloadCRR"},
731 {0x000500C2, UnloadCRO, "UnloadCRO"}, 756 {0x000402C2, LoadCRO<false>, "LoadCRO"},
732 {0x00060042, LinkCRO, "LinkCRO"}, 757 {0x000500C2, UnloadCRO, "UnloadCRO"},
733 {0x00070042, UnlinkCRO, "UnlinkCRO"}, 758 {0x00060042, LinkCRO, "LinkCRO"},
734 {0x00080042, Shutdown, "Shutdown"}, 759 {0x00070042, UnlinkCRO, "UnlinkCRO"},
735 {0x000902C2, LoadCRO<true>, "LoadCRO_New"}, 760 {0x00080042, Shutdown, "Shutdown"},
761 {0x000902C2, LoadCRO<true>, "LoadCRO_New"},
762 // clang-format on
736}; 763};
737 764
738//////////////////////////////////////////////////////////////////////////////////////////////////// 765////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp
index 4402876e6..989887264 100644
--- a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp
+++ b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp
@@ -3,9 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6
7#include "common/assert.h" 6#include "common/assert.h"
8
9#include "core/hle/service/ldr_ro/memory_synchronizer.h" 7#include "core/hle/service/ldr_ro/memory_synchronizer.h"
10 8
11//////////////////////////////////////////////////////////////////////////////////////////////////// 9////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -14,9 +12,8 @@
14namespace LDR_RO { 12namespace LDR_RO {
15 13
16auto MemorySynchronizer::FindMemoryBlock(VAddr mapping, VAddr original) { 14auto MemorySynchronizer::FindMemoryBlock(VAddr mapping, VAddr original) {
17 auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(), [=](MemoryBlock& b){ 15 auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(),
18 return b.original == original; 16 [=](MemoryBlock& b) { return b.original == original; });
19 });
20 ASSERT(block->mapping == mapping); 17 ASSERT(block->mapping == mapping);
21 return block; 18 return block;
22} 19}
diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.h b/src/core/hle/service/ldr_ro/memory_synchronizer.h
index 92f267912..883ee4acf 100644
--- a/src/core/hle/service/ldr_ro/memory_synchronizer.h
+++ b/src/core/hle/service/ldr_ro/memory_synchronizer.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include <vector> 7#include <vector>
8
9#include "core/memory.h" 8#include "core/memory.h"
10 9
11//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp
index f792bc9cd..edd1ea97b 100644
--- a/src/core/hle/service/mic_u.cpp
+++ b/src/core/hle/service/mic_u.cpp
@@ -10,22 +10,22 @@
10namespace MIC_U { 10namespace MIC_U {
11 11
12const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010042, nullptr, "MapSharedMem"}, 13 {0x00010042, nullptr, "MapSharedMem"},
14 {0x00020000, nullptr, "UnmapSharedMem"}, 14 {0x00020000, nullptr, "UnmapSharedMem"},
15 {0x00030140, nullptr, "Initialize"}, 15 {0x00030140, nullptr, "Initialize"},
16 {0x00040040, nullptr, "AdjustSampling"}, 16 {0x00040040, nullptr, "AdjustSampling"},
17 {0x00050000, nullptr, "StopSampling"}, 17 {0x00050000, nullptr, "StopSampling"},
18 {0x00060000, nullptr, "IsSampling"}, 18 {0x00060000, nullptr, "IsSampling"},
19 {0x00070000, nullptr, "GetEventHandle"}, 19 {0x00070000, nullptr, "GetEventHandle"},
20 {0x00080040, nullptr, "SetGain"}, 20 {0x00080040, nullptr, "SetGain"},
21 {0x00090000, nullptr, "GetGain"}, 21 {0x00090000, nullptr, "GetGain"},
22 {0x000A0040, nullptr, "SetPower"}, 22 {0x000A0040, nullptr, "SetPower"},
23 {0x000B0000, nullptr, "GetPower"}, 23 {0x000B0000, nullptr, "GetPower"},
24 {0x000C0042, nullptr, "size"}, 24 {0x000C0042, nullptr, "size"},
25 {0x000D0040, nullptr, "SetClamp"}, 25 {0x000D0040, nullptr, "SetClamp"},
26 {0x000E0000, nullptr, "GetClamp"}, 26 {0x000E0000, nullptr, "GetClamp"},
27 {0x000F0040, nullptr, "SetAllowShellClosed"}, 27 {0x000F0040, nullptr, "SetAllowShellClosed"},
28 {0x00100040, nullptr, "unknown_input2"}, 28 {0x00100040, nullptr, "unknown_input2"},
29}; 29};
30 30
31//////////////////////////////////////////////////////////////////////////////////////////////////// 31////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ndm/ndm.cpp b/src/core/hle/service/ndm/ndm.cpp
index bc9c3413d..5eb97f0d3 100644
--- a/src/core/hle/service/ndm/ndm.cpp
+++ b/src/core/hle/service/ndm/ndm.cpp
@@ -4,21 +4,23 @@
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/service/service.h"
8#include "core/hle/service/ndm/ndm.h" 7#include "core/hle/service/ndm/ndm.h"
9#include "core/hle/service/ndm/ndm_u.h" 8#include "core/hle/service/ndm/ndm_u.h"
9#include "core/hle/service/service.h"
10 10
11namespace Service { 11namespace Service {
12namespace NDM { 12namespace NDM {
13 13
14enum : u32 { 14enum : u32 {
15 DEFAULT_RETRY_INTERVAL = 10, 15 DEFAULT_RETRY_INTERVAL = 10,
16 DEFAULT_SCAN_INTERVAL = 30 16 DEFAULT_SCAN_INTERVAL = 30,
17}; 17};
18 18
19static DaemonMask daemon_bit_mask = DaemonMask::Default; 19static DaemonMask daemon_bit_mask = DaemonMask::Default;
20static DaemonMask default_daemon_bit_mask = DaemonMask::Default; 20static DaemonMask default_daemon_bit_mask = DaemonMask::Default;
21static std::array<DaemonStatus, 4> daemon_status = { DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle }; 21static std::array<DaemonStatus, 4> daemon_status = {
22 DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle,
23};
22static ExclusiveState exclusive_state = ExclusiveState::None; 24static ExclusiveState exclusive_state = ExclusiveState::None;
23static u32 scan_interval = DEFAULT_SCAN_INTERVAL; 25static u32 scan_interval = DEFAULT_SCAN_INTERVAL;
24static u32 retry_interval = DEFAULT_RETRY_INTERVAL; 26static u32 retry_interval = DEFAULT_RETRY_INTERVAL;
@@ -72,7 +74,8 @@ void UnlockState(Service::Interface* self) {
72void SuspendDaemons(Service::Interface* self) { 74void SuspendDaemons(Service::Interface* self) {
73 u32* cmd_buff = Kernel::GetCommandBuffer(); 75 u32* cmd_buff = Kernel::GetCommandBuffer();
74 u32 bit_mask = cmd_buff[1] & 0xF; 76 u32 bit_mask = cmd_buff[1] & 0xF;
75 daemon_bit_mask = static_cast<DaemonMask>(static_cast<u32>(default_daemon_bit_mask) & ~bit_mask); 77 daemon_bit_mask =
78 static_cast<DaemonMask>(static_cast<u32>(default_daemon_bit_mask) & ~bit_mask);
76 for (size_t index = 0; index < daemon_status.size(); ++index) { 79 for (size_t index = 0; index < daemon_status.size(); ++index) {
77 if (bit_mask & (1 << index)) { 80 if (bit_mask & (1 << index)) {
78 daemon_status[index] = DaemonStatus::Suspended; 81 daemon_status[index] = DaemonStatus::Suspended;
@@ -228,9 +231,7 @@ void Init() {
228 AddService(new NDM_U_Interface); 231 AddService(new NDM_U_Interface);
229} 232}
230 233
231void Shutdown() { 234void Shutdown() {}
232
233}
234 235
235}// namespace NDM 236} // namespace NDM
236}// namespace Service 237} // namespace Service
diff --git a/src/core/hle/service/ndm/ndm.h b/src/core/hle/service/ndm/ndm.h
index 5c2b968dc..979e7fcf1 100644
--- a/src/core/hle/service/ndm/ndm.h
+++ b/src/core/hle/service/ndm/ndm.h
@@ -13,35 +13,30 @@ class Interface;
13namespace NDM { 13namespace NDM {
14 14
15enum class Daemon : u32 { 15enum class Daemon : u32 {
16 Cec = 0, 16 Cec = 0,
17 Boss = 1, 17 Boss = 1,
18 Nim = 2, 18 Nim = 2,
19 Friend = 3 19 Friend = 3,
20}; 20};
21 21
22enum class DaemonMask : u32 { 22enum class DaemonMask : u32 {
23 None = 0, 23 None = 0,
24 Cec = (1 << static_cast<u32>(Daemon::Cec)), 24 Cec = (1 << static_cast<u32>(Daemon::Cec)),
25 Boss = (1 << static_cast<u32>(Daemon::Boss)), 25 Boss = (1 << static_cast<u32>(Daemon::Boss)),
26 Nim = (1 << static_cast<u32>(Daemon::Nim)), 26 Nim = (1 << static_cast<u32>(Daemon::Nim)),
27 Friend = (1 << static_cast<u32>(Daemon::Friend)), 27 Friend = (1 << static_cast<u32>(Daemon::Friend)),
28 Default = Cec | Friend, 28 Default = Cec | Friend,
29 All = Cec | Boss | Nim | Friend 29 All = Cec | Boss | Nim | Friend,
30}; 30};
31 31
32enum class DaemonStatus : u32 { 32enum class DaemonStatus : u32 { Busy = 0, Idle = 1, Suspending = 2, Suspended = 3 };
33 Busy = 0,
34 Idle = 1,
35 Suspending = 2,
36 Suspended = 3
37};
38 33
39enum class ExclusiveState : u32 { 34enum class ExclusiveState : u32 {
40 None = 0, 35 None = 0,
41 Infrastructure = 1, 36 Infrastructure = 1,
42 LocalCommunications = 2, 37 LocalCommunications = 2,
43 Streetpass = 3, 38 Streetpass = 3,
44 StreetpassData = 4, 39 StreetpassData = 4,
45}; 40};
46 41
47/** 42/**
@@ -205,7 +200,6 @@ void SetRetryInterval(Service::Interface* self);
205 */ 200 */
206void GetRetryInterval(Service::Interface* self); 201void GetRetryInterval(Service::Interface* self);
207 202
208
209/** 203/**
210 * NDM::OverrideDefaultDaemons service function 204 * NDM::OverrideDefaultDaemons service function
211 * Inputs: 205 * Inputs:
@@ -233,7 +227,8 @@ void ResetDefaultDaemons(Service::Interface* self);
233 * 1 : Result, 0 on success, otherwise error code 227 * 1 : Result, 0 on success, otherwise error code
234 * 2 : Daemon bit mask 228 * 2 : Daemon bit mask
235 * Note: 229 * Note:
236 * Gets the current default daemon bit mask. The default value is (DAEMONMASK_CEC | DAEMONMASK_FRIENDS) 230 * Gets the current default daemon bit mask. The default value is (DAEMONMASK_CEC |
231 * DAEMONMASK_FRIENDS)
237 */ 232 */
238void GetDefaultDaemons(Service::Interface* self); 233void GetDefaultDaemons(Service::Interface* self);
239 234
@@ -252,5 +247,5 @@ void Init();
252/// Shutdown NDM service 247/// Shutdown NDM service
253void Shutdown(); 248void Shutdown();
254 249
255}// namespace NDM 250} // namespace NDM
256}// namespace Service 251} // namespace Service
diff --git a/src/core/hle/service/ndm/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp
index 3ff0744ee..f5c7a341a 100644
--- a/src/core/hle/service/ndm/ndm_u.cpp
+++ b/src/core/hle/service/ndm/ndm_u.cpp
@@ -9,28 +9,28 @@ namespace Service {
9namespace NDM { 9namespace NDM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010042, EnterExclusiveState, "EnterExclusiveState"}, 12 {0x00010042, EnterExclusiveState, "EnterExclusiveState"},
13 {0x00020002, LeaveExclusiveState, "LeaveExclusiveState"}, 13 {0x00020002, LeaveExclusiveState, "LeaveExclusiveState"},
14 {0x00030000, QueryExclusiveMode, "QueryExclusiveMode"}, 14 {0x00030000, QueryExclusiveMode, "QueryExclusiveMode"},
15 {0x00040002, LockState, "LockState"}, 15 {0x00040002, LockState, "LockState"},
16 {0x00050002, UnlockState, "UnlockState"}, 16 {0x00050002, UnlockState, "UnlockState"},
17 {0x00060040, SuspendDaemons, "SuspendDaemons"}, 17 {0x00060040, SuspendDaemons, "SuspendDaemons"},
18 {0x00070040, ResumeDaemons, "ResumeDaemons"}, 18 {0x00070040, ResumeDaemons, "ResumeDaemons"},
19 {0x00080040, SuspendScheduler, "SuspendScheduler"}, 19 {0x00080040, SuspendScheduler, "SuspendScheduler"},
20 {0x00090000, ResumeScheduler, "ResumeScheduler"}, 20 {0x00090000, ResumeScheduler, "ResumeScheduler"},
21 {0x000A0000, nullptr, "GetCurrentState"}, 21 {0x000A0000, nullptr, "GetCurrentState"},
22 {0x000B0000, nullptr, "GetTargetState"}, 22 {0x000B0000, nullptr, "GetTargetState"},
23 {0x000C0000, nullptr, "<Stubbed>"}, 23 {0x000C0000, nullptr, "<Stubbed>"},
24 {0x000D0040, QueryStatus, "QueryStatus"}, 24 {0x000D0040, QueryStatus, "QueryStatus"},
25 {0x000E0040, GetDaemonDisableCount, "GetDaemonDisableCount"}, 25 {0x000E0040, GetDaemonDisableCount, "GetDaemonDisableCount"},
26 {0x000F0000, GetSchedulerDisableCount,"GetSchedulerDisableCount"}, 26 {0x000F0000, GetSchedulerDisableCount, "GetSchedulerDisableCount"},
27 {0x00100040, SetScanInterval, "SetScanInterval"}, 27 {0x00100040, SetScanInterval, "SetScanInterval"},
28 {0x00110000, GetScanInterval, "GetScanInterval"}, 28 {0x00110000, GetScanInterval, "GetScanInterval"},
29 {0x00120040, SetRetryInterval, "SetRetryInterval"}, 29 {0x00120040, SetRetryInterval, "SetRetryInterval"},
30 {0x00130000, GetRetryInterval, "GetRetryInterval"}, 30 {0x00130000, GetRetryInterval, "GetRetryInterval"},
31 {0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"}, 31 {0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"},
32 {0x00150000, ResetDefaultDaemons, "ResetDefaultDaemons"}, 32 {0x00150000, ResetDefaultDaemons, "ResetDefaultDaemons"},
33 {0x00160000, GetDefaultDaemons, "GetDefaultDaemons"}, 33 {0x00160000, GetDefaultDaemons, "GetDefaultDaemons"},
34 {0x00170000, ClearHalfAwakeMacFilter, "ClearHalfAwakeMacFilter"}, 34 {0x00170000, ClearHalfAwakeMacFilter, "ClearHalfAwakeMacFilter"},
35}; 35};
36 36
diff --git a/src/core/hle/service/news/news.cpp b/src/core/hle/service/news/news.cpp
index b3f500694..8b70ec45b 100644
--- a/src/core/hle/service/news/news.cpp
+++ b/src/core/hle/service/news/news.cpp
@@ -3,11 +3,10 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/news/news.h" 6#include "core/hle/service/news/news.h"
9#include "core/hle/service/news/news_s.h" 7#include "core/hle/service/news/news_s.h"
10#include "core/hle/service/news/news_u.h" 8#include "core/hle/service/news/news_u.h"
9#include "core/hle/service/service.h"
11 10
12namespace Service { 11namespace Service {
13namespace NEWS { 12namespace NEWS {
@@ -19,8 +18,7 @@ void Init() {
19 AddService(new NEWS_U_Interface); 18 AddService(new NEWS_U_Interface);
20} 19}
21 20
22void Shutdown() { 21void Shutdown() {}
23}
24 22
25} // namespace NEWS 23} // namespace NEWS
26 24
diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp
index 39b5a50f8..dda3d0f6a 100644
--- a/src/core/hle/service/news/news_s.cpp
+++ b/src/core/hle/service/news/news_s.cpp
@@ -9,19 +9,19 @@ namespace Service {
9namespace NEWS { 9namespace NEWS {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x000100C6, nullptr, "AddNotification"}, 12 {0x000100C6, nullptr, "AddNotification"},
13 {0x00050000, nullptr, "GetTotalNotifications"}, 13 {0x00050000, nullptr, "GetTotalNotifications"},
14 {0x00060042, nullptr, "SetNewsDBHeader"}, 14 {0x00060042, nullptr, "SetNewsDBHeader"},
15 {0x00070082, nullptr, "SetNotificationHeader"}, 15 {0x00070082, nullptr, "SetNotificationHeader"},
16 {0x00080082, nullptr, "SetNotificationMessage"}, 16 {0x00080082, nullptr, "SetNotificationMessage"},
17 {0x00090082, nullptr, "SetNotificationImage"}, 17 {0x00090082, nullptr, "SetNotificationImage"},
18 {0x000A0042, nullptr, "GetNewsDBHeader"}, 18 {0x000A0042, nullptr, "GetNewsDBHeader"},
19 {0x000B0082, nullptr, "GetNotificationHeader"}, 19 {0x000B0082, nullptr, "GetNotificationHeader"},
20 {0x000C0082, nullptr, "GetNotificationMessage"}, 20 {0x000C0082, nullptr, "GetNotificationMessage"},
21 {0x000D0082, nullptr, "GetNotificationImage"}, 21 {0x000D0082, nullptr, "GetNotificationImage"},
22 {0x000E0040, nullptr, "SetInfoLEDPattern"}, 22 {0x000E0040, nullptr, "SetInfoLEDPattern"},
23 {0x00120082, nullptr, "GetNotificationHeaderOther"}, 23 {0x00120082, nullptr, "GetNotificationHeaderOther"},
24 {0x00130000, nullptr, "WriteNewsDBSavedata"}, 24 {0x00130000, nullptr, "WriteNewsDBSavedata"},
25}; 25};
26 26
27NEWS_S_Interface::NEWS_S_Interface() { 27NEWS_S_Interface::NEWS_S_Interface() {
diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp
index 6b75cc24e..a07e466de 100644
--- a/src/core/hle/service/news/news_u.cpp
+++ b/src/core/hle/service/news/news_u.cpp
@@ -8,7 +8,7 @@ namespace Service {
8namespace NEWS { 8namespace NEWS {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x000100C6, nullptr, "AddNotification"}, 11 {0x000100C6, nullptr, "AddNotification"},
12}; 12};
13 13
14NEWS_U_Interface::NEWS_U_Interface() { 14NEWS_U_Interface::NEWS_U_Interface() {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index ed42464ce..0be94322c 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -4,12 +4,11 @@
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7
8#include "core/hle/service/service.h"
9#include "core/hle/service/nim/nim.h" 7#include "core/hle/service/nim/nim.h"
10#include "core/hle/service/nim/nim_aoc.h" 8#include "core/hle/service/nim/nim_aoc.h"
11#include "core/hle/service/nim/nim_s.h" 9#include "core/hle/service/nim/nim_s.h"
12#include "core/hle/service/nim/nim_u.h" 10#include "core/hle/service/nim/nim_u.h"
11#include "core/hle/service/service.h"
13 12
14namespace Service { 13namespace Service {
15namespace NIM { 14namespace NIM {
@@ -31,8 +30,7 @@ void Init() {
31 AddService(new NIM_U_Interface); 30 AddService(new NIM_U_Interface);
32} 31}
33 32
34void Shutdown() { 33void Shutdown() {}
35}
36 34
37} // namespace NIM 35} // namespace NIM
38 36
diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp
index 4a4818d57..2d0fb6fc4 100644
--- a/src/core/hle/service/nim/nim_aoc.cpp
+++ b/src/core/hle/service/nim/nim_aoc.cpp
@@ -8,14 +8,14 @@ namespace Service {
8namespace NIM { 8namespace NIM {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x00030042, nullptr, "SetApplicationId"}, 11 {0x00030042, nullptr, "SetApplicationId"},
12 {0x00040042, nullptr, "SetTin"}, 12 {0x00040042, nullptr, "SetTin"},
13 {0x000902D0, nullptr, "ListContentSetsEx"}, 13 {0x000902D0, nullptr, "ListContentSetsEx"},
14 {0x00180000, nullptr, "GetBalance"}, 14 {0x00180000, nullptr, "GetBalance"},
15 {0x001D0000, nullptr, "GetCustomerSupportCode"}, 15 {0x001D0000, nullptr, "GetCustomerSupportCode"},
16 {0x00210000, nullptr, "Initialize"}, 16 {0x00210000, nullptr, "Initialize"},
17 {0x00240282, nullptr, "CalculateContentsRequiredSize"}, 17 {0x00240282, nullptr, "CalculateContentsRequiredSize"},
18 {0x00250000, nullptr, "RefreshServerTime"}, 18 {0x00250000, nullptr, "RefreshServerTime"},
19}; 19};
20 20
21NIM_AOC_Interface::NIM_AOC_Interface() { 21NIM_AOC_Interface::NIM_AOC_Interface() {
diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp
index dcaa0255a..e2ba693c9 100644
--- a/src/core/hle/service/nim/nim_s.cpp
+++ b/src/core/hle/service/nim/nim_s.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace NIM { 8namespace NIM {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"}, 11 {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"},
12 {0x0016020A, nullptr, "ListTitles"}, 12 {0x0016020A, nullptr, "ListTitles"},
13 {0x002D0042, nullptr, "DownloadTickets"}, 13 {0x002D0042, nullptr, "DownloadTickets"},
14 {0x00420240, nullptr, "StartDownload"}, 14 {0x00420240, nullptr, "StartDownload"},
15}; 15};
16 16
17NIM_S_Interface::NIM_S_Interface() { 17NIM_S_Interface::NIM_S_Interface() {
@@ -20,4 +20,3 @@ NIM_S_Interface::NIM_S_Interface() {
20 20
21} // namespace NIM 21} // namespace NIM
22} // namespace Service 22} // namespace Service
23
diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp
index eae45ebc0..7e07d02e8 100644
--- a/src/core/hle/service/nim/nim_u.cpp
+++ b/src/core/hle/service/nim/nim_u.cpp
@@ -9,12 +9,12 @@ namespace Service {
9namespace NIM { 9namespace NIM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010000, nullptr, "StartSysUpdate"}, 12 {0x00010000, nullptr, "StartSysUpdate"},
13 {0x00020000, nullptr, "GetUpdateDownloadProgress"}, 13 {0x00020000, nullptr, "GetUpdateDownloadProgress"},
14 {0x00040000, nullptr, "FinishTitlesInstall"}, 14 {0x00040000, nullptr, "FinishTitlesInstall"},
15 {0x00050000, nullptr, "CheckForSysUpdateEvent"}, 15 {0x00050000, nullptr, "CheckForSysUpdateEvent"},
16 {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"}, 16 {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
17 {0x000A0000, nullptr, "GetState"}, 17 {0x000A0000, nullptr, "GetState"},
18}; 18};
19 19
20NIM_U_Interface::NIM_U_Interface() { 20NIM_U_Interface::NIM_U_Interface() {
@@ -23,4 +23,3 @@ NIM_U_Interface::NIM_U_Interface() {
23 23
24} // namespace NIM 24} // namespace NIM
25} // namespace Service 25} // namespace Service
26
diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h
index bc89dc0f3..c4b74985a 100644
--- a/src/core/hle/service/nim/nim_u.h
+++ b/src/core/hle/service/nim/nim_u.h
@@ -1,6 +1,6 @@
1// Copyright 2015 Citra Emulator Project 1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.. 3// Refer to the license.txt file included.
4 4
5#pragma once 5#pragma once
6 6
diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp
index 072918d62..6693f7c08 100644
--- a/src/core/hle/service/ns_s.cpp
+++ b/src/core/hle/service/ns_s.cpp
@@ -10,21 +10,21 @@
10namespace NS_S { 10namespace NS_S {
11 11
12const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
13 {0x000100C0, nullptr, "LaunchFIRM"}, 13 {0x000100C0, nullptr, "LaunchFIRM"},
14 {0x000200C0, nullptr, "LaunchTitle"}, 14 {0x000200C0, nullptr, "LaunchTitle"},
15 {0x00030000, nullptr, "TerminateApplication"}, 15 {0x00030000, nullptr, "TerminateApplication"},
16 {0x00040040, nullptr, "TerminateProcess"}, 16 {0x00040040, nullptr, "TerminateProcess"},
17 {0x000500C0, nullptr, "LaunchApplicationFIRM"}, 17 {0x000500C0, nullptr, "LaunchApplicationFIRM"},
18 {0x00060042, nullptr, "SetFIRMParams4A0"}, 18 {0x00060042, nullptr, "SetFIRMParams4A0"},
19 {0x00070042, nullptr, "CardUpdateInitialize"}, 19 {0x00070042, nullptr, "CardUpdateInitialize"},
20 {0x00080000, nullptr, "CardUpdateShutdown"}, 20 {0x00080000, nullptr, "CardUpdateShutdown"},
21 {0x000D0140, nullptr, "SetTWLBannerHMAC"}, 21 {0x000D0140, nullptr, "SetTWLBannerHMAC"},
22 {0x000E0000, nullptr, "ShutdownAsync"}, 22 {0x000E0000, nullptr, "ShutdownAsync"},
23 {0x00100180, nullptr, "RebootSystem"}, 23 {0x00100180, nullptr, "RebootSystem"},
24 {0x00110100, nullptr, "TerminateTitle"}, 24 {0x00110100, nullptr, "TerminateTitle"},
25 {0x001200C0, nullptr, "SetApplicationCpuTimeLimit"}, 25 {0x001200C0, nullptr, "SetApplicationCpuTimeLimit"},
26 {0x00150140, nullptr, "LaunchApplication"}, 26 {0x00150140, nullptr, "LaunchApplication"},
27 {0x00160000, nullptr, "RebootSystemClean"}, 27 {0x00160000, nullptr, "RebootSystemClean"},
28}; 28};
29 29
30//////////////////////////////////////////////////////////////////////////////////////////////////// 30////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index ae4640409..27e829209 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -4,7 +4,6 @@
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7
8#include "core/hle/kernel/event.h" 7#include "core/hle/kernel/event.h"
9#include "core/hle/service/nwm_uds.h" 8#include "core/hle/service/nwm_uds.h"
10 9
@@ -54,22 +53,23 @@ static void Shutdown(Service::Interface* self) {
54static void RecvBeaconBroadcastData(Service::Interface* self) { 53static void RecvBeaconBroadcastData(Service::Interface* self) {
55 u32* cmd_buff = Kernel::GetCommandBuffer(); 54 u32* cmd_buff = Kernel::GetCommandBuffer();
56 u32 out_buffer_size = cmd_buff[1]; 55 u32 out_buffer_size = cmd_buff[1];
57 u32 unk1 = cmd_buff[2]; 56 u32 unk1 = cmd_buff[2];
58 u32 unk2 = cmd_buff[3]; 57 u32 unk2 = cmd_buff[3];
59 u32 mac_address = cmd_buff[4]; 58 u32 mac_address = cmd_buff[4];
60 59
61 u32 unk3 = cmd_buff[6]; 60 u32 unk3 = cmd_buff[6];
62 61
63 u32 wlan_comm_id = cmd_buff[15]; 62 u32 wlan_comm_id = cmd_buff[15];
64 u32 ctr_gen_id = cmd_buff[16]; 63 u32 ctr_gen_id = cmd_buff[16];
65 u32 value = cmd_buff[17]; 64 u32 value = cmd_buff[17];
66 u32 input_handle = cmd_buff[18]; 65 u32 input_handle = cmd_buff[18];
67 u32 new_buffer_size = cmd_buff[19]; 66 u32 new_buffer_size = cmd_buff[19];
68 u32 out_buffer_ptr = cmd_buff[20]; 67 u32 out_buffer_ptr = cmd_buff[20];
69 68
70 cmd_buff[1] = RESULT_SUCCESS.raw; 69 cmd_buff[1] = RESULT_SUCCESS.raw;
71 70
72 LOG_WARNING(Service_NWM, "(STUBBED) called out_buffer_size=0x%08X, unk1=0x%08X, unk2=0x%08X," 71 LOG_WARNING(Service_NWM,
72 "(STUBBED) called out_buffer_size=0x%08X, unk1=0x%08X, unk2=0x%08X,"
73 "mac_address=0x%08X, unk3=0x%08X, wlan_comm_id=0x%08X, ctr_gen_id=0x%08X," 73 "mac_address=0x%08X, unk3=0x%08X, wlan_comm_id=0x%08X, ctr_gen_id=0x%08X,"
74 "value=%u, input_handle=0x%08X, new_buffer_size=0x%08X, out_buffer_ptr=0x%08X", 74 "value=%u, input_handle=0x%08X, new_buffer_size=0x%08X, out_buffer_ptr=0x%08X",
75 out_buffer_size, unk1, unk2, mac_address, unk3, wlan_comm_id, ctr_gen_id, value, 75 out_buffer_size, unk1, unk2, mac_address, unk3, wlan_comm_id, ctr_gen_id, value,
@@ -92,46 +92,47 @@ static void RecvBeaconBroadcastData(Service::Interface* self) {
92 */ 92 */
93static void Initialize(Service::Interface* self) { 93static void Initialize(Service::Interface* self) {
94 u32* cmd_buff = Kernel::GetCommandBuffer(); 94 u32* cmd_buff = Kernel::GetCommandBuffer();
95 u32 unk1 = cmd_buff[1]; 95 u32 unk1 = cmd_buff[1];
96 u32 unk2 = cmd_buff[12]; 96 u32 unk2 = cmd_buff[12];
97 u32 value = cmd_buff[13]; 97 u32 value = cmd_buff[13];
98 u32 handle = cmd_buff[14]; 98 u32 handle = cmd_buff[14];
99 99
100 cmd_buff[1] = RESULT_SUCCESS.raw; 100 cmd_buff[1] = RESULT_SUCCESS.raw;
101 cmd_buff[2] = 0; 101 cmd_buff[2] = 0;
102 cmd_buff[3] = Kernel::g_handle_table.Create(handle_event).MoveFrom(); //TODO(purpasmart): Verify if this is a event handle 102 cmd_buff[3] = Kernel::g_handle_table.Create(handle_event)
103 .MoveFrom(); // TODO(purpasmart): Verify if this is a event handle
103 104
104 LOG_WARNING(Service_NWM, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, value=%u, handle=0x%08X", 105 LOG_WARNING(Service_NWM, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, value=%u, handle=0x%08X",
105 unk1, unk2, value, handle); 106 unk1, unk2, value, handle);
106} 107}
107 108
108const Interface::FunctionInfo FunctionTable[] = { 109const Interface::FunctionInfo FunctionTable[] = {
109 {0x00020000, nullptr, "Scrap"}, 110 {0x00020000, nullptr, "Scrap"},
110 {0x00030000, Shutdown, "Shutdown"}, 111 {0x00030000, Shutdown, "Shutdown"},
111 {0x00040402, nullptr, "CreateNetwork"}, 112 {0x00040402, nullptr, "CreateNetwork"},
112 {0x00050040, nullptr, "EjectClient"}, 113 {0x00050040, nullptr, "EjectClient"},
113 {0x00060000, nullptr, "EjectSpectator"}, 114 {0x00060000, nullptr, "EjectSpectator"},
114 {0x00070080, nullptr, "UpdateNetworkAttribute"}, 115 {0x00070080, nullptr, "UpdateNetworkAttribute"},
115 {0x00080000, nullptr, "DestroyNetwork"}, 116 {0x00080000, nullptr, "DestroyNetwork"},
116 {0x000A0000, nullptr, "DisconnectNetwork"}, 117 {0x000A0000, nullptr, "DisconnectNetwork"},
117 {0x000B0000, nullptr, "GetConnectionStatus"}, 118 {0x000B0000, nullptr, "GetConnectionStatus"},
118 {0x000D0040, nullptr, "GetNodeInformation"}, 119 {0x000D0040, nullptr, "GetNodeInformation"},
119 {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, 120 {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"},
120 {0x00100042, nullptr, "SetBeaconAdditionalData"}, 121 {0x00100042, nullptr, "SetBeaconAdditionalData"},
121 {0x00110040, nullptr, "GetApplicationData"}, 122 {0x00110040, nullptr, "GetApplicationData"},
122 {0x00120100, nullptr, "Bind"}, 123 {0x00120100, nullptr, "Bind"},
123 {0x00130040, nullptr, "Unbind"}, 124 {0x00130040, nullptr, "Unbind"},
124 {0x001400C0, nullptr, "RecvBroadcastDataFrame"}, 125 {0x001400C0, nullptr, "RecvBroadcastDataFrame"},
125 {0x00150080, nullptr, "SetMaxSendDelay"}, 126 {0x00150080, nullptr, "SetMaxSendDelay"},
126 {0x00170182, nullptr, "SendTo"}, 127 {0x00170182, nullptr, "SendTo"},
127 {0x001A0000, nullptr, "GetChannel"}, 128 {0x001A0000, nullptr, "GetChannel"},
128 {0x001B0302, Initialize, "Initialize"}, 129 {0x001B0302, Initialize, "Initialize"},
129 {0x001D0044, nullptr, "BeginHostingNetwork"}, 130 {0x001D0044, nullptr, "BeginHostingNetwork"},
130 {0x001E0084, nullptr, "ConnectToNetwork"}, 131 {0x001E0084, nullptr, "ConnectToNetwork"},
131 {0x001F0006, nullptr, "DecryptBeaconData"}, 132 {0x001F0006, nullptr, "DecryptBeaconData"},
132 {0x00200040, nullptr, "Flush"}, 133 {0x00200040, nullptr, "Flush"},
133 {0x00210080, nullptr, "SetProbeResponseParam"}, 134 {0x00210080, nullptr, "SetProbeResponseParam"},
134 {0x00220402, nullptr, "ScanOnConnection"}, 135 {0x00220402, nullptr, "ScanOnConnection"},
135}; 136};
136 137
137//////////////////////////////////////////////////////////////////////////////////////////////////// 138////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp
index 05d01bc48..7d91694f6 100644
--- a/src/core/hle/service/pm_app.cpp
+++ b/src/core/hle/service/pm_app.cpp
@@ -10,18 +10,18 @@
10namespace PM_APP { 10namespace PM_APP {
11 11
12const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010140, nullptr, "LaunchTitle"}, 13 {0x00010140, nullptr, "LaunchTitle"},
14 {0x00020082, nullptr, "LaunchFIRMSetParams"}, 14 {0x00020082, nullptr, "LaunchFIRMSetParams"},
15 {0x00030080, nullptr, "TerminateProcesse"}, 15 {0x00030080, nullptr, "TerminateProcesse"},
16 {0x00040100, nullptr, "TerminateProcessTID"}, 16 {0x00040100, nullptr, "TerminateProcessTID"},
17 {0x000500C0, nullptr, "TerminateProcessTID_unknown"}, 17 {0x000500C0, nullptr, "TerminateProcessTID_unknown"},
18 {0x00070042, nullptr, "GetFIRMLaunchParams"}, 18 {0x00070042, nullptr, "GetFIRMLaunchParams"},
19 {0x00080100, nullptr, "GetTitleExheaderFlags"}, 19 {0x00080100, nullptr, "GetTitleExheaderFlags"},
20 {0x00090042, nullptr, "SetFIRMLaunchParams"}, 20 {0x00090042, nullptr, "SetFIRMLaunchParams"},
21 {0x000A0140, nullptr, "SetResourceLimit"}, 21 {0x000A0140, nullptr, "SetResourceLimit"},
22 {0x000B0140, nullptr, "GetResourceLimitMax"}, 22 {0x000B0140, nullptr, "GetResourceLimitMax"},
23 {0x000C0080, nullptr, "UnregisterProcess"}, 23 {0x000C0080, nullptr, "UnregisterProcess"},
24 {0x000D0240, nullptr, "LaunchTitleUpdate"}, 24 {0x000D0240, nullptr, "LaunchTitleUpdate"},
25}; 25};
26 26
27//////////////////////////////////////////////////////////////////////////////////////////////////// 27////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index e2c17d93b..6e6b63329 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "core/settings.h"
7#include "core/file_sys/file_backend.h" 6#include "core/file_sys/file_backend.h"
8#include "core/hle/service/fs/archive.h" 7#include "core/hle/service/fs/archive.h"
9#include "core/hle/service/ptm/ptm.h" 8#include "core/hle/service/ptm/ptm.h"
@@ -11,12 +10,13 @@
11#include "core/hle/service/ptm/ptm_sysm.h" 10#include "core/hle/service/ptm/ptm_sysm.h"
12#include "core/hle/service/ptm/ptm_u.h" 11#include "core/hle/service/ptm/ptm_u.h"
13#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
13#include "core/settings.h"
14 14
15namespace Service { 15namespace Service {
16namespace PTM { 16namespace PTM {
17 17
18/// Values for the default gamecoin.dat file 18/// Values for the default gamecoin.dat file
19static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 }; 19static const GameCoin default_game_coin = {0x4F00, 42, 0, 0, 0, 2014, 12, 29};
20 20
21/// Id of the SharedExtData archive used by the PTM process 21/// Id of the SharedExtData archive used by the PTM process
22static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0}; 22static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0};
@@ -51,7 +51,8 @@ void GetBatteryLevel(Service::Interface* self) {
51 // it returns a valid result without implementing full functionality. 51 // it returns a valid result without implementing full functionality.
52 52
53 cmd_buff[1] = RESULT_SUCCESS.raw; 53 cmd_buff[1] = RESULT_SUCCESS.raw;
54 cmd_buff[2] = static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery 54 cmd_buff[2] =
55 static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery
55 56
56 LOG_WARNING(Service_PTM, "(STUBBED) called"); 57 LOG_WARNING(Service_PTM, "(STUBBED) called");
57} 58}
@@ -94,7 +95,8 @@ void CheckNew3DS(Service::Interface* self) {
94 const bool is_new_3ds = Settings::values.is_new_3ds; 95 const bool is_new_3ds = Settings::values.is_new_3ds;
95 96
96 if (is_new_3ds) { 97 if (is_new_3ds) {
97 LOG_CRITICAL(Service_PTM, "The option 'is_new_3ds' is enabled as part of the 'System' settings. Citra does not fully support New 3DS emulation yet!"); 98 LOG_CRITICAL(Service_PTM, "The option 'is_new_3ds' is enabled as part of the 'System' "
99 "settings. Citra does not fully support New 3DS emulation yet!");
98 } 100 }
99 101
100 cmd_buff[1] = RESULT_SUCCESS.raw; 102 cmd_buff[1] = RESULT_SUCCESS.raw;
@@ -111,15 +113,19 @@ void Init() {
111 shell_open = true; 113 shell_open = true;
112 battery_is_charging = true; 114 battery_is_charging = true;
113 115
114 // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist 116 // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't
117 // exist
115 FileSys::Path archive_path(ptm_shared_extdata_id); 118 FileSys::Path archive_path(ptm_shared_extdata_id);
116 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); 119 auto archive_result =
120 Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
117 // If the archive didn't exist, create the files inside 121 // If the archive didn't exist, create the files inside
118 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { 122 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
119 // Format the archive to create the directories 123 // Format the archive to create the directories
120 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, FileSys::ArchiveFormatInfo(), archive_path); 124 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData,
125 FileSys::ArchiveFormatInfo(), archive_path);
121 // Open it again to get a valid archive now that the folder exists 126 // Open it again to get a valid archive now that the folder exists
122 archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); 127 archive_result =
128 Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
123 ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); 129 ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
124 130
125 FileSys::Path gamecoin_path("gamecoin.dat"); 131 FileSys::Path gamecoin_path("gamecoin.dat");
@@ -127,18 +133,18 @@ void Init() {
127 open_mode.write_flag.Assign(1); 133 open_mode.write_flag.Assign(1);
128 open_mode.create_flag.Assign(1); 134 open_mode.create_flag.Assign(1);
129 // Open the file and write the default gamecoin information 135 // Open the file and write the default gamecoin information
130 auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); 136 auto gamecoin_result =
137 Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
131 if (gamecoin_result.Succeeded()) { 138 if (gamecoin_result.Succeeded()) {
132 auto gamecoin = gamecoin_result.MoveFrom(); 139 auto gamecoin = gamecoin_result.MoveFrom();
133 gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin)); 140 gamecoin->backend->Write(0, sizeof(GameCoin), 1,
141 reinterpret_cast<const u8*>(&default_game_coin));
134 gamecoin->backend->Close(); 142 gamecoin->backend->Close();
135 } 143 }
136 } 144 }
137} 145}
138 146
139void Shutdown() { 147void Shutdown() {}
140
141}
142 148
143} // namespace PTM 149} // namespace PTM
144} // namespace Service 150} // namespace Service
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
index 7ef8877c7..6e163a6f9 100644
--- a/src/core/hle/service/ptm/ptm.h
+++ b/src/core/hle/service/ptm/ptm.h
@@ -14,23 +14,24 @@ namespace PTM {
14 14
15/// Charge levels used by PTM functions 15/// Charge levels used by PTM functions
16enum class ChargeLevels : u32 { 16enum class ChargeLevels : u32 {
17 CriticalBattery = 1, 17 CriticalBattery = 1,
18 LowBattery = 2, 18 LowBattery = 2,
19 HalfFull = 3, 19 HalfFull = 3,
20 MostlyFull = 4, 20 MostlyFull = 4,
21 CompletelyFull = 5, 21 CompletelyFull = 5,
22}; 22};
23 23
24/** 24/**
25 * Represents the gamecoin file structure in the SharedExtData archive 25 * Represents the gamecoin file structure in the SharedExtData archive
26 * More information in 3dbrew (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat) 26 * More information in 3dbrew
27 * (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat)
27 */ 28 */
28struct GameCoin { 29struct GameCoin {
29 u32 magic; ///< Magic number: 0x4F00 30 u32 magic; ///< Magic number: 0x4F00
30 u16 total_coins; ///< Total Play Coins 31 u16 total_coins; ///< Total Play Coins
31 u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below. 32 u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below.
32 u32 step_count; ///< Total step count at the time a new Play Coin was obtained. 33 u32 step_count; ///< Total step count at the time a new Play Coin was obtained.
33 u32 last_step_count; ///< Step count for the day the last Play Coin was obtained 34 u32 last_step_count; ///< Step count for the day the last Play Coin was obtained
34 u16 year; 35 u16 year;
35 u8 month; 36 u8 month;
36 u8 day; 37 u8 day;
diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp
index ca5dd0403..2e0c6e1a3 100644
--- a/src/core/hle/service/ptm/ptm_play.cpp
+++ b/src/core/hle/service/ptm/ptm_play.cpp
@@ -8,10 +8,10 @@ namespace Service {
8namespace PTM { 8namespace PTM {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const Interface::FunctionInfo FunctionTable[] = {
11 {0x08070082, nullptr, "GetPlayHistory"}, 11 {0x08070082, nullptr, "GetPlayHistory"},
12 {0x08080000, nullptr, "GetPlayHistoryStart"}, 12 {0x08080000, nullptr, "GetPlayHistoryStart"},
13 {0x08090000, nullptr, "GetPlayHistoryLength"}, 13 {0x08090000, nullptr, "GetPlayHistoryLength"},
14 {0x080B0080, nullptr, "CalcPlayHistoryStart"}, 14 {0x080B0080, nullptr, "CalcPlayHistoryStart"},
15}; 15};
16 16
17PTM_Play_Interface::PTM_Play_Interface() { 17PTM_Play_Interface::PTM_Play_Interface() {
diff --git a/src/core/hle/service/ptm/ptm_play.h b/src/core/hle/service/ptm/ptm_play.h
index e5c3e04df..47f229581 100644
--- a/src/core/hle/service/ptm/ptm_play.h
+++ b/src/core/hle/service/ptm/ptm_play.h
@@ -13,9 +13,9 @@ class PTM_Play_Interface : public Service::Interface {
13public: 13public:
14 PTM_Play_Interface(); 14 PTM_Play_Interface();
15 15
16std::string GetPortName() const override { 16 std::string GetPortName() const override {
17 return "ptm:play"; 17 return "ptm:play";
18} 18 }
19}; 19};
20 20
21} // namespace PTM 21} // namespace PTM
diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp
index cc4ef1101..693158dbf 100644
--- a/src/core/hle/service/ptm/ptm_sysm.cpp
+++ b/src/core/hle/service/ptm/ptm_sysm.cpp
@@ -9,37 +9,37 @@ namespace Service {
9namespace PTM { 9namespace PTM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x040100C0, nullptr, "SetRtcAlarmEx"}, 12 {0x040100C0, nullptr, "SetRtcAlarmEx"},
13 {0x04020042, nullptr, "ReplySleepQuery"}, 13 {0x04020042, nullptr, "ReplySleepQuery"},
14 {0x04030042, nullptr, "NotifySleepPreparationComplete"}, 14 {0x04030042, nullptr, "NotifySleepPreparationComplete"},
15 {0x04040102, nullptr, "SetWakeupTrigger"}, 15 {0x04040102, nullptr, "SetWakeupTrigger"},
16 {0x04050000, nullptr, "GetAwakeReason"}, 16 {0x04050000, nullptr, "GetAwakeReason"},
17 {0x04060000, nullptr, "RequestSleep"}, 17 {0x04060000, nullptr, "RequestSleep"},
18 {0x040700C0, nullptr, "ShutdownAsync"}, 18 {0x040700C0, nullptr, "ShutdownAsync"},
19 {0x04080000, nullptr, "Awake"}, 19 {0x04080000, nullptr, "Awake"},
20 {0x04090080, nullptr, "RebootAsync"}, 20 {0x04090080, nullptr, "RebootAsync"},
21 {0x040A0000, CheckNew3DS, "CheckNew3DS"}, 21 {0x040A0000, CheckNew3DS, "CheckNew3DS"},
22 {0x08010640, nullptr, "SetInfoLEDPattern"}, 22 {0x08010640, nullptr, "SetInfoLEDPattern"},
23 {0x08020040, nullptr, "SetInfoLEDPatternHeader"}, 23 {0x08020040, nullptr, "SetInfoLEDPatternHeader"},
24 {0x08030000, nullptr, "GetInfoLEDStatus"}, 24 {0x08030000, nullptr, "GetInfoLEDStatus"},
25 {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"}, 25 {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"},
26 {0x08050000, nullptr, "ClearStepHistory"}, 26 {0x08050000, nullptr, "ClearStepHistory"},
27 {0x080600C2, nullptr, "SetStepHistory"}, 27 {0x080600C2, nullptr, "SetStepHistory"},
28 {0x08070082, nullptr, "GetPlayHistory"}, 28 {0x08070082, nullptr, "GetPlayHistory"},
29 {0x08080000, nullptr, "GetPlayHistoryStart"}, 29 {0x08080000, nullptr, "GetPlayHistoryStart"},
30 {0x08090000, nullptr, "GetPlayHistoryLength"}, 30 {0x08090000, nullptr, "GetPlayHistoryLength"},
31 {0x080A0000, nullptr, "ClearPlayHistory"}, 31 {0x080A0000, nullptr, "ClearPlayHistory"},
32 {0x080B0080, nullptr, "CalcPlayHistoryStart"}, 32 {0x080B0080, nullptr, "CalcPlayHistoryStart"},
33 {0x080C0080, nullptr, "SetUserTime"}, 33 {0x080C0080, nullptr, "SetUserTime"},
34 {0x080D0000, nullptr, "InvalidateSystemTime"}, 34 {0x080D0000, nullptr, "InvalidateSystemTime"},
35 {0x080E0140, nullptr, "NotifyPlayEvent"}, 35 {0x080E0140, nullptr, "NotifyPlayEvent"},
36 {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"}, 36 {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"},
37 {0x08100000, nullptr, "ClearLegacyPowerOff"}, 37 {0x08100000, nullptr, "ClearLegacyPowerOff"},
38 {0x08110000, GetShellState, "GetShellState"}, 38 {0x08110000, GetShellState, "GetShellState"},
39 {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, 39 {0x08120000, nullptr, "IsShutdownByBatteryEmpty"},
40 {0x08130000, nullptr, "FormatSavedata"}, 40 {0x08130000, nullptr, "FormatSavedata"},
41 {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"}, 41 {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"},
42 {0x08180040, nullptr, "ConfigureNew3DSCPU"}, 42 {0x08180040, nullptr, "ConfigureNew3DSCPU"},
43}; 43};
44 44
45PTM_Sysm_Interface::PTM_Sysm_Interface() { 45PTM_Sysm_Interface::PTM_Sysm_Interface() {
diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp
index 17e764866..65e868393 100644
--- a/src/core/hle/service/ptm/ptm_u.cpp
+++ b/src/core/hle/service/ptm/ptm_u.cpp
@@ -9,21 +9,21 @@ namespace Service {
9namespace PTM { 9namespace PTM {
10 10
11const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
12 {0x00010002, nullptr, "RegisterAlarmClient"}, 12 {0x00010002, nullptr, "RegisterAlarmClient"},
13 {0x00020080, nullptr, "SetRtcAlarm"}, 13 {0x00020080, nullptr, "SetRtcAlarm"},
14 {0x00030000, nullptr, "GetRtcAlarm"}, 14 {0x00030000, nullptr, "GetRtcAlarm"},
15 {0x00040000, nullptr, "CancelRtcAlarm"}, 15 {0x00040000, nullptr, "CancelRtcAlarm"},
16 {0x00050000, GetAdapterState, "GetAdapterState"}, 16 {0x00050000, GetAdapterState, "GetAdapterState"},
17 {0x00060000, GetShellState, "GetShellState"}, 17 {0x00060000, GetShellState, "GetShellState"},
18 {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, 18 {0x00070000, GetBatteryLevel, "GetBatteryLevel"},
19 {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"}, 19 {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"},
20 {0x00090000, nullptr, "GetPedometerState"}, 20 {0x00090000, nullptr, "GetPedometerState"},
21 {0x000A0042, nullptr, "GetStepHistoryEntry"}, 21 {0x000A0042, nullptr, "GetStepHistoryEntry"},
22 {0x000B00C2, nullptr, "GetStepHistory"}, 22 {0x000B00C2, nullptr, "GetStepHistory"},
23 {0x000C0000, GetTotalStepCount, "GetTotalStepCount"}, 23 {0x000C0000, GetTotalStepCount, "GetTotalStepCount"},
24 {0x000D0040, nullptr, "SetPedometerRecordingMode"}, 24 {0x000D0040, nullptr, "SetPedometerRecordingMode"},
25 {0x000E0000, nullptr, "GetPedometerRecordingMode"}, 25 {0x000E0000, nullptr, "GetPedometerRecordingMode"},
26 {0x000F0084, nullptr, "GetStepHistoryAll"}, 26 {0x000F0084, nullptr, "GetStepHistoryAll"},
27}; 27};
28 28
29PTM_U_Interface::PTM_U_Interface() { 29PTM_U_Interface::PTM_U_Interface() {
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 5b8440b77..ca7eeac8a 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -4,42 +4,40 @@
4 4
5#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/string_util.h" 6#include "common/string_util.h"
7
8#include "core/hle/service/service.h"
9#include "core/hle/service/ac_u.h" 7#include "core/hle/service/ac_u.h"
10#include "core/hle/service/act_a.h" 8#include "core/hle/service/act_a.h"
11#include "core/hle/service/act_u.h" 9#include "core/hle/service/act_u.h"
12#include "core/hle/service/csnd_snd.h"
13#include "core/hle/service/dsp_dsp.h"
14#include "core/hle/service/err_f.h"
15#include "core/hle/service/gsp_gpu.h"
16#include "core/hle/service/gsp_lcd.h"
17#include "core/hle/service/http_c.h"
18#include "core/hle/service/mic_u.h"
19#include "core/hle/service/ns_s.h"
20#include "core/hle/service/nwm_uds.h"
21#include "core/hle/service/pm_app.h"
22#include "core/hle/service/soc_u.h"
23#include "core/hle/service/srv.h"
24#include "core/hle/service/ssl_c.h"
25#include "core/hle/service/y2r_u.h"
26
27#include "core/hle/service/am/am.h" 10#include "core/hle/service/am/am.h"
28#include "core/hle/service/apt/apt.h" 11#include "core/hle/service/apt/apt.h"
29#include "core/hle/service/boss/boss.h" 12#include "core/hle/service/boss/boss.h"
30#include "core/hle/service/cam/cam.h" 13#include "core/hle/service/cam/cam.h"
31#include "core/hle/service/cecd/cecd.h" 14#include "core/hle/service/cecd/cecd.h"
15#include "core/hle/service/cfg/cfg.h"
16#include "core/hle/service/csnd_snd.h"
32#include "core/hle/service/dlp/dlp.h" 17#include "core/hle/service/dlp/dlp.h"
18#include "core/hle/service/dsp_dsp.h"
19#include "core/hle/service/err_f.h"
33#include "core/hle/service/frd/frd.h" 20#include "core/hle/service/frd/frd.h"
34#include "core/hle/service/fs/archive.h" 21#include "core/hle/service/fs/archive.h"
35#include "core/hle/service/cfg/cfg.h" 22#include "core/hle/service/gsp_gpu.h"
23#include "core/hle/service/gsp_lcd.h"
36#include "core/hle/service/hid/hid.h" 24#include "core/hle/service/hid/hid.h"
25#include "core/hle/service/http_c.h"
37#include "core/hle/service/ir/ir.h" 26#include "core/hle/service/ir/ir.h"
38#include "core/hle/service/ldr_ro/ldr_ro.h" 27#include "core/hle/service/ldr_ro/ldr_ro.h"
28#include "core/hle/service/mic_u.h"
39#include "core/hle/service/ndm/ndm.h" 29#include "core/hle/service/ndm/ndm.h"
40#include "core/hle/service/news/news.h" 30#include "core/hle/service/news/news.h"
41#include "core/hle/service/nim/nim.h" 31#include "core/hle/service/nim/nim.h"
32#include "core/hle/service/ns_s.h"
33#include "core/hle/service/nwm_uds.h"
34#include "core/hle/service/pm_app.h"
42#include "core/hle/service/ptm/ptm.h" 35#include "core/hle/service/ptm/ptm.h"
36#include "core/hle/service/service.h"
37#include "core/hle/service/soc_u.h"
38#include "core/hle/service/srv.h"
39#include "core/hle/service/ssl_c.h"
40#include "core/hle/service/y2r_u.h"
43 41
44namespace Service { 42namespace Service {
45 43
@@ -50,11 +48,13 @@ std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
50 * Creates a function string for logging, complete with the name (or header code, depending 48 * Creates a function string for logging, complete with the name (or header code, depending
51 * on what's passed in) the port name, and all the cmd_buff arguments. 49 * on what's passed in) the port name, and all the cmd_buff arguments.
52 */ 50 */
53static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { 51static std::string MakeFunctionString(const char* name, const char* port_name,
52 const u32* cmd_buff) {
54 // Number of params == bits 0-5 + bits 6-11 53 // Number of params == bits 0-5 + bits 6-11
55 int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); 54 int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F);
56 55
57 std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name); 56 std::string function_string =
57 Common::StringFromFormat("function '%s': port=%s", name, port_name);
58 for (int i = 1; i <= num_params; ++i) { 58 for (int i = 1; i <= num_params; ++i) {
59 function_string += Common::StringFromFormat(", cmd_buff[%i]=0x%X", i, cmd_buff[i]); 59 function_string += Common::StringFromFormat(", cmd_buff[%i]=0x%X", i, cmd_buff[i]);
60 } 60 }
@@ -66,14 +66,19 @@ ResultVal<bool> Interface::SyncRequest() {
66 auto itr = m_functions.find(cmd_buff[0]); 66 auto itr = m_functions.find(cmd_buff[0]);
67 67
68 if (itr == m_functions.end() || itr->second.func == nullptr) { 68 if (itr == m_functions.end() || itr->second.func == nullptr) {
69 std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; 69 std::string function_name = (itr == m_functions.end())
70 LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); 70 ? Common::StringFromFormat("0x%08X", cmd_buff[0])
71 : itr->second.name;
72 LOG_ERROR(
73 Service, "unknown / unimplemented %s",
74 MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str());
71 75
72 // TODO(bunnei): Hack - ignore error 76 // TODO(bunnei): Hack - ignore error
73 cmd_buff[1] = 0; 77 cmd_buff[1] = 0;
74 return MakeResult<bool>(false); 78 return MakeResult<bool>(false);
75 } 79 }
76 LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); 80 LOG_TRACE(Service, "%s",
81 MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str());
77 82
78 itr->second.func(this); 83 itr->second.func(this);
79 84
@@ -163,6 +168,4 @@ void Shutdown() {
163 g_kernel_named_ports.clear(); 168 g_kernel_named_ports.clear();
164 LOG_DEBUG(Service, "shutdown OK"); 169 LOG_DEBUG(Service, "shutdown OK");
165} 170}
166
167
168} 171}
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index f31135212..39b5ffaae 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -7,11 +7,8 @@
7#include <cstddef> 7#include <cstddef>
8#include <string> 8#include <string>
9#include <unordered_map> 9#include <unordered_map>
10
11#include <boost/container/flat_map.hpp> 10#include <boost/container/flat_map.hpp>
12
13#include "common/common_types.h" 11#include "common/common_types.h"
14
15#include "core/hle/kernel/session.h" 12#include "core/hle/kernel/session.h"
16#include "core/hle/result.h" 13#include "core/hle/result.h"
17 14
@@ -28,13 +25,15 @@ class Interface : public Kernel::Session {
28 // just something that encapsulates a session and acts as a helper to implement service 25 // just something that encapsulates a session and acts as a helper to implement service
29 // processes. 26 // processes.
30public: 27public:
31 std::string GetName() const override { return GetPortName(); } 28 std::string GetName() const override {
29 return GetPortName();
30 }
32 31
33 typedef void (*Function)(Interface*); 32 typedef void (*Function)(Interface*);
34 33
35 struct FunctionInfo { 34 struct FunctionInfo {
36 u32 id; 35 u32 id;
37 Function func; 36 Function func;
38 const char* name; 37 const char* name;
39 }; 38 };
40 39
@@ -49,7 +48,6 @@ public:
49 ResultVal<bool> SyncRequest() override; 48 ResultVal<bool> SyncRequest() override;
50 49
51protected: 50protected:
52
53 /** 51 /**
54 * Registers the functions in the service 52 * Registers the functions in the service
55 */ 53 */
@@ -62,7 +60,6 @@ protected:
62 60
63private: 61private:
64 boost::container::flat_map<u32, FunctionInfo> m_functions; 62 boost::container::flat_map<u32, FunctionInfo> m_functions;
65
66}; 63};
67 64
68/// Initialize ServiceManager 65/// Initialize ServiceManager
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 9b285567b..4279b67fb 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -6,53 +6,51 @@
6#include <cstring> 6#include <cstring>
7#include <unordered_map> 7#include <unordered_map>
8#include <vector> 8#include <vector>
9
10#include "common/assert.h" 9#include "common/assert.h"
11#include "common/bit_field.h" 10#include "common/bit_field.h"
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "common/logging/log.h" 12#include "common/logging/log.h"
14#include "common/scope_exit.h" 13#include "common/scope_exit.h"
15
16#include "core/hle/kernel/session.h" 14#include "core/hle/kernel/session.h"
17#include "core/hle/result.h" 15#include "core/hle/result.h"
18#include "core/hle/service/soc_u.h" 16#include "core/hle/service/soc_u.h"
19#include "core/memory.h" 17#include "core/memory.h"
20 18
21#ifdef _WIN32 19#ifdef _WIN32
22 #include <winsock2.h> 20#include <winsock2.h>
23 #include <ws2tcpip.h> 21#include <ws2tcpip.h>
24 22
25 // MinGW does not define several errno constants 23// MinGW does not define several errno constants
26 #ifndef _MSC_VER 24#ifndef _MSC_VER
27 #define EBADMSG 104 25#define EBADMSG 104
28 #define ENODATA 120 26#define ENODATA 120
29 #define ENOMSG 122 27#define ENOMSG 122
30 #define ENOSR 124 28#define ENOSR 124
31 #define ENOSTR 125 29#define ENOSTR 125
32 #define ETIME 137 30#define ETIME 137
33 #define EIDRM 2001 31#define EIDRM 2001
34 #define ENOLINK 2002 32#define ENOLINK 2002
35 #endif // _MSC_VER 33#endif // _MSC_VER
36#else 34#else
37 #include <cerrno> 35#include <cerrno>
38 #include <fcntl.h> 36#include <fcntl.h>
39 #include <netinet/in.h> 37#include <netdb.h>
40 #include <netdb.h> 38#include <netinet/in.h>
41 #include <poll.h> 39#include <poll.h>
42 #include <sys/socket.h> 40#include <sys/socket.h>
43 #include <unistd.h> 41#include <unistd.h>
44#endif 42#endif
45 43
46#ifdef _WIN32 44#ifdef _WIN32
47# define WSAEAGAIN WSAEWOULDBLOCK 45#define WSAEAGAIN WSAEWOULDBLOCK
48# define WSAEMULTIHOP -1 // Invalid dummy value 46#define WSAEMULTIHOP -1 // Invalid dummy value
49# define ERRNO(x) WSA##x 47#define ERRNO(x) WSA##x
50# define GET_ERRNO WSAGetLastError() 48#define GET_ERRNO WSAGetLastError()
51# define poll(x, y, z) WSAPoll(x, y, z); 49#define poll(x, y, z) WSAPoll(x, y, z);
52#else 50#else
53# define ERRNO(x) x 51#define ERRNO(x) x
54# define GET_ERRNO errno 52#define GET_ERRNO errno
55# define closesocket(x) close(x) 53#define closesocket(x) close(x)
56#endif 54#endif
57 55
58static const s32 SOCKET_ERROR_VALUE = -1; 56static const s32 SOCKET_ERROR_VALUE = -1;
@@ -63,83 +61,83 @@ static const s32 SOCKET_ERROR_VALUE = -1;
63namespace SOC_U { 61namespace SOC_U {
64 62
65/// Holds the translation from system network errors to 3DS network errors 63/// Holds the translation from system network errors to 3DS network errors
66static const std::unordered_map<int, int> error_map = { { 64static const std::unordered_map<int, int> error_map = {{
67 { E2BIG, 1 }, 65 {E2BIG, 1},
68 { ERRNO(EACCES), 2 }, 66 {ERRNO(EACCES), 2},
69 { ERRNO(EADDRINUSE), 3 }, 67 {ERRNO(EADDRINUSE), 3},
70 { ERRNO(EADDRNOTAVAIL), 4 }, 68 {ERRNO(EADDRNOTAVAIL), 4},
71 { ERRNO(EAFNOSUPPORT), 5 }, 69 {ERRNO(EAFNOSUPPORT), 5},
72 { ERRNO(EAGAIN), 6 }, 70 {ERRNO(EAGAIN), 6},
73 { ERRNO(EALREADY), 7 }, 71 {ERRNO(EALREADY), 7},
74 { ERRNO(EBADF), 8 }, 72 {ERRNO(EBADF), 8},
75 { EBADMSG, 9 }, 73 {EBADMSG, 9},
76 { EBUSY, 10 }, 74 {EBUSY, 10},
77 { ECANCELED, 11 }, 75 {ECANCELED, 11},
78 { ECHILD, 12 }, 76 {ECHILD, 12},
79 { ERRNO(ECONNABORTED), 13 }, 77 {ERRNO(ECONNABORTED), 13},
80 { ERRNO(ECONNREFUSED), 14 }, 78 {ERRNO(ECONNREFUSED), 14},
81 { ERRNO(ECONNRESET), 15 }, 79 {ERRNO(ECONNRESET), 15},
82 { EDEADLK, 16 }, 80 {EDEADLK, 16},
83 { ERRNO(EDESTADDRREQ), 17 }, 81 {ERRNO(EDESTADDRREQ), 17},
84 { EDOM, 18 }, 82 {EDOM, 18},
85 { ERRNO(EDQUOT), 19 }, 83 {ERRNO(EDQUOT), 19},
86 { EEXIST, 20 }, 84 {EEXIST, 20},
87 { ERRNO(EFAULT), 21 }, 85 {ERRNO(EFAULT), 21},
88 { EFBIG, 22 }, 86 {EFBIG, 22},
89 { ERRNO(EHOSTUNREACH), 23 }, 87 {ERRNO(EHOSTUNREACH), 23},
90 { EIDRM, 24 }, 88 {EIDRM, 24},
91 { EILSEQ, 25 }, 89 {EILSEQ, 25},
92 { ERRNO(EINPROGRESS), 26 }, 90 {ERRNO(EINPROGRESS), 26},
93 { ERRNO(EINTR), 27 }, 91 {ERRNO(EINTR), 27},
94 { ERRNO(EINVAL), 28 }, 92 {ERRNO(EINVAL), 28},
95 { EIO, 29 }, 93 {EIO, 29},
96 { ERRNO(EISCONN), 30 }, 94 {ERRNO(EISCONN), 30},
97 { EISDIR, 31 }, 95 {EISDIR, 31},
98 { ERRNO(ELOOP), 32 }, 96 {ERRNO(ELOOP), 32},
99 { ERRNO(EMFILE), 33 }, 97 {ERRNO(EMFILE), 33},
100 { EMLINK, 34 }, 98 {EMLINK, 34},
101 { ERRNO(EMSGSIZE), 35 }, 99 {ERRNO(EMSGSIZE), 35},
102 { ERRNO(EMULTIHOP), 36 }, 100 {ERRNO(EMULTIHOP), 36},
103 { ERRNO(ENAMETOOLONG), 37 }, 101 {ERRNO(ENAMETOOLONG), 37},
104 { ERRNO(ENETDOWN), 38 }, 102 {ERRNO(ENETDOWN), 38},
105 { ERRNO(ENETRESET), 39 }, 103 {ERRNO(ENETRESET), 39},
106 { ERRNO(ENETUNREACH), 40 }, 104 {ERRNO(ENETUNREACH), 40},
107 { ENFILE, 41 }, 105 {ENFILE, 41},
108 { ERRNO(ENOBUFS), 42 }, 106 {ERRNO(ENOBUFS), 42},
109 { ENODATA, 43 }, 107 {ENODATA, 43},
110 { ENODEV, 44 }, 108 {ENODEV, 44},
111 { ENOENT, 45 }, 109 {ENOENT, 45},
112 { ENOEXEC, 46 }, 110 {ENOEXEC, 46},
113 { ENOLCK, 47 }, 111 {ENOLCK, 47},
114 { ENOLINK, 48 }, 112 {ENOLINK, 48},
115 { ENOMEM, 49 }, 113 {ENOMEM, 49},
116 { ENOMSG, 50 }, 114 {ENOMSG, 50},
117 { ERRNO(ENOPROTOOPT), 51 }, 115 {ERRNO(ENOPROTOOPT), 51},
118 { ENOSPC, 52 }, 116 {ENOSPC, 52},
119 { ENOSR, 53 }, 117 {ENOSR, 53},
120 { ENOSTR, 54 }, 118 {ENOSTR, 54},
121 { ENOSYS, 55 }, 119 {ENOSYS, 55},
122 { ERRNO(ENOTCONN), 56 }, 120 {ERRNO(ENOTCONN), 56},
123 { ENOTDIR, 57 }, 121 {ENOTDIR, 57},
124 { ERRNO(ENOTEMPTY), 58 }, 122 {ERRNO(ENOTEMPTY), 58},
125 { ERRNO(ENOTSOCK), 59 }, 123 {ERRNO(ENOTSOCK), 59},
126 { ENOTSUP, 60 }, 124 {ENOTSUP, 60},
127 { ENOTTY, 61 }, 125 {ENOTTY, 61},
128 { ENXIO, 62 }, 126 {ENXIO, 62},
129 { ERRNO(EOPNOTSUPP), 63 }, 127 {ERRNO(EOPNOTSUPP), 63},
130 { EOVERFLOW, 64 }, 128 {EOVERFLOW, 64},
131 { EPERM, 65 }, 129 {EPERM, 65},
132 { EPIPE, 66 }, 130 {EPIPE, 66},
133 { EPROTO, 67 }, 131 {EPROTO, 67},
134 { ERRNO(EPROTONOSUPPORT), 68 }, 132 {ERRNO(EPROTONOSUPPORT), 68},
135 { ERRNO(EPROTOTYPE), 69 }, 133 {ERRNO(EPROTOTYPE), 69},
136 { ERANGE, 70 }, 134 {ERANGE, 70},
137 { EROFS, 71 }, 135 {EROFS, 71},
138 { ESPIPE, 72 }, 136 {ESPIPE, 72},
139 { ESRCH, 73 }, 137 {ESRCH, 73},
140 { ERRNO(ESTALE), 74 }, 138 {ERRNO(ESTALE), 74},
141 { ETIME, 75 }, 139 {ETIME, 75},
142 { ERRNO(ETIMEDOUT), 76 } 140 {ERRNO(ETIMEDOUT), 76},
143}}; 141}};
144 142
145/// Converts a network error from platform-specific to 3ds-specific 143/// Converts a network error from platform-specific to 3ds-specific
@@ -153,21 +151,21 @@ static int TranslateError(int error) {
153 151
154/// Holds the translation from system network socket options to 3DS network socket options 152/// Holds the translation from system network socket options to 3DS network socket options
155/// Note: -1 = No effect/unavailable 153/// Note: -1 = No effect/unavailable
156static const std::unordered_map<int, int> sockopt_map = { { 154static const std::unordered_map<int, int> sockopt_map = {{
157 { 0x0004, SO_REUSEADDR }, 155 {0x0004, SO_REUSEADDR},
158 { 0x0080, -1 }, 156 {0x0080, -1},
159 { 0x0100, -1 }, 157 {0x0100, -1},
160 { 0x1001, SO_SNDBUF }, 158 {0x1001, SO_SNDBUF},
161 { 0x1002, SO_RCVBUF }, 159 {0x1002, SO_RCVBUF},
162 { 0x1003, -1 }, 160 {0x1003, -1},
163#ifdef _WIN32 161#ifdef _WIN32
164 /// Unsupported in WinSock2 162 /// Unsupported in WinSock2
165 { 0x1004, -1 }, 163 {0x1004, -1},
166#else 164#else
167 { 0x1004, SO_RCVLOWAT }, 165 {0x1004, SO_RCVLOWAT},
168#endif 166#endif
169 { 0x1008, SO_TYPE }, 167 {0x1008, SO_TYPE},
170 { 0x1009, SO_ERROR }, 168 {0x1009, SO_ERROR},
171}}; 169}};
172 170
173/// Converts a socket option from 3ds-specific to platform-specific 171/// Converts a socket option from 3ds-specific to platform-specific
@@ -203,7 +201,8 @@ struct CTRPollFD {
203 return *this; 201 return *this;
204 } 202 }
205 203
206 /// Translates the resulting events of a Poll operation from platform-specific to 3ds specific 204 /// Translates the resulting events of a Poll operation from platform-specific to 3ds
205 /// specific
207 static Events TranslateTo3DS(u32 input_event) { 206 static Events TranslateTo3DS(u32 input_event) {
208 Events ev = {}; 207 Events ev = {};
209 if (input_event & POLLIN) 208 if (input_event & POLLIN)
@@ -221,7 +220,8 @@ struct CTRPollFD {
221 return ev; 220 return ev;
222 } 221 }
223 222
224 /// Translates the resulting events of a Poll operation from 3ds specific to platform specific 223 /// Translates the resulting events of a Poll operation from 3ds specific to platform
224 /// specific
225 static u32 TranslateToPlatform(Events input_event) { 225 static u32 TranslateToPlatform(Events input_event) {
226 u32 ret = 0; 226 u32 ret = 0;
227 if (input_event.pollin) 227 if (input_event.pollin)
@@ -239,7 +239,7 @@ struct CTRPollFD {
239 return ret; 239 return ret;
240 } 240 }
241 }; 241 };
242 Events events; ///< Events to poll for (input) 242 Events events; ///< Events to poll for (input)
243 Events revents; ///< Events received (output) 243 Events revents; ///< Events received (output)
244 244
245 /// Converts a platform-specific pollfd to a 3ds specific structure 245 /// Converts a platform-specific pollfd to a 3ds specific structure
@@ -265,17 +265,17 @@ struct CTRPollFD {
265union CTRSockAddr { 265union CTRSockAddr {
266 /// Structure to represent a raw sockaddr 266 /// Structure to represent a raw sockaddr
267 struct { 267 struct {
268 u8 len; ///< The length of the entire structure, only the set fields count 268 u8 len; ///< The length of the entire structure, only the set fields count
269 u8 sa_family; ///< The address family of the sockaddr 269 u8 sa_family; ///< The address family of the sockaddr
270 u8 sa_data[0x1A]; ///< The extra data, this varies, depending on the address family 270 u8 sa_data[0x1A]; ///< The extra data, this varies, depending on the address family
271 } raw; 271 } raw;
272 272
273 /// Structure to represent the 3ds' sockaddr_in structure 273 /// Structure to represent the 3ds' sockaddr_in structure
274 struct CTRSockAddrIn { 274 struct CTRSockAddrIn {
275 u8 len; ///< The length of the entire structure 275 u8 len; ///< The length of the entire structure
276 u8 sin_family; ///< The address family of the sockaddr_in 276 u8 sin_family; ///< The address family of the sockaddr_in
277 u16 sin_port; ///< The port associated with this sockaddr_in 277 u16 sin_port; ///< The port associated with this sockaddr_in
278 u32 sin_addr; ///< The actual address of the sockaddr_in 278 u32 sin_addr; ///< The actual address of the sockaddr_in
279 } in; 279 } in;
280 280
281 /// Convert a 3DS CTRSockAddr to a platform-specific sockaddr 281 /// Convert a 3DS CTRSockAddr to a platform-specific sockaddr
@@ -286,8 +286,7 @@ union CTRSockAddr {
286 286
287 // We can not guarantee ABI compatibility between platforms so we copy the fields manually 287 // We can not guarantee ABI compatibility between platforms so we copy the fields manually
288 switch (result.sa_family) { 288 switch (result.sa_family) {
289 case AF_INET: 289 case AF_INET: {
290 {
291 sockaddr_in* result_in = reinterpret_cast<sockaddr_in*>(&result); 290 sockaddr_in* result_in = reinterpret_cast<sockaddr_in*>(&result);
292 result_in->sin_port = ctr_addr.in.sin_port; 291 result_in->sin_port = ctr_addr.in.sin_port;
293 result_in->sin_addr.s_addr = ctr_addr.in.sin_addr; 292 result_in->sin_addr.s_addr = ctr_addr.in.sin_addr;
@@ -307,8 +306,7 @@ union CTRSockAddr {
307 result.raw.sa_family = static_cast<u8>(addr.sa_family); 306 result.raw.sa_family = static_cast<u8>(addr.sa_family);
308 // We can not guarantee ABI compatibility between platforms so we copy the fields manually 307 // We can not guarantee ABI compatibility between platforms so we copy the fields manually
309 switch (result.raw.sa_family) { 308 switch (result.raw.sa_family) {
310 case AF_INET: 309 case AF_INET: {
311 {
312 sockaddr_in const* addr_in = reinterpret_cast<sockaddr_in const*>(&addr); 310 sockaddr_in const* addr_in = reinterpret_cast<sockaddr_in const*>(&addr);
313 result.raw.len = sizeof(CTRSockAddrIn); 311 result.raw.len = sizeof(CTRSockAddrIn);
314 result.in.sin_port = addr_in->sin_port; 312 result.in.sin_port = addr_in->sin_port;
@@ -341,24 +339,27 @@ static void Socket(Service::Interface* self) {
341 339
342 // Only 0 is allowed according to 3dbrew, using 0 will let the OS decide which protocol to use 340 // Only 0 is allowed according to 3dbrew, using 0 will let the OS decide which protocol to use
343 if (protocol != 0) { 341 if (protocol != 0) {
344 cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code 342 cmd_buffer[1] =
343 UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
345 return; 344 return;
346 } 345 }
347 346
348 if (domain != AF_INET) { 347 if (domain != AF_INET) {
349 cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code 348 cmd_buffer[1] =
349 UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
350 return; 350 return;
351 } 351 }
352 352
353 if (type != SOCK_DGRAM && type != SOCK_STREAM) { 353 if (type != SOCK_DGRAM && type != SOCK_STREAM) {
354 cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code 354 cmd_buffer[1] =
355 UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
355 return; 356 return;
356 } 357 }
357 358
358 u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol)); 359 u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol));
359 360
360 if ((s32)socket_handle != SOCKET_ERROR_VALUE) 361 if ((s32)socket_handle != SOCKET_ERROR_VALUE)
361 open_sockets[socket_handle] = { socket_handle, true }; 362 open_sockets[socket_handle] = {socket_handle, true};
362 363
363 int result = 0; 364 int result = 0;
364 if ((s32)socket_handle == SOCKET_ERROR_VALUE) 365 if ((s32)socket_handle == SOCKET_ERROR_VALUE)
@@ -406,8 +407,8 @@ static void Fcntl(Service::Interface* self) {
406 int result = 0; 407 int result = 0;
407 u32 posix_ret = 0; // TODO: Check what hardware returns for F_SETFL (unspecified by POSIX) 408 u32 posix_ret = 0; // TODO: Check what hardware returns for F_SETFL (unspecified by POSIX)
408 SCOPE_EXIT({ 409 SCOPE_EXIT({
409 cmd_buffer[1] = result; 410 cmd_buffer[1] = result;
410 cmd_buffer[2] = posix_ret; 411 cmd_buffer[2] = posix_ret;
411 }); 412 });
412 413
413 if (ctr_cmd == 3) { // F_GETFL 414 if (ctr_cmd == 3) { // F_GETFL
@@ -493,7 +494,7 @@ static void Accept(Service::Interface* self) {
493 u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len)); 494 u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
494 495
495 if ((s32)ret != SOCKET_ERROR_VALUE) 496 if ((s32)ret != SOCKET_ERROR_VALUE)
496 open_sockets[ret] = { ret, true }; 497 open_sockets[ret] = {ret, true};
497 498
498 int result = 0; 499 int result = 0;
499 if ((s32)ret == SOCKET_ERROR_VALUE) { 500 if ((s32)ret == SOCKET_ERROR_VALUE) {
@@ -573,9 +574,11 @@ static void SendTo(Service::Interface* self) {
573 int ret = -1; 574 int ret = -1;
574 if (addr_len > 0) { 575 if (addr_len > 0) {
575 sockaddr dest_addr = CTRSockAddr::ToPlatform(ctr_dest_addr); 576 sockaddr dest_addr = CTRSockAddr::ToPlatform(ctr_dest_addr);
576 ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, &dest_addr, sizeof(dest_addr)); 577 ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags,
578 &dest_addr, sizeof(dest_addr));
577 } else { 579 } else {
578 ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, nullptr, 0); 580 ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags,
581 nullptr, 0);
579 } 582 }
580 583
581 int result = 0; 584 int result = 0;
@@ -596,8 +599,7 @@ static void RecvFrom(Service::Interface* self) {
596 u32 flags = cmd_buffer[3]; 599 u32 flags = cmd_buffer[3];
597 socklen_t addr_len = static_cast<socklen_t>(cmd_buffer[4]); 600 socklen_t addr_len = static_cast<socklen_t>(cmd_buffer[4]);
598 601
599 struct 602 struct {
600 {
601 u32 output_buffer_descriptor; 603 u32 output_buffer_descriptor;
602 u32 output_buffer_addr; 604 u32 output_buffer_addr;
603 u32 address_buffer_descriptor; 605 u32 address_buffer_descriptor;
@@ -619,11 +621,13 @@ static void RecvFrom(Service::Interface* self) {
619 std::vector<u8> output_buff(len); 621 std::vector<u8> output_buff(len);
620 sockaddr src_addr; 622 sockaddr src_addr;
621 socklen_t src_addr_len = sizeof(src_addr); 623 socklen_t src_addr_len = sizeof(src_addr);
622 int ret = ::recvfrom(socket_handle, reinterpret_cast<char*>(output_buff.data()), len, flags, &src_addr, &src_addr_len); 624 int ret = ::recvfrom(socket_handle, reinterpret_cast<char*>(output_buff.data()), len, flags,
625 &src_addr, &src_addr_len);
623 626
624 if (ret >= 0 && buffer_parameters.output_src_address_buffer != 0 && src_addr_len > 0) { 627 if (ret >= 0 && buffer_parameters.output_src_address_buffer != 0 && src_addr_len > 0) {
625 CTRSockAddr ctr_src_addr = CTRSockAddr::FromPlatform(src_addr); 628 CTRSockAddr ctr_src_addr = CTRSockAddr::FromPlatform(src_addr);
626 Memory::WriteBlock(buffer_parameters.output_src_address_buffer, &ctr_src_addr, sizeof(ctr_src_addr)); 629 Memory::WriteBlock(buffer_parameters.output_src_address_buffer, &ctr_src_addr,
630 sizeof(ctr_src_addr));
627 } 631 }
628 632
629 int result = 0; 633 int result = 0;
@@ -633,7 +637,8 @@ static void RecvFrom(Service::Interface* self) {
633 total_received = 0; 637 total_received = 0;
634 } else { 638 } else {
635 // Write only the data we received to avoid overwriting parts of the buffer with zeros 639 // Write only the data we received to avoid overwriting parts of the buffer with zeros
636 Memory::WriteBlock(buffer_parameters.output_buffer_addr, output_buff.data(), total_received); 640 Memory::WriteBlock(buffer_parameters.output_buffer_addr, output_buff.data(),
641 total_received);
637 } 642 }
638 643
639 cmd_buffer[1] = result; 644 cmd_buffer[1] = result;
@@ -648,7 +653,8 @@ static void Poll(Service::Interface* self) {
648 653
649 VAddr input_fds_addr = cmd_buffer[6]; 654 VAddr input_fds_addr = cmd_buffer[6];
650 VAddr output_fds_addr = cmd_buffer[0x104 >> 2]; 655 VAddr output_fds_addr = cmd_buffer[0x104 >> 2];
651 if (!Memory::IsValidVirtualAddress(input_fds_addr) || !Memory::IsValidVirtualAddress(output_fds_addr)) { 656 if (!Memory::IsValidVirtualAddress(input_fds_addr) ||
657 !Memory::IsValidVirtualAddress(output_fds_addr)) {
652 cmd_buffer[1] = -1; // TODO(Subv): Find correct error code. 658 cmd_buffer[1] = -1; // TODO(Subv): Find correct error code.
653 return; 659 return;
654 } 660 }
@@ -656,7 +662,8 @@ static void Poll(Service::Interface* self) {
656 std::vector<CTRPollFD> ctr_fds(nfds); 662 std::vector<CTRPollFD> ctr_fds(nfds);
657 Memory::ReadBlock(input_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD)); 663 Memory::ReadBlock(input_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD));
658 664
659 // The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different sizes) 665 // The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different
666 // sizes)
660 // so we have to copy the data 667 // so we have to copy the data
661 std::vector<pollfd> platform_pollfd(nfds); 668 std::vector<pollfd> platform_pollfd(nfds);
662 std::transform(ctr_fds.begin(), ctr_fds.end(), platform_pollfd.begin(), CTRPollFD::ToPlatform); 669 std::transform(ctr_fds.begin(), ctr_fds.end(), platform_pollfd.begin(), CTRPollFD::ToPlatform);
@@ -664,7 +671,8 @@ static void Poll(Service::Interface* self) {
664 const int ret = ::poll(platform_pollfd.data(), nfds, timeout); 671 const int ret = ::poll(platform_pollfd.data(), nfds, timeout);
665 672
666 // Now update the output pollfd structure 673 // Now update the output pollfd structure
667 std::transform(platform_pollfd.begin(), platform_pollfd.end(), ctr_fds.begin(), CTRPollFD::FromPlatform); 674 std::transform(platform_pollfd.begin(), platform_pollfd.end(), ctr_fds.begin(),
675 CTRPollFD::FromPlatform);
668 676
669 Memory::WriteBlock(output_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD)); 677 Memory::WriteBlock(output_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD));
670 678
@@ -775,7 +783,7 @@ static void Connect(Service::Interface* self) {
775} 783}
776 784
777static void InitializeSockets(Service::Interface* self) { 785static void InitializeSockets(Service::Interface* self) {
778 // TODO(Subv): Implement 786// TODO(Subv): Implement
779#ifdef _WIN32 787#ifdef _WIN32
780 WSADATA data; 788 WSADATA data;
781 WSAStartup(MAKEWORD(2, 2), &data); 789 WSAStartup(MAKEWORD(2, 2), &data);
@@ -808,7 +816,7 @@ static void GetSockOpt(Service::Interface* self) {
808 int ret = -1; 816 int ret = -1;
809 int err = 0; 817 int err = 0;
810 818
811 if(optname < 0) { 819 if (optname < 0) {
812#ifdef _WIN32 820#ifdef _WIN32
813 err = WSAEINVAL; 821 err = WSAEINVAL;
814#else 822#else
@@ -818,7 +826,7 @@ static void GetSockOpt(Service::Interface* self) {
818 // 0x100 = static buffer offset (bytes) 826 // 0x100 = static buffer offset (bytes)
819 // + 0x4 = 2nd pointer (u32) position 827 // + 0x4 = 2nd pointer (u32) position
820 // >> 2 = convert to u32 offset instead of byte offset (cmd_buffer = u32*) 828 // >> 2 = convert to u32 offset instead of byte offset (cmd_buffer = u32*)
821 char* optval = reinterpret_cast<char *>(Memory::GetPointer(cmd_buffer[0x104 >> 2])); 829 char* optval = reinterpret_cast<char*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
822 830
823 ret = ::getsockopt(socket_handle, level, optname, optval, &optlen); 831 ret = ::getsockopt(socket_handle, level, optname, optval, &optlen);
824 err = 0; 832 err = 0;
@@ -842,7 +850,7 @@ static void SetSockOpt(Service::Interface* self) {
842 int ret = -1; 850 int ret = -1;
843 int err = 0; 851 int err = 0;
844 852
845 if(optname < 0) { 853 if (optname < 0) {
846#ifdef _WIN32 854#ifdef _WIN32
847 err = WSAEINVAL; 855 err = WSAEINVAL;
848#else 856#else
@@ -850,7 +858,7 @@ static void SetSockOpt(Service::Interface* self) {
850#endif 858#endif
851 } else { 859 } else {
852 socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]); 860 socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]);
853 const char* optval = reinterpret_cast<const char *>(Memory::GetPointer(cmd_buffer[8])); 861 const char* optval = reinterpret_cast<const char*>(Memory::GetPointer(cmd_buffer[8]));
854 862
855 ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen)); 863 ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen));
856 err = 0; 864 err = 0;
@@ -865,39 +873,39 @@ static void SetSockOpt(Service::Interface* self) {
865} 873}
866 874
867const Interface::FunctionInfo FunctionTable[] = { 875const Interface::FunctionInfo FunctionTable[] = {
868 {0x00010044, InitializeSockets, "InitializeSockets"}, 876 {0x00010044, InitializeSockets, "InitializeSockets"},
869 {0x000200C2, Socket, "Socket"}, 877 {0x000200C2, Socket, "Socket"},
870 {0x00030082, Listen, "Listen"}, 878 {0x00030082, Listen, "Listen"},
871 {0x00040082, Accept, "Accept"}, 879 {0x00040082, Accept, "Accept"},
872 {0x00050084, Bind, "Bind"}, 880 {0x00050084, Bind, "Bind"},
873 {0x00060084, Connect, "Connect"}, 881 {0x00060084, Connect, "Connect"},
874 {0x00070104, nullptr, "recvfrom_other"}, 882 {0x00070104, nullptr, "recvfrom_other"},
875 {0x00080102, RecvFrom, "RecvFrom"}, 883 {0x00080102, RecvFrom, "RecvFrom"},
876 {0x00090106, nullptr, "sendto_other"}, 884 {0x00090106, nullptr, "sendto_other"},
877 {0x000A0106, SendTo, "SendTo"}, 885 {0x000A0106, SendTo, "SendTo"},
878 {0x000B0042, Close, "Close"}, 886 {0x000B0042, Close, "Close"},
879 {0x000C0082, Shutdown, "Shutdown"}, 887 {0x000C0082, Shutdown, "Shutdown"},
880 {0x000D0082, nullptr, "GetHostByName"}, 888 {0x000D0082, nullptr, "GetHostByName"},
881 {0x000E00C2, nullptr, "GetHostByAddr"}, 889 {0x000E00C2, nullptr, "GetHostByAddr"},
882 {0x000F0106, nullptr, "GetAddrInfo"}, 890 {0x000F0106, nullptr, "GetAddrInfo"},
883 {0x00100102, nullptr, "GetNameInfo"}, 891 {0x00100102, nullptr, "GetNameInfo"},
884 {0x00110102, GetSockOpt, "GetSockOpt"}, 892 {0x00110102, GetSockOpt, "GetSockOpt"},
885 {0x00120104, SetSockOpt, "SetSockOpt"}, 893 {0x00120104, SetSockOpt, "SetSockOpt"},
886 {0x001300C2, Fcntl, "Fcntl"}, 894 {0x001300C2, Fcntl, "Fcntl"},
887 {0x00140084, Poll, "Poll"}, 895 {0x00140084, Poll, "Poll"},
888 {0x00150042, nullptr, "SockAtMark"}, 896 {0x00150042, nullptr, "SockAtMark"},
889 {0x00160000, GetHostId, "GetHostId"}, 897 {0x00160000, GetHostId, "GetHostId"},
890 {0x00170082, GetSockName, "GetSockName"}, 898 {0x00170082, GetSockName, "GetSockName"},
891 {0x00180082, GetPeerName, "GetPeerName"}, 899 {0x00180082, GetPeerName, "GetPeerName"},
892 {0x00190000, ShutdownSockets, "ShutdownSockets"}, 900 {0x00190000, ShutdownSockets, "ShutdownSockets"},
893 {0x001A00C0, nullptr, "GetNetworkOpt"}, 901 {0x001A00C0, nullptr, "GetNetworkOpt"},
894 {0x001B0040, nullptr, "ICMPSocket"}, 902 {0x001B0040, nullptr, "ICMPSocket"},
895 {0x001C0104, nullptr, "ICMPPing"}, 903 {0x001C0104, nullptr, "ICMPPing"},
896 {0x001D0040, nullptr, "ICMPCancel"}, 904 {0x001D0040, nullptr, "ICMPCancel"},
897 {0x001E0040, nullptr, "ICMPClose"}, 905 {0x001E0040, nullptr, "ICMPClose"},
898 {0x001F0040, nullptr, "GetResolverInfo"}, 906 {0x001F0040, nullptr, "GetResolverInfo"},
899 {0x00210002, nullptr, "CloseSockets"}, 907 {0x00210002, nullptr, "CloseSockets"},
900 {0x00230040, nullptr, "AddGlobalSocket"}, 908 {0x00230040, nullptr, "AddGlobalSocket"},
901}; 909};
902 910
903//////////////////////////////////////////////////////////////////////////////////////////////////// 911////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h
index a091f597c..8d02ed30f 100644
--- a/src/core/hle/service/soc_u.h
+++ b/src/core/hle/service/soc_u.h
@@ -5,7 +5,6 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8
9#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
10 9
11//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 3c05f836b..b25be413a 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -4,9 +4,8 @@
4 4
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7
8#include "core/hle/service/srv.h"
9#include "core/hle/kernel/event.h" 7#include "core/hle/kernel/event.h"
8#include "core/hle/service/srv.h"
10 9
11//////////////////////////////////////////////////////////////////////////////////////////////////// 10////////////////////////////////////////////////////////////////////////////////////////////////////
12// Namespace SRV 11// Namespace SRV
@@ -28,13 +27,14 @@ static void RegisterClient(Service::Interface* self) {
28 u32* cmd_buff = Kernel::GetCommandBuffer(); 27 u32* cmd_buff = Kernel::GetCommandBuffer();
29 28
30 if (cmd_buff[1] != IPC::CallingPidDesc()) { 29 if (cmd_buff[1] != IPC::CallingPidDesc()) {
31 cmd_buff[0] = IPC::MakeHeader(0x0, 0x1, 0); //0x40 30 cmd_buff[0] = IPC::MakeHeader(0x0, 0x1, 0); // 0x40
32 cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, 31 cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
33 ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; 32 ErrorSummary::WrongArgument, ErrorLevel::Permanent)
33 .raw;
34 return; 34 return;
35 } 35 }
36 cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); //0x10040 36 cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); // 0x10040
37 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 37 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
38 LOG_WARNING(Service_SRV, "(STUBBED) called"); 38 LOG_WARNING(Service_SRV, "(STUBBED) called");
39} 39}
40 40
@@ -56,7 +56,7 @@ static void EnableNotification(Service::Interface* self) {
56 event_handle->Clear(); 56 event_handle->Clear();
57 57
58 cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0x2); // 0x20042 58 cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0x2); // 0x20042
59 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 59 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
60 cmd_buff[2] = IPC::CopyHandleDesc(1); 60 cmd_buff[2] = IPC::CopyHandleDesc(1);
61 cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom(); 61 cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom();
62 LOG_WARNING(Service_SRV, "(STUBBED) called"); 62 LOG_WARNING(Service_SRV, "(STUBBED) called");
@@ -105,7 +105,7 @@ static void Subscribe(Service::Interface* self) {
105 u32 notification_id = cmd_buff[1]; 105 u32 notification_id = cmd_buff[1];
106 106
107 cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0); // 0x90040 107 cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0); // 0x90040
108 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 108 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
109 LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id); 109 LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id);
110} 110}
111 111
@@ -124,7 +124,7 @@ static void Unsubscribe(Service::Interface* self) {
124 u32 notification_id = cmd_buff[1]; 124 u32 notification_id = cmd_buff[1];
125 125
126 cmd_buff[0] = IPC::MakeHeader(0xA, 0x1, 0); // 0xA0040 126 cmd_buff[0] = IPC::MakeHeader(0xA, 0x1, 0); // 0xA0040
127 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 127 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
128 LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id); 128 LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id);
129} 129}
130 130
@@ -145,25 +145,26 @@ static void PublishToSubscriber(Service::Interface* self) {
145 u8 flags = cmd_buff[2] & 0xFF; 145 u8 flags = cmd_buff[2] & 0xFF;
146 146
147 cmd_buff[0] = IPC::MakeHeader(0xC, 0x1, 0); // 0xC0040 147 cmd_buff[0] = IPC::MakeHeader(0xC, 0x1, 0); // 0xC0040
148 cmd_buff[1] = RESULT_SUCCESS.raw; // No error 148 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
149 LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X, flags=%u", notification_id, flags); 149 LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X, flags=%u", notification_id,
150 flags);
150} 151}
151 152
152const Interface::FunctionInfo FunctionTable[] = { 153const Interface::FunctionInfo FunctionTable[] = {
153 {0x00010002, RegisterClient, "RegisterClient"}, 154 {0x00010002, RegisterClient, "RegisterClient"},
154 {0x00020000, EnableNotification, "EnableNotification"}, 155 {0x00020000, EnableNotification, "EnableNotification"},
155 {0x00030100, nullptr, "RegisterService"}, 156 {0x00030100, nullptr, "RegisterService"},
156 {0x000400C0, nullptr, "UnregisterService"}, 157 {0x000400C0, nullptr, "UnregisterService"},
157 {0x00050100, GetServiceHandle, "GetServiceHandle"}, 158 {0x00050100, GetServiceHandle, "GetServiceHandle"},
158 {0x000600C2, nullptr, "RegisterPort"}, 159 {0x000600C2, nullptr, "RegisterPort"},
159 {0x000700C0, nullptr, "UnregisterPort"}, 160 {0x000700C0, nullptr, "UnregisterPort"},
160 {0x00080100, nullptr, "GetPort"}, 161 {0x00080100, nullptr, "GetPort"},
161 {0x00090040, Subscribe, "Subscribe"}, 162 {0x00090040, Subscribe, "Subscribe"},
162 {0x000A0040, Unsubscribe, "Unsubscribe"}, 163 {0x000A0040, Unsubscribe, "Unsubscribe"},
163 {0x000B0000, nullptr, "ReceiveNotification"}, 164 {0x000B0000, nullptr, "ReceiveNotification"},
164 {0x000C0080, PublishToSubscriber, "PublishToSubscriber"}, 165 {0x000C0080, PublishToSubscriber, "PublishToSubscriber"},
165 {0x000D0040, nullptr, "PublishAndGetSubscriber"}, 166 {0x000D0040, nullptr, "PublishAndGetSubscriber"},
166 {0x000E00C0, nullptr, "IsServiceRegistered"}, 167 {0x000E00C0, nullptr, "IsServiceRegistered"},
167}; 168};
168 169
169//////////////////////////////////////////////////////////////////////////////////////////////////// 170////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp
index a8aff1abf..abab1d271 100644
--- a/src/core/hle/service/ssl_c.cpp
+++ b/src/core/hle/service/ssl_c.cpp
@@ -3,7 +3,6 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <random> 5#include <random>
6
7#include "common/common_types.h" 6#include "common/common_types.h"
8#include "core/hle/service/ssl_c.h" 7#include "core/hle/service/ssl_c.h"
9 8
@@ -37,7 +36,8 @@ static void GenerateRandomData(Service::Interface* self) {
37 u32 i = 0; 36 u32 i = 0;
38 while (i < size) { 37 while (i < size) {
39 if ((i % 4) == 0) { 38 if ((i % 4) == 0) {
40 // The random number generator returns 4 bytes worth of data, so generate new random data when i == 0 and when i is divisible by 4 39 // The random number generator returns 4 bytes worth of data, so generate new random
40 // data when i == 0 and when i is divisible by 4
41 data = rand_gen(); 41 data = rand_gen();
42 } 42 }
43 43
@@ -59,26 +59,26 @@ static void GenerateRandomData(Service::Interface* self) {
59} 59}
60 60
61const Interface::FunctionInfo FunctionTable[] = { 61const Interface::FunctionInfo FunctionTable[] = {
62 {0x00010002, Initialize, "Initialize"}, 62 {0x00010002, Initialize, "Initialize"},
63 {0x000200C2, nullptr, "CreateContext"}, 63 {0x000200C2, nullptr, "CreateContext"},
64 {0x00030000, nullptr, "CreateRootCertChain"}, 64 {0x00030000, nullptr, "CreateRootCertChain"},
65 {0x00040040, nullptr, "DestroyRootCertChain"}, 65 {0x00040040, nullptr, "DestroyRootCertChain"},
66 {0x00050082, nullptr, "AddTrustedRootCA"}, 66 {0x00050082, nullptr, "AddTrustedRootCA"},
67 {0x00060080, nullptr, "RootCertChainAddDefaultCert"}, 67 {0x00060080, nullptr, "RootCertChainAddDefaultCert"},
68 {0x00070080, nullptr, "RootCertChainRemoveCert"}, 68 {0x00070080, nullptr, "RootCertChainRemoveCert"},
69 {0x000E0040, nullptr, "OpenDefaultClientCertContext"}, 69 {0x000E0040, nullptr, "OpenDefaultClientCertContext"},
70 {0x000F0040, nullptr, "CloseClientCertContext"}, 70 {0x000F0040, nullptr, "CloseClientCertContext"},
71 {0x00110042, GenerateRandomData, "GenerateRandomData"}, 71 {0x00110042, GenerateRandomData, "GenerateRandomData"},
72 {0x00120042, nullptr, "InitializeConnectionSession"}, 72 {0x00120042, nullptr, "InitializeConnectionSession"},
73 {0x00130040, nullptr, "StartConnection"}, 73 {0x00130040, nullptr, "StartConnection"},
74 {0x00140040, nullptr, "StartConnectionGetOut"}, 74 {0x00140040, nullptr, "StartConnectionGetOut"},
75 {0x00150082, nullptr, "Read"}, 75 {0x00150082, nullptr, "Read"},
76 {0x00170082, nullptr, "Write"}, 76 {0x00170082, nullptr, "Write"},
77 {0x00180080, nullptr, "ContextSetRootCertChain"}, 77 {0x00180080, nullptr, "ContextSetRootCertChain"},
78 {0x00190080, nullptr, "ContextSetClientCert"}, 78 {0x00190080, nullptr, "ContextSetClientCert"},
79 {0x001B0080, nullptr, "ContextClearOpt"}, 79 {0x001B0080, nullptr, "ContextClearOpt"},
80 {0x001E0040, nullptr, "DestroyContext"}, 80 {0x001E0040, nullptr, "DestroyContext"},
81 {0x001F0082, nullptr, "ContextInitSharedmem"} 81 {0x001F0082, nullptr, "ContextInitSharedmem"},
82}; 82};
83 83
84//////////////////////////////////////////////////////////////////////////////////////////////////// 84////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
index d16578f87..097e09d28 100644
--- a/src/core/hle/service/y2r_u.cpp
+++ b/src/core/hle/service/y2r_u.cpp
@@ -3,11 +3,9 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring> 5#include <cstring>
6
7#include "common/common_funcs.h" 6#include "common/common_funcs.h"
8#include "common/common_types.h" 7#include "common/common_types.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10
11#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
12#include "core/hle/kernel/kernel.h" 10#include "core/hle/kernel/kernel.h"
13#include "core/hle/service/y2r_u.h" 11#include "core/hle/service/y2r_u.h"
@@ -39,16 +37,16 @@ static u32 transfer_end_interrupt_enabled = 0;
39static u32 spacial_dithering_enabled = 0; 37static u32 spacial_dithering_enabled = 0;
40 38
41static const CoefficientSet standard_coefficients[4] = { 39static const CoefficientSet standard_coefficients[4] = {
42 {{ 0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B }}, // ITU_Rec601 40 {{0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B}}, // ITU_Rec601
43 {{ 0x100, 0x193, 0x77, 0x2F, 0x1DB, -0x1933, 0xA7C, -0x1D51 }}, // ITU_Rec709 41 {{0x100, 0x193, 0x77, 0x2F, 0x1DB, -0x1933, 0xA7C, -0x1D51}}, // ITU_Rec709
44 {{ 0x12A, 0x198, 0xD0, 0x64, 0x204, -0x1BDE, 0x10F2, -0x229B }}, // ITU_Rec601_Scaling 42 {{0x12A, 0x198, 0xD0, 0x64, 0x204, -0x1BDE, 0x10F2, -0x229B}}, // ITU_Rec601_Scaling
45 {{ 0x12A, 0x1CA, 0x88, 0x36, 0x21C, -0x1F04, 0x99C, -0x2421 }}, // ITU_Rec709_Scaling 43 {{0x12A, 0x1CA, 0x88, 0x36, 0x21C, -0x1F04, 0x99C, -0x2421}}, // ITU_Rec709_Scaling
46}; 44};
47 45
48ResultCode ConversionConfiguration::SetInputLineWidth(u16 width) { 46ResultCode ConversionConfiguration::SetInputLineWidth(u16 width) {
49 if (width == 0 || width > 1024 || width % 8 != 0) { 47 if (width == 0 || width > 1024 || width % 8 != 0) {
50 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::CAM, 48 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::CAM,
51 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD 49 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD
52 } 50 }
53 51
54 // Note: The hardware uses the register value 0 to represent a width of 1024, so for a width of 52 // Note: The hardware uses the register value 0 to represent a width of 1024, so for a width of
@@ -61,7 +59,7 @@ ResultCode ConversionConfiguration::SetInputLineWidth(u16 width) {
61ResultCode ConversionConfiguration::SetInputLines(u16 lines) { 59ResultCode ConversionConfiguration::SetInputLines(u16 lines) {
62 if (lines == 0 || lines > 1024) { 60 if (lines == 0 || lines > 1024) {
63 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::CAM, 61 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::CAM,
64 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD 62 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD
65 } 63 }
66 64
67 // Note: In what appears to be a bug, the `camera` module does not set the hardware register at 65 // Note: In what appears to be a bug, the `camera` module does not set the hardware register at
@@ -73,11 +71,12 @@ ResultCode ConversionConfiguration::SetInputLines(u16 lines) {
73 return RESULT_SUCCESS; 71 return RESULT_SUCCESS;
74} 72}
75 73
76ResultCode ConversionConfiguration::SetStandardCoefficient(StandardCoefficient standard_coefficient) { 74ResultCode ConversionConfiguration::SetStandardCoefficient(
75 StandardCoefficient standard_coefficient) {
77 size_t index = static_cast<size_t>(standard_coefficient); 76 size_t index = static_cast<size_t>(standard_coefficient);
78 if (index >= ARRAY_SIZE(standard_coefficients)) { 77 if (index >= ARRAY_SIZE(standard_coefficients)) {
79 return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::CAM, 78 return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::CAM,
80 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053ED 79 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053ED
81 } 80 }
82 81
83 std::memcpy(coefficients.data(), standard_coefficients[index].data(), sizeof(coefficients)); 82 std::memcpy(coefficients.data(), standard_coefficients[index].data(), sizeof(coefficients));
@@ -294,8 +293,10 @@ static void SetSendingY(Service::Interface* self) {
294 cmd_buff[0] = IPC::MakeHeader(0x10, 1, 0); 293 cmd_buff[0] = IPC::MakeHeader(0x10, 1, 0);
295 cmd_buff[1] = RESULT_SUCCESS.raw; 294 cmd_buff[1] = RESULT_SUCCESS.raw;
296 295
297 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", 296 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, "
298 conversion.src_Y.image_size, conversion.src_Y.transfer_unit, conversion.src_Y.gap, cmd_buff[6]); 297 "src_process_handle=0x%08X",
298 conversion.src_Y.image_size, conversion.src_Y.transfer_unit, conversion.src_Y.gap,
299 cmd_buff[6]);
299} 300}
300 301
301static void SetSendingU(Service::Interface* self) { 302static void SetSendingU(Service::Interface* self) {
@@ -309,8 +310,10 @@ static void SetSendingU(Service::Interface* self) {
309 cmd_buff[0] = IPC::MakeHeader(0x11, 1, 0); 310 cmd_buff[0] = IPC::MakeHeader(0x11, 1, 0);
310 cmd_buff[1] = RESULT_SUCCESS.raw; 311 cmd_buff[1] = RESULT_SUCCESS.raw;
311 312
312 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", 313 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, "
313 conversion.src_U.image_size, conversion.src_U.transfer_unit, conversion.src_U.gap, cmd_buff[6]); 314 "src_process_handle=0x%08X",
315 conversion.src_U.image_size, conversion.src_U.transfer_unit, conversion.src_U.gap,
316 cmd_buff[6]);
314} 317}
315 318
316static void SetSendingV(Service::Interface* self) { 319static void SetSendingV(Service::Interface* self) {
@@ -324,8 +327,10 @@ static void SetSendingV(Service::Interface* self) {
324 cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0); 327 cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0);
325 cmd_buff[1] = RESULT_SUCCESS.raw; 328 cmd_buff[1] = RESULT_SUCCESS.raw;
326 329
327 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", 330 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, "
328 conversion.src_V.image_size, conversion.src_V.transfer_unit, conversion.src_V.gap, cmd_buff[6]); 331 "src_process_handle=0x%08X",
332 conversion.src_V.image_size, conversion.src_V.transfer_unit, conversion.src_V.gap,
333 cmd_buff[6]);
329} 334}
330 335
331static void SetSendingYUYV(Service::Interface* self) { 336static void SetSendingYUYV(Service::Interface* self) {
@@ -339,8 +344,10 @@ static void SetSendingYUYV(Service::Interface* self) {
339 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); 344 cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0);
340 cmd_buff[1] = RESULT_SUCCESS.raw; 345 cmd_buff[1] = RESULT_SUCCESS.raw;
341 346
342 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", 347 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, "
343 conversion.src_YUYV.image_size, conversion.src_YUYV.transfer_unit, conversion.src_YUYV.gap, cmd_buff[6]); 348 "src_process_handle=0x%08X",
349 conversion.src_YUYV.image_size, conversion.src_YUYV.transfer_unit,
350 conversion.src_YUYV.gap, cmd_buff[6]);
344} 351}
345 352
346/** 353/**
@@ -418,8 +425,10 @@ static void SetReceiving(Service::Interface* self) {
418 cmd_buff[0] = IPC::MakeHeader(0x18, 1, 0); 425 cmd_buff[0] = IPC::MakeHeader(0x18, 1, 0);
419 cmd_buff[1] = RESULT_SUCCESS.raw; 426 cmd_buff[1] = RESULT_SUCCESS.raw;
420 427
421 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, dst_process_handle=0x%08X", 428 LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, "
422 conversion.dst.image_size, conversion.dst.transfer_unit, conversion.dst.gap, cmd_buff[6]); 429 "dst_process_handle=0x%08X",
430 conversion.dst.image_size, conversion.dst.transfer_unit, conversion.dst.gap,
431 cmd_buff[6]);
423} 432}
424 433
425/** 434/**
@@ -486,8 +495,8 @@ static void SetCoefficient(Service::Interface* self) {
486 cmd_buff[1] = RESULT_SUCCESS.raw; 495 cmd_buff[1] = RESULT_SUCCESS.raw;
487 496
488 LOG_DEBUG(Service_Y2R, "called coefficients=[%hX, %hX, %hX, %hX, %hX, %hX, %hX, %hX]", 497 LOG_DEBUG(Service_Y2R, "called coefficients=[%hX, %hX, %hX, %hX, %hX, %hX, %hX, %hX]",
489 coefficients[0], coefficients[1], coefficients[2], coefficients[3], 498 coefficients[0], coefficients[1], coefficients[2], coefficients[3], coefficients[4],
490 coefficients[4], coefficients[5], coefficients[6], coefficients[7]); 499 coefficients[5], coefficients[6], coefficients[7]);
491} 500}
492 501
493static void GetCoefficient(Service::Interface* self) { 502static void GetCoefficient(Service::Interface* self) {
@@ -575,8 +584,10 @@ static void StartConversion(Service::Interface* self) {
575 u32* cmd_buff = Kernel::GetCommandBuffer(); 584 u32* cmd_buff = Kernel::GetCommandBuffer();
576 585
577 // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( 586 // dst_image_size would seem to be perfect for this, but it doesn't include the gap :(
578 u32 total_output_size = conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); 587 u32 total_output_size =
579 Memory::RasterizerFlushAndInvalidateRegion(Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); 588 conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap);
589 Memory::RasterizerFlushAndInvalidateRegion(
590 Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size);
580 591
581 HW::Y2R::PerformConversion(conversion); 592 HW::Y2R::PerformConversion(conversion);
582 593
@@ -648,10 +659,13 @@ cleanup:
648 cmd_buff[0] = IPC::MakeHeader(0x29, 1, 0); 659 cmd_buff[0] = IPC::MakeHeader(0x29, 1, 0);
649 cmd_buff[1] = result.raw; 660 cmd_buff[1] = result.raw;
650 661
651 LOG_DEBUG(Service_Y2R, "called input_format=%hhu output_format=%hhu rotation=%hhu block_alignment=%hhu " 662 LOG_DEBUG(
652 "input_line_width=%hu input_lines=%hu standard_coefficient=%hhu reserved=%hhu alpha=%hX", 663 Service_Y2R,
653 params->input_format, params->output_format, params->rotation, params->block_alignment, 664 "called input_format=%hhu output_format=%hhu rotation=%hhu block_alignment=%hhu "
654 params->input_line_width, params->input_lines, params->standard_coefficient, params->padding, params->alpha); 665 "input_line_width=%hu input_lines=%hu standard_coefficient=%hhu reserved=%hhu alpha=%hX",
666 params->input_format, params->output_format, params->rotation, params->block_alignment,
667 params->input_line_width, params->input_lines, params->standard_coefficient,
668 params->padding, params->alpha);
655} 669}
656 670
657static void PingProcess(Service::Interface* self) { 671static void PingProcess(Service::Interface* self) {
@@ -699,7 +713,6 @@ static void DriverFinalize(Service::Interface* self) {
699 LOG_DEBUG(Service_Y2R, "called"); 713 LOG_DEBUG(Service_Y2R, "called");
700} 714}
701 715
702
703static void GetPackageParameter(Service::Interface* self) { 716static void GetPackageParameter(Service::Interface* self) {
704 u32* cmd_buff = Kernel::GetCommandBuffer(); 717 u32* cmd_buff = Kernel::GetCommandBuffer();
705 718
@@ -711,51 +724,51 @@ static void GetPackageParameter(Service::Interface* self) {
711} 724}
712 725
713const Interface::FunctionInfo FunctionTable[] = { 726const Interface::FunctionInfo FunctionTable[] = {
714 {0x00010040, SetInputFormat, "SetInputFormat"}, 727 {0x00010040, SetInputFormat, "SetInputFormat"},
715 {0x00020000, GetInputFormat, "GetInputFormat"}, 728 {0x00020000, GetInputFormat, "GetInputFormat"},
716 {0x00030040, SetOutputFormat, "SetOutputFormat"}, 729 {0x00030040, SetOutputFormat, "SetOutputFormat"},
717 {0x00040000, GetOutputFormat, "GetOutputFormat"}, 730 {0x00040000, GetOutputFormat, "GetOutputFormat"},
718 {0x00050040, SetRotation, "SetRotation"}, 731 {0x00050040, SetRotation, "SetRotation"},
719 {0x00060000, GetRotation, "GetRotation"}, 732 {0x00060000, GetRotation, "GetRotation"},
720 {0x00070040, SetBlockAlignment, "SetBlockAlignment"}, 733 {0x00070040, SetBlockAlignment, "SetBlockAlignment"},
721 {0x00080000, GetBlockAlignment, "GetBlockAlignment"}, 734 {0x00080000, GetBlockAlignment, "GetBlockAlignment"},
722 {0x00090040, SetSpacialDithering, "SetSpacialDithering"}, 735 {0x00090040, SetSpacialDithering, "SetSpacialDithering"},
723 {0x000A0000, GetSpacialDithering, "GetSpacialDithering"}, 736 {0x000A0000, GetSpacialDithering, "GetSpacialDithering"},
724 {0x000B0040, SetTemporalDithering, "SetTemporalDithering"}, 737 {0x000B0040, SetTemporalDithering, "SetTemporalDithering"},
725 {0x000C0000, GetTemporalDithering, "GetTemporalDithering"}, 738 {0x000C0000, GetTemporalDithering, "GetTemporalDithering"},
726 {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"}, 739 {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"},
727 {0x000E0000, GetTransferEndInterrupt, "GetTransferEndInterrupt"}, 740 {0x000E0000, GetTransferEndInterrupt, "GetTransferEndInterrupt"},
728 {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, 741 {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"},
729 {0x00100102, SetSendingY, "SetSendingY"}, 742 {0x00100102, SetSendingY, "SetSendingY"},
730 {0x00110102, SetSendingU, "SetSendingU"}, 743 {0x00110102, SetSendingU, "SetSendingU"},
731 {0x00120102, SetSendingV, "SetSendingV"}, 744 {0x00120102, SetSendingV, "SetSendingV"},
732 {0x00130102, SetSendingYUYV, "SetSendingYUYV"}, 745 {0x00130102, SetSendingYUYV, "SetSendingYUYV"},
733 {0x00140000, IsFinishedSendingYuv, "IsFinishedSendingYuv"}, 746 {0x00140000, IsFinishedSendingYuv, "IsFinishedSendingYuv"},
734 {0x00150000, IsFinishedSendingY, "IsFinishedSendingY"}, 747 {0x00150000, IsFinishedSendingY, "IsFinishedSendingY"},
735 {0x00160000, IsFinishedSendingU, "IsFinishedSendingU"}, 748 {0x00160000, IsFinishedSendingU, "IsFinishedSendingU"},
736 {0x00170000, IsFinishedSendingV, "IsFinishedSendingV"}, 749 {0x00170000, IsFinishedSendingV, "IsFinishedSendingV"},
737 {0x00180102, SetReceiving, "SetReceiving"}, 750 {0x00180102, SetReceiving, "SetReceiving"},
738 {0x00190000, IsFinishedReceiving, "IsFinishedReceiving"}, 751 {0x00190000, IsFinishedReceiving, "IsFinishedReceiving"},
739 {0x001A0040, SetInputLineWidth, "SetInputLineWidth"}, 752 {0x001A0040, SetInputLineWidth, "SetInputLineWidth"},
740 {0x001B0000, GetInputLineWidth, "GetInputLineWidth"}, 753 {0x001B0000, GetInputLineWidth, "GetInputLineWidth"},
741 {0x001C0040, SetInputLines, "SetInputLines"}, 754 {0x001C0040, SetInputLines, "SetInputLines"},
742 {0x001D0000, GetInputLines, "GetInputLines"}, 755 {0x001D0000, GetInputLines, "GetInputLines"},
743 {0x001E0100, SetCoefficient, "SetCoefficient"}, 756 {0x001E0100, SetCoefficient, "SetCoefficient"},
744 {0x001F0000, GetCoefficient, "GetCoefficient"}, 757 {0x001F0000, GetCoefficient, "GetCoefficient"},
745 {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"}, 758 {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"},
746 {0x00210040, GetStandardCoefficient, "GetStandardCoefficient"}, 759 {0x00210040, GetStandardCoefficient, "GetStandardCoefficient"},
747 {0x00220040, SetAlpha, "SetAlpha"}, 760 {0x00220040, SetAlpha, "SetAlpha"},
748 {0x00230000, GetAlpha, "GetAlpha"}, 761 {0x00230000, GetAlpha, "GetAlpha"},
749 {0x00240200, SetDitheringWeightParams,"SetDitheringWeightParams"}, 762 {0x00240200, SetDitheringWeightParams, "SetDitheringWeightParams"},
750 {0x00250000, GetDitheringWeightParams,"GetDitheringWeightParams"}, 763 {0x00250000, GetDitheringWeightParams, "GetDitheringWeightParams"},
751 {0x00260000, StartConversion, "StartConversion"}, 764 {0x00260000, StartConversion, "StartConversion"},
752 {0x00270000, StopConversion, "StopConversion"}, 765 {0x00270000, StopConversion, "StopConversion"},
753 {0x00280000, IsBusyConversion, "IsBusyConversion"}, 766 {0x00280000, IsBusyConversion, "IsBusyConversion"},
754 {0x002901C0, SetPackageParameter, "SetPackageParameter"}, 767 {0x002901C0, SetPackageParameter, "SetPackageParameter"},
755 {0x002A0000, PingProcess, "PingProcess"}, 768 {0x002A0000, PingProcess, "PingProcess"},
756 {0x002B0000, DriverInitialize, "DriverInitialize"}, 769 {0x002B0000, DriverInitialize, "DriverInitialize"},
757 {0x002C0000, DriverFinalize, "DriverFinalize"}, 770 {0x002C0000, DriverFinalize, "DriverFinalize"},
758 {0x002D0000, GetPackageParameter, "GetPackageParameter"}, 771 {0x002D0000, GetPackageParameter, "GetPackageParameter"},
759}; 772};
760 773
761//////////////////////////////////////////////////////////////////////////////////////////////////// 774////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
index 95fa2fdb7..1b47b5322 100644
--- a/src/core/hle/service/y2r_u.h
+++ b/src/core/hle/service/y2r_u.h
@@ -6,9 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <string> 8#include <string>
9
10#include "common/common_types.h" 9#include "common/common_types.h"
11
12#include "core/hle/result.h" 10#include "core/hle/result.h"
13#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
14 12
diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp
index 4d9272923..d0d92487d 100644
--- a/src/core/hle/shared_page.cpp
+++ b/src/core/hle/shared_page.cpp
@@ -5,7 +5,6 @@
5#include <chrono> 5#include <chrono>
6#include <cstring> 6#include <cstring>
7#include <ctime> 7#include <ctime>
8
9#include "core/core_timing.h" 8#include "core/core_timing.h"
10#include "core/hle/shared_page.h" 9#include "core/hle/shared_page.h"
11 10
@@ -52,8 +51,8 @@ static u64 GetSystemTime() {
52} 51}
53 52
54static void UpdateTimeCallback(u64 userdata, int cycles_late) { 53static void UpdateTimeCallback(u64 userdata, int cycles_late) {
55 DateTime& date_time = shared_page.date_time_counter % 2 ? 54 DateTime& date_time =
56 shared_page.date_time_0 : shared_page.date_time_1; 55 shared_page.date_time_counter % 2 ? shared_page.date_time_0 : shared_page.date_time_1;
57 56
58 date_time.date_time = GetSystemTime(); 57 date_time.date_time = GetSystemTime();
59 date_time.update_tick = CoreTiming::GetTicks(); 58 date_time.update_tick = CoreTiming::GetTicks();
@@ -74,7 +73,8 @@ void Init() {
74 // Some games wait until this value becomes 0x1, before asking running_hw 73 // Some games wait until this value becomes 0x1, before asking running_hw
75 shared_page.unknown_value = 0x1; 74 shared_page.unknown_value = 0x1;
76 75
77 update_time_event = CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback); 76 update_time_event =
77 CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback);
78 CoreTiming::ScheduleEvent(0, update_time_event); 78 CoreTiming::ScheduleEvent(0, update_time_event);
79} 79}
80 80
diff --git a/src/core/hle/shared_page.h b/src/core/hle/shared_page.h
index cd9246726..106e47efc 100644
--- a/src/core/hle/shared_page.h
+++ b/src/core/hle/shared_page.h
@@ -13,7 +13,6 @@
13#include "common/common_funcs.h" 13#include "common/common_funcs.h"
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/swap.h" 15#include "common/swap.h"
16
17#include "core/memory.h" 16#include "core/memory.h"
18 17
19//////////////////////////////////////////////////////////////////////////////////////////////////// 18////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,27 +31,28 @@ static_assert(sizeof(DateTime) == 0x20, "Datetime size is wrong");
32 31
33struct SharedPageDef { 32struct SharedPageDef {
34 // Most of these names are taken from the 3dbrew page linked above. 33 // Most of these names are taken from the 3dbrew page linked above.
35 u32_le date_time_counter; // 0 34 u32_le date_time_counter; // 0
36 u8 running_hw; // 4 35 u8 running_hw; // 4
37 /// "Microcontroller hardware info" 36 /// "Microcontroller hardware info"
38 u8 mcu_hw_info; // 5 37 u8 mcu_hw_info; // 5
39 INSERT_PADDING_BYTES(0x20 - 0x6); // 6 38 INSERT_PADDING_BYTES(0x20 - 0x6); // 6
40 DateTime date_time_0; // 20 39 DateTime date_time_0; // 20
41 DateTime date_time_1; // 40 40 DateTime date_time_1; // 40
42 u8 wifi_macaddr[6]; // 60 41 u8 wifi_macaddr[6]; // 60
43 u8 wifi_link_level; // 66 42 u8 wifi_link_level; // 66
44 u8 wifi_unknown2; // 67 43 u8 wifi_unknown2; // 67
45 INSERT_PADDING_BYTES(0x80 - 0x68); // 68 44 INSERT_PADDING_BYTES(0x80 - 0x68); // 68
46 float_le sliderstate_3d; // 80 45 float_le sliderstate_3d; // 80
47 u8 ledstate_3d; // 84 46 u8 ledstate_3d; // 84
48 INSERT_PADDING_BYTES(1); // 85 47 INSERT_PADDING_BYTES(1); // 85
49 u8 unknown_value; // 86 48 u8 unknown_value; // 86
50 INSERT_PADDING_BYTES(0xA0 - 0x87); // 87 49 INSERT_PADDING_BYTES(0xA0 - 0x87); // 87
51 u64_le menu_title_id; // A0 50 u64_le menu_title_id; // A0
52 u64_le active_menu_title_id; // A8 51 u64_le active_menu_title_id; // A8
53 INSERT_PADDING_BYTES(0x1000 - 0xB0); // B0 52 INSERT_PADDING_BYTES(0x1000 - 0xB0); // B0
54}; 53};
55static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong"); 54static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE,
55 "Shared page structure size is wrong");
56 56
57extern SharedPageDef shared_page; 57extern SharedPageDef shared_page;
58 58
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 5d71d5619..02b397eba 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -3,16 +3,14 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <map> 5#include <map>
6
7#include "common/logging/log.h" 6#include "common/logging/log.h"
8#include "common/microprofile.h" 7#include "common/microprofile.h"
9#include "common/scope_exit.h" 8#include "common/scope_exit.h"
10#include "common/string_util.h" 9#include "common/string_util.h"
11#include "common/symbols.h" 10#include "common/symbols.h"
12
13#include "core/core_timing.h"
14#include "core/arm/arm_interface.h" 11#include "core/arm/arm_interface.h"
15 12#include "core/core_timing.h"
13#include "core/hle/function_wrappers.h"
16#include "core/hle/kernel/address_arbiter.h" 14#include "core/hle/kernel/address_arbiter.h"
17#include "core/hle/kernel/client_port.h" 15#include "core/hle/kernel/client_port.h"
18#include "core/hle/kernel/event.h" 16#include "core/hle/kernel/event.h"
@@ -26,8 +24,6 @@
26#include "core/hle/kernel/thread.h" 24#include "core/hle/kernel/thread.h"
27#include "core/hle/kernel/timer.h" 25#include "core/hle/kernel/timer.h"
28#include "core/hle/kernel/vm_manager.h" 26#include "core/hle/kernel/vm_manager.h"
29
30#include "core/hle/function_wrappers.h"
31#include "core/hle/result.h" 27#include "core/hle/result.h"
32#include "core/hle/service/service.h" 28#include "core/hle/service/service.h"
33 29
@@ -40,43 +36,46 @@ using Kernel::ERR_INVALID_HANDLE;
40namespace SVC { 36namespace SVC {
41 37
42const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, 38const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel,
43 ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA 39 ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA
44const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, 40const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS,
45 ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E 41 ErrorSummary::InvalidArgument,
46 42 ErrorLevel::Usage); // 0xE0E0181E
47const ResultCode ERR_MISALIGNED_ADDRESS{ // 0xE0E01BF1 43
48 ErrorDescription::MisalignedAddress, ErrorModule::OS, 44const ResultCode ERR_MISALIGNED_ADDRESS{// 0xE0E01BF1
49 ErrorSummary::InvalidArgument, ErrorLevel::Usage}; 45 ErrorDescription::MisalignedAddress, ErrorModule::OS,
50const ResultCode ERR_MISALIGNED_SIZE{ // 0xE0E01BF2 46 ErrorSummary::InvalidArgument, ErrorLevel::Usage};
51 ErrorDescription::MisalignedSize, ErrorModule::OS, 47const ResultCode ERR_MISALIGNED_SIZE{// 0xE0E01BF2
52 ErrorSummary::InvalidArgument, ErrorLevel::Usage}; 48 ErrorDescription::MisalignedSize, ErrorModule::OS,
53const ResultCode ERR_INVALID_COMBINATION{ // 0xE0E01BEE 49 ErrorSummary::InvalidArgument, ErrorLevel::Usage};
54 ErrorDescription::InvalidCombination, ErrorModule::OS, 50const ResultCode ERR_INVALID_COMBINATION{// 0xE0E01BEE
55 ErrorSummary::InvalidArgument, ErrorLevel::Usage}; 51 ErrorDescription::InvalidCombination, ErrorModule::OS,
52 ErrorSummary::InvalidArgument, ErrorLevel::Usage};
56 53
57enum ControlMemoryOperation { 54enum ControlMemoryOperation {
58 MEMOP_FREE = 1, 55 MEMOP_FREE = 1,
59 MEMOP_RESERVE = 2, // This operation seems to be unsupported in the kernel 56 MEMOP_RESERVE = 2, // This operation seems to be unsupported in the kernel
60 MEMOP_COMMIT = 3, 57 MEMOP_COMMIT = 3,
61 MEMOP_MAP = 4, 58 MEMOP_MAP = 4,
62 MEMOP_UNMAP = 5, 59 MEMOP_UNMAP = 5,
63 MEMOP_PROTECT = 6, 60 MEMOP_PROTECT = 6,
64 MEMOP_OPERATION_MASK = 0xFF, 61 MEMOP_OPERATION_MASK = 0xFF,
65 62
66 MEMOP_REGION_APP = 0x100, 63 MEMOP_REGION_APP = 0x100,
67 MEMOP_REGION_SYSTEM = 0x200, 64 MEMOP_REGION_SYSTEM = 0x200,
68 MEMOP_REGION_BASE = 0x300, 65 MEMOP_REGION_BASE = 0x300,
69 MEMOP_REGION_MASK = 0xF00, 66 MEMOP_REGION_MASK = 0xF00,
70 67
71 MEMOP_LINEAR = 0x10000, 68 MEMOP_LINEAR = 0x10000,
72}; 69};
73 70
74/// Map application or GSP heap memory 71/// Map application or GSP heap memory
75static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { 72static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size,
73 u32 permissions) {
76 using namespace Kernel; 74 using namespace Kernel;
77 75
78 LOG_DEBUG(Kernel_SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=0x%X, permissions=0x%08X", 76 LOG_DEBUG(Kernel_SVC,
79 operation, addr0, addr1, size, permissions); 77 "called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=0x%X, permissions=0x%08X",
78 operation, addr0, addr1, size, permissions);
80 79
81 if ((addr0 & Memory::PAGE_MASK) != 0 || (addr1 & Memory::PAGE_MASK) != 0) { 80 if ((addr0 & Memory::PAGE_MASK) != 0 || (addr1 & Memory::PAGE_MASK) != 0) {
82 return ERR_MISALIGNED_ADDRESS; 81 return ERR_MISALIGNED_ADDRESS;
@@ -89,7 +88,8 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
89 operation &= ~MEMOP_REGION_MASK; 88 operation &= ~MEMOP_REGION_MASK;
90 89
91 if (region != 0) { 90 if (region != 0) {
92 LOG_WARNING(Kernel_SVC, "ControlMemory with specified region not supported, region=%X", region); 91 LOG_WARNING(Kernel_SVC, "ControlMemory with specified region not supported, region=%X",
92 region);
93 } 93 }
94 94
95 if ((permissions & (u32)MemoryPermission::ReadWrite) != permissions) { 95 if ((permissions & (u32)MemoryPermission::ReadWrite) != permissions) {
@@ -100,15 +100,17 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
100 auto& process = *g_current_process; 100 auto& process = *g_current_process;
101 101
102 switch (operation & MEMOP_OPERATION_MASK) { 102 switch (operation & MEMOP_OPERATION_MASK) {
103 case MEMOP_FREE: 103 case MEMOP_FREE: {
104 { 104 // TODO(Subv): What happens if an application tries to FREE a block of memory that has a
105 // TODO(Subv): What happens if an application tries to FREE a block of memory that has a SharedMemory pointing to it? 105 // SharedMemory pointing to it?
106 if (addr0 >= Memory::HEAP_VADDR && addr0 < Memory::HEAP_VADDR_END) { 106 if (addr0 >= Memory::HEAP_VADDR && addr0 < Memory::HEAP_VADDR_END) {
107 ResultCode result = process.HeapFree(addr0, size); 107 ResultCode result = process.HeapFree(addr0, size);
108 if (result.IsError()) return result; 108 if (result.IsError())
109 return result;
109 } else if (addr0 >= process.GetLinearHeapBase() && addr0 < process.GetLinearHeapLimit()) { 110 } else if (addr0 >= process.GetLinearHeapBase() && addr0 < process.GetLinearHeapLimit()) {
110 ResultCode result = process.LinearFree(addr0, size); 111 ResultCode result = process.LinearFree(addr0, size);
111 if (result.IsError()) return result; 112 if (result.IsError())
113 return result;
112 } else { 114 } else {
113 return ERR_INVALID_ADDRESS; 115 return ERR_INVALID_ADDRESS;
114 } 116 }
@@ -116,8 +118,7 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
116 break; 118 break;
117 } 119 }
118 120
119 case MEMOP_COMMIT: 121 case MEMOP_COMMIT: {
120 {
121 if (operation & MEMOP_LINEAR) { 122 if (operation & MEMOP_LINEAR) {
122 CASCADE_RESULT(*out_addr, process.LinearAllocate(addr0, size, vma_permissions)); 123 CASCADE_RESULT(*out_addr, process.LinearAllocate(addr0, size, vma_permissions));
123 } else { 124 } else {
@@ -126,23 +127,26 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add
126 break; 127 break;
127 } 128 }
128 129
129 case MEMOP_MAP: // TODO: This is just a hack to avoid regressions until memory aliasing is implemented 130 case MEMOP_MAP: // TODO: This is just a hack to avoid regressions until memory aliasing is
130 { 131 // implemented
131 CASCADE_RESULT(*out_addr, process.HeapAllocate(addr0, size, vma_permissions)); 132 {
132 break; 133 CASCADE_RESULT(*out_addr, process.HeapAllocate(addr0, size, vma_permissions));
133 } 134 break;
135 }
134 136
135 case MEMOP_UNMAP: // TODO: This is just a hack to avoid regressions until memory aliasing is implemented 137 case MEMOP_UNMAP: // TODO: This is just a hack to avoid regressions until memory aliasing is
136 { 138 // implemented
137 ResultCode result = process.HeapFree(addr0, size); 139 {
138 if (result.IsError()) return result; 140 ResultCode result = process.HeapFree(addr0, size);
139 break; 141 if (result.IsError())
140 } 142 return result;
143 break;
144 }
141 145
142 case MEMOP_PROTECT: 146 case MEMOP_PROTECT: {
143 {
144 ResultCode result = process.vm_manager.ReprotectRange(addr0, size, vma_permissions); 147 ResultCode result = process.vm_manager.ReprotectRange(addr0, size, vma_permissions);
145 if (result.IsError()) return result; 148 if (result.IsError())
149 return result;
146 break; 150 break;
147 } 151 }
148 152
@@ -161,8 +165,9 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
161 using Kernel::SharedMemory; 165 using Kernel::SharedMemory;
162 using Kernel::MemoryPermission; 166 using Kernel::MemoryPermission;
163 167
164 LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", 168 LOG_TRACE(Kernel_SVC,
165 handle, addr, permissions, other_permissions); 169 "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",
170 handle, addr, permissions, other_permissions);
166 171
167 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); 172 SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
168 if (shared_memory == nullptr) 173 if (shared_memory == nullptr)
@@ -179,12 +184,13 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o
179 case MemoryPermission::ReadWriteExecute: 184 case MemoryPermission::ReadWriteExecute:
180 case MemoryPermission::DontCare: 185 case MemoryPermission::DontCare:
181 return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type, 186 return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type,
182 static_cast<MemoryPermission>(other_permissions)); 187 static_cast<MemoryPermission>(other_permissions));
183 default: 188 default:
184 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); 189 LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
185 } 190 }
186 191
187 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 192 return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS,
193 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
188} 194}
189 195
190static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { 196static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) {
@@ -249,7 +255,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
249 return ERR_INVALID_HANDLE; 255 return ERR_INVALID_HANDLE;
250 256
251 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, 257 LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle,
252 object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); 258 object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds);
253 259
254 HLE::Reschedule(__func__); 260 HLE::Reschedule(__func__);
255 261
@@ -257,7 +263,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
257 if (object->ShouldWait()) { 263 if (object->ShouldWait()) {
258 264
259 object->AddWaitingThread(thread); 265 object->AddWaitingThread(thread);
260 Kernel::WaitCurrentThread_WaitSynchronization({ object }, false, false); 266 Kernel::WaitCurrentThread_WaitSynchronization({object}, false, false);
261 267
262 // Create an event to wake the thread up after the specified nanosecond delay has passed 268 // Create an event to wake the thread up after the specified nanosecond delay has passed
263 thread->WakeAfterDelay(nano_seconds); 269 thread->WakeAfterDelay(nano_seconds);
@@ -272,7 +278,8 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) {
272} 278}
273 279
274/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 280/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
275static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) { 281static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all,
282 s64 nano_seconds) {
276 bool wait_thread = !wait_all; 283 bool wait_thread = !wait_all;
277 int handle_index = 0; 284 int handle_index = 0;
278 Kernel::Thread* thread = Kernel::GetCurrentThread(); 285 Kernel::Thread* thread = Kernel::GetCurrentThread();
@@ -281,7 +288,8 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
281 288
282 // Check if 'handles' is invalid 289 // Check if 'handles' is invalid
283 if (handles == nullptr) 290 if (handles == nullptr)
284 return ResultCode(ErrorDescription::InvalidPointer, ErrorModule::Kernel, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 291 return ResultCode(ErrorDescription::InvalidPointer, ErrorModule::Kernel,
292 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
285 293
286 // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If 294 // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If
287 // this happens, the running application will crash. 295 // this happens, the running application will crash.
@@ -289,7 +297,8 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
289 297
290 // Check if 'handle_count' is invalid 298 // Check if 'handle_count' is invalid
291 if (handle_count < 0) 299 if (handle_count < 0)
292 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 300 return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS,
301 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
293 302
294 // If 'handle_count' is non-zero, iterate through each handle and wait the current thread if 303 // If 'handle_count' is non-zero, iterate through each handle and wait the current thread if
295 // necessary 304 // necessary
@@ -329,7 +338,9 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou
329 } 338 }
330 } 339 }
331 340
332 SCOPE_EXIT({HLE::Reschedule("WaitSynchronizationN");}); // Reschedule after putting the threads to sleep. 341 SCOPE_EXIT({
342 HLE::Reschedule("WaitSynchronizationN");
343 }); // Reschedule after putting the threads to sleep.
333 344
334 // If thread should wait, then set its state to waiting 345 // If thread should wait, then set its state to waiting
335 if (wait_thread) { 346 if (wait_thread) {
@@ -386,18 +397,19 @@ static ResultCode CreateAddressArbiter(Handle* out_handle) {
386} 397}
387 398
388/// Arbitrate address 399/// Arbitrate address
389static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds) { 400static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value,
401 s64 nanoseconds) {
390 using Kernel::AddressArbiter; 402 using Kernel::AddressArbiter;
391 403
392 LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", handle, 404 LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", handle,
393 address, type, value); 405 address, type, value);
394 406
395 SharedPtr<AddressArbiter> arbiter = Kernel::g_handle_table.Get<AddressArbiter>(handle); 407 SharedPtr<AddressArbiter> arbiter = Kernel::g_handle_table.Get<AddressArbiter>(handle);
396 if (arbiter == nullptr) 408 if (arbiter == nullptr)
397 return ERR_INVALID_HANDLE; 409 return ERR_INVALID_HANDLE;
398 410
399 auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), 411 auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), address, value,
400 address, value, nanoseconds); 412 nanoseconds);
401 413
402 return res; 414 return res;
403} 415}
@@ -406,10 +418,18 @@ static void Break(u8 break_reason) {
406 LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); 418 LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!");
407 std::string reason_str; 419 std::string reason_str;
408 switch (break_reason) { 420 switch (break_reason) {
409 case 0: reason_str = "PANIC"; break; 421 case 0:
410 case 1: reason_str = "ASSERT"; break; 422 reason_str = "PANIC";
411 case 2: reason_str = "USER"; break; 423 break;
412 default: reason_str = "UNKNOWN"; break; 424 case 1:
425 reason_str = "ASSERT";
426 break;
427 case 2:
428 reason_str = "USER";
429 break;
430 default:
431 reason_str = "UNKNOWN";
432 break;
413 } 433 }
414 LOG_CRITICAL(Debug_Emulated, "Break reason: %s", reason_str.c_str()); 434 LOG_CRITICAL(Debug_Emulated, "Break reason: %s", reason_str.c_str());
415} 435}
@@ -423,7 +443,8 @@ static void OutputDebugString(const char* string) {
423static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { 443static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) {
424 LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); 444 LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle);
425 445
426 SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle); 446 SharedPtr<Kernel::Process> process =
447 Kernel::g_handle_table.Get<Kernel::Process>(process_handle);
427 if (process == nullptr) 448 if (process == nullptr)
428 return ERR_INVALID_HANDLE; 449 return ERR_INVALID_HANDLE;
429 450
@@ -433,12 +454,13 @@ static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle
433} 454}
434 455
435/// Get resource limit current values 456/// Get resource limit current values
436static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, 457static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle,
437 u32 name_count) { 458 u32* names, u32 name_count) {
438 LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", 459 LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
439 resource_limit_handle, names, name_count); 460 resource_limit_handle, names, name_count);
440 461
441 SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); 462 SharedPtr<Kernel::ResourceLimit> resource_limit =
463 Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle);
442 if (resource_limit == nullptr) 464 if (resource_limit == nullptr)
443 return ERR_INVALID_HANDLE; 465 return ERR_INVALID_HANDLE;
444 466
@@ -450,11 +472,12 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_lim
450 472
451/// Get resource limit max values 473/// Get resource limit max values
452static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, 474static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names,
453 u32 name_count) { 475 u32 name_count) {
454 LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", 476 LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d",
455 resource_limit_handle, names, name_count); 477 resource_limit_handle, names, name_count);
456 478
457 SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); 479 SharedPtr<Kernel::ResourceLimit> resource_limit =
480 Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle);
458 if (resource_limit == nullptr) 481 if (resource_limit == nullptr)
459 return ERR_INVALID_HANDLE; 482 return ERR_INVALID_HANDLE;
460 483
@@ -465,7 +488,8 @@ static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit
465} 488}
466 489
467/// Creates a new thread 490/// Creates a new thread
468static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { 491static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point, u32 arg,
492 u32 stack_top, s32 processor_id) {
469 using Kernel::Thread; 493 using Kernel::Thread;
470 494
471 std::string name; 495 std::string name;
@@ -499,20 +523,23 @@ static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point
499 } 523 }
500 524
501 if (processor_id == THREADPROCESSORID_1 || processor_id == THREADPROCESSORID_ALL || 525 if (processor_id == THREADPROCESSORID_1 || processor_id == THREADPROCESSORID_ALL ||
502 (processor_id == THREADPROCESSORID_DEFAULT && Kernel::g_current_process->ideal_processor == THREADPROCESSORID_1)) { 526 (processor_id == THREADPROCESSORID_DEFAULT &&
503 LOG_WARNING(Kernel_SVC, "Newly created thread is allowed to be run in the SysCore, unimplemented."); 527 Kernel::g_current_process->ideal_processor == THREADPROCESSORID_1)) {
528 LOG_WARNING(Kernel_SVC,
529 "Newly created thread is allowed to be run in the SysCore, unimplemented.");
504 } 530 }
505 531
506 CASCADE_RESULT(SharedPtr<Thread> thread, Kernel::Thread::Create( 532 CASCADE_RESULT(SharedPtr<Thread> thread, Kernel::Thread::Create(name, entry_point, priority,
507 name, entry_point, priority, arg, processor_id, stack_top)); 533 arg, processor_id, stack_top));
508 534
509 thread->context.fpscr = FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000 535 thread->context.fpscr =
536 FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000
510 537
511 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread))); 538 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread)));
512 539
513 LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " 540 LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
514 "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", entry_point, 541 "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
515 name.c_str(), arg, stack_top, priority, processor_id, *out_handle); 542 entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle);
516 543
517 return RESULT_SUCCESS; 544 return RESULT_SUCCESS;
518} 545}
@@ -552,7 +579,7 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) {
552 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); 579 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex)));
553 580
554 LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", 581 LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X",
555 initial_locked ? "true" : "false", *out_handle); 582 initial_locked ? "true" : "false", *out_handle);
556 583
557 return RESULT_SUCCESS; 584 return RESULT_SUCCESS;
558} 585}
@@ -576,7 +603,8 @@ static ResultCode ReleaseMutex(Handle handle) {
576static ResultCode GetProcessId(u32* process_id, Handle process_handle) { 603static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
577 LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); 604 LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle);
578 605
579 const SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle); 606 const SharedPtr<Kernel::Process> process =
607 Kernel::g_handle_table.Get<Kernel::Process>(process_handle);
580 if (process == nullptr) 608 if (process == nullptr)
581 return ERR_INVALID_HANDLE; 609 return ERR_INVALID_HANDLE;
582 610
@@ -588,7 +616,8 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
588static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { 616static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) {
589 LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); 617 LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle);
590 618
591 const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle); 619 const SharedPtr<Kernel::Thread> thread =
620 Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle);
592 if (thread == nullptr) 621 if (thread == nullptr)
593 return ERR_INVALID_HANDLE; 622 return ERR_INVALID_HANDLE;
594 623
@@ -620,7 +649,7 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max
620 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(semaphore))); 649 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(semaphore)));
621 650
622 LOG_TRACE(Kernel_SVC, "called initial_count=%d, max_count=%d, created handle=0x%08X", 651 LOG_TRACE(Kernel_SVC, "called initial_count=%d, max_count=%d, created handle=0x%08X",
623 initial_count, max_count, *out_handle); 652 initial_count, max_count, *out_handle);
624 return RESULT_SUCCESS; 653 return RESULT_SUCCESS;
625} 654}
626 655
@@ -640,7 +669,8 @@ static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count)
640} 669}
641 670
642/// Query process memory 671/// Query process memory
643static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, Handle process_handle, u32 addr) { 672static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info,
673 Handle process_handle, u32 addr) {
644 using Kernel::Process; 674 using Kernel::Process;
645 Kernel::SharedPtr<Process> process = Kernel::g_handle_table.Get<Process>(process_handle); 675 Kernel::SharedPtr<Process> process = Kernel::g_handle_table.Get<Process>(process_handle);
646 if (process == nullptr) 676 if (process == nullptr)
@@ -649,7 +679,8 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_inf
649 auto vma = process->vm_manager.FindVMA(addr); 679 auto vma = process->vm_manager.FindVMA(addr);
650 680
651 if (vma == Kernel::g_current_process->vm_manager.vma_map.end()) 681 if (vma == Kernel::g_current_process->vm_manager.vma_map.end())
652 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 682 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS,
683 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
653 684
654 memory_info->base_address = vma->second.base; 685 memory_info->base_address = vma->second.base;
655 memory_info->permission = static_cast<u32>(vma->second.permissions); 686 memory_info->permission = static_cast<u32>(vma->second.permissions);
@@ -673,8 +704,8 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) {
673 SharedPtr<Event> evt = Event::Create(static_cast<Kernel::ResetType>(reset_type)); 704 SharedPtr<Event> evt = Event::Create(static_cast<Kernel::ResetType>(reset_type));
674 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); 705 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt)));
675 706
676 LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", 707 LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type,
677 reset_type, *out_handle); 708 *out_handle);
678 return RESULT_SUCCESS; 709 return RESULT_SUCCESS;
679} 710}
680 711
@@ -719,8 +750,8 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) {
719 SharedPtr<Timer> timer = Timer::Create(static_cast<Kernel::ResetType>(reset_type)); 750 SharedPtr<Timer> timer = Timer::Create(static_cast<Kernel::ResetType>(reset_type));
720 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); 751 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer)));
721 752
722 LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", 753 LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type,
723 reset_type, *out_handle); 754 *out_handle);
724 return RESULT_SUCCESS; 755 return RESULT_SUCCESS;
725} 756}
726 757
@@ -783,17 +814,19 @@ static void SleepThread(s64 nanoseconds) {
783static s64 GetSystemTick() { 814static s64 GetSystemTick() {
784 s64 result = CoreTiming::GetTicks(); 815 s64 result = CoreTiming::GetTicks();
785 // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end. 816 // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
786 Core::g_app_core->AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b 817 Core::g_app_core->AddTicks(
818 150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
787 return result; 819 return result;
788} 820}
789 821
790/// Creates a memory block at the specified address with the specified permissions and size 822/// Creates a memory block at the specified address with the specified permissions and size
791static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, 823static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission,
792 u32 other_permission) { 824 u32 other_permission) {
793 using Kernel::SharedMemory; 825 using Kernel::SharedMemory;
794 826
795 if (size % Memory::PAGE_SIZE != 0) 827 if (size % Memory::PAGE_SIZE != 0)
796 return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 828 return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS,
829 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
797 830
798 SharedPtr<SharedMemory> shared_memory = nullptr; 831 SharedPtr<SharedMemory> shared_memory = nullptr;
799 832
@@ -818,25 +851,29 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
818 ErrorSummary::InvalidArgument, ErrorLevel::Usage); 851 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
819 852
820 if (addr < Memory::PROCESS_IMAGE_VADDR || addr + size > Memory::SHARED_MEMORY_VADDR_END) { 853 if (addr < Memory::PROCESS_IMAGE_VADDR || addr + size > Memory::SHARED_MEMORY_VADDR_END) {
821 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); 854 return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS,
855 ErrorSummary::InvalidArgument, ErrorLevel::Usage);
822 } 856 }
823 857
824 // When trying to create a memory block with address = 0, 858 // When trying to create a memory block with address = 0,
825 // if the process has the Shared Device Memory flag in the exheader, 859 // if the process has the Shared Device Memory flag in the exheader,
826 // then we have to allocate from the same region as the caller process instead of the BASE region. 860 // then we have to allocate from the same region as the caller process instead of the BASE
861 // region.
827 Kernel::MemoryRegion region = Kernel::MemoryRegion::BASE; 862 Kernel::MemoryRegion region = Kernel::MemoryRegion::BASE;
828 if (addr == 0 && Kernel::g_current_process->flags.shared_device_mem) 863 if (addr == 0 && Kernel::g_current_process->flags.shared_device_mem)
829 region = Kernel::g_current_process->flags.memory_region; 864 region = Kernel::g_current_process->flags.memory_region;
830 865
831 shared_memory = SharedMemory::Create(Kernel::g_current_process, size, 866 shared_memory = SharedMemory::Create(
832 static_cast<MemoryPermission>(my_permission), static_cast<MemoryPermission>(other_permission), addr, region); 867 Kernel::g_current_process, size, static_cast<MemoryPermission>(my_permission),
868 static_cast<MemoryPermission>(other_permission), addr, region);
833 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); 869 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory)));
834 870
835 LOG_WARNING(Kernel_SVC, "called addr=0x%08X", addr); 871 LOG_WARNING(Kernel_SVC, "called addr=0x%08X", addr);
836 return RESULT_SUCCESS; 872 return RESULT_SUCCESS;
837} 873}
838 874
839static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name, u32 max_sessions) { 875static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name,
876 u32 max_sessions) {
840 // TODO(Subv): Implement named ports. 877 // TODO(Subv): Implement named ports.
841 ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented"); 878 ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented");
842 879
@@ -845,9 +882,12 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, const cha
845 using Kernel::SharedPtr; 882 using Kernel::SharedPtr;
846 883
847 auto ports = ServerPort::CreatePortPair(max_sessions); 884 auto ports = ServerPort::CreatePortPair(max_sessions);
848 CASCADE_RESULT(*client_port, Kernel::g_handle_table.Create(std::move(std::get<SharedPtr<ClientPort>>(ports)))); 885 CASCADE_RESULT(*client_port, Kernel::g_handle_table.Create(
849 // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be created. 886 std::move(std::get<SharedPtr<ClientPort>>(ports))));
850 CASCADE_RESULT(*server_port, Kernel::g_handle_table.Create(std::move(std::get<SharedPtr<ServerPort>>(ports)))); 887 // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be
888 // created.
889 CASCADE_RESULT(*server_port, Kernel::g_handle_table.Create(
890 std::move(std::get<SharedPtr<ServerPort>>(ports))));
851 891
852 LOG_TRACE(Kernel_SVC, "called max_sessions=%u", max_sessions); 892 LOG_TRACE(Kernel_SVC, "called max_sessions=%u", max_sessions);
853 return RESULT_SUCCESS; 893 return RESULT_SUCCESS;
@@ -862,9 +902,9 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
862 case SystemInfoType::REGION_MEMORY_USAGE: 902 case SystemInfoType::REGION_MEMORY_USAGE:
863 switch ((SystemInfoMemUsageRegion)param) { 903 switch ((SystemInfoMemUsageRegion)param) {
864 case SystemInfoMemUsageRegion::ALL: 904 case SystemInfoMemUsageRegion::ALL:
865 *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used 905 *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used +
866 + Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used 906 Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used +
867 + Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used; 907 Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used;
868 break; 908 break;
869 case SystemInfoMemUsageRegion::APPLICATION: 909 case SystemInfoMemUsageRegion::APPLICATION:
870 *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used; 910 *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used;
@@ -912,7 +952,7 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
912 // TODO(yuriks): Type 0 returns a slightly higher number than type 2, but I'm not sure 952 // TODO(yuriks): Type 0 returns a slightly higher number than type 2, but I'm not sure
913 // what's the difference between them. 953 // what's the difference between them.
914 *out = process->heap_used + process->linear_heap_used + process->misc_memory_used; 954 *out = process->heap_used + process->linear_heap_used + process->misc_memory_used;
915 if(*out % Memory::PAGE_SIZE != 0) { 955 if (*out % Memory::PAGE_SIZE != 0) {
916 LOG_ERROR(Kernel_SVC, "called, memory size not page-aligned"); 956 LOG_ERROR(Kernel_SVC, "called, memory size not page-aligned");
917 return ERR_MISALIGNED_SIZE; 957 return ERR_MISALIGNED_SIZE;
918 } 958 }
@@ -935,12 +975,12 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
935 975
936 if (type >= 21 && type <= 23) { 976 if (type >= 21 && type <= 23) {
937 return ResultCode( // 0xE0E01BF4 977 return ResultCode( // 0xE0E01BF4
938 ErrorDescription::NotImplemented, ErrorModule::OS, 978 ErrorDescription::NotImplemented, ErrorModule::OS, ErrorSummary::InvalidArgument,
939 ErrorSummary::InvalidArgument, ErrorLevel::Usage); 979 ErrorLevel::Usage);
940 } else { 980 } else {
941 return ResultCode( // 0xD8E007ED 981 return ResultCode( // 0xD8E007ED
942 ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, 982 ErrorDescription::InvalidEnumValue, ErrorModule::Kernel,
943 ErrorSummary::InvalidArgument, ErrorLevel::Permanent); 983 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
944 } 984 }
945 break; 985 break;
946 } 986 }
@@ -949,142 +989,142 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) {
949} 989}
950 990
951namespace { 991namespace {
952 struct FunctionDef { 992struct FunctionDef {
953 using Func = void(); 993 using Func = void();
954 994
955 u32 id; 995 u32 id;
956 Func* func; 996 Func* func;
957 const char* name; 997 const char* name;
958 }; 998};
959} 999}
960 1000
961static const FunctionDef SVC_Table[] = { 1001static const FunctionDef SVC_Table[] = {
962 {0x00, nullptr, "Unknown"}, 1002 {0x00, nullptr, "Unknown"},
963 {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"}, 1003 {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"},
964 {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"}, 1004 {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"},
965 {0x03, nullptr, "ExitProcess"}, 1005 {0x03, nullptr, "ExitProcess"},
966 {0x04, nullptr, "GetProcessAffinityMask"}, 1006 {0x04, nullptr, "GetProcessAffinityMask"},
967 {0x05, nullptr, "SetProcessAffinityMask"}, 1007 {0x05, nullptr, "SetProcessAffinityMask"},
968 {0x06, nullptr, "GetProcessIdealProcessor"}, 1008 {0x06, nullptr, "GetProcessIdealProcessor"},
969 {0x07, nullptr, "SetProcessIdealProcessor"}, 1009 {0x07, nullptr, "SetProcessIdealProcessor"},
970 {0x08, HLE::Wrap<CreateThread>, "CreateThread"}, 1010 {0x08, HLE::Wrap<CreateThread>, "CreateThread"},
971 {0x09, ExitThread, "ExitThread"}, 1011 {0x09, ExitThread, "ExitThread"},
972 {0x0A, HLE::Wrap<SleepThread>, "SleepThread"}, 1012 {0x0A, HLE::Wrap<SleepThread>, "SleepThread"},
973 {0x0B, HLE::Wrap<GetThreadPriority>, "GetThreadPriority"}, 1013 {0x0B, HLE::Wrap<GetThreadPriority>, "GetThreadPriority"},
974 {0x0C, HLE::Wrap<SetThreadPriority>, "SetThreadPriority"}, 1014 {0x0C, HLE::Wrap<SetThreadPriority>, "SetThreadPriority"},
975 {0x0D, nullptr, "GetThreadAffinityMask"}, 1015 {0x0D, nullptr, "GetThreadAffinityMask"},
976 {0x0E, nullptr, "SetThreadAffinityMask"}, 1016 {0x0E, nullptr, "SetThreadAffinityMask"},
977 {0x0F, nullptr, "GetThreadIdealProcessor"}, 1017 {0x0F, nullptr, "GetThreadIdealProcessor"},
978 {0x10, nullptr, "SetThreadIdealProcessor"}, 1018 {0x10, nullptr, "SetThreadIdealProcessor"},
979 {0x11, nullptr, "GetCurrentProcessorNumber"}, 1019 {0x11, nullptr, "GetCurrentProcessorNumber"},
980 {0x12, nullptr, "Run"}, 1020 {0x12, nullptr, "Run"},
981 {0x13, HLE::Wrap<CreateMutex>, "CreateMutex"}, 1021 {0x13, HLE::Wrap<CreateMutex>, "CreateMutex"},
982 {0x14, HLE::Wrap<ReleaseMutex>, "ReleaseMutex"}, 1022 {0x14, HLE::Wrap<ReleaseMutex>, "ReleaseMutex"},
983 {0x15, HLE::Wrap<CreateSemaphore>, "CreateSemaphore"}, 1023 {0x15, HLE::Wrap<CreateSemaphore>, "CreateSemaphore"},
984 {0x16, HLE::Wrap<ReleaseSemaphore>, "ReleaseSemaphore"}, 1024 {0x16, HLE::Wrap<ReleaseSemaphore>, "ReleaseSemaphore"},
985 {0x17, HLE::Wrap<CreateEvent>, "CreateEvent"}, 1025 {0x17, HLE::Wrap<CreateEvent>, "CreateEvent"},
986 {0x18, HLE::Wrap<SignalEvent>, "SignalEvent"}, 1026 {0x18, HLE::Wrap<SignalEvent>, "SignalEvent"},
987 {0x19, HLE::Wrap<ClearEvent>, "ClearEvent"}, 1027 {0x19, HLE::Wrap<ClearEvent>, "ClearEvent"},
988 {0x1A, HLE::Wrap<CreateTimer>, "CreateTimer"}, 1028 {0x1A, HLE::Wrap<CreateTimer>, "CreateTimer"},
989 {0x1B, HLE::Wrap<SetTimer>, "SetTimer"}, 1029 {0x1B, HLE::Wrap<SetTimer>, "SetTimer"},
990 {0x1C, HLE::Wrap<CancelTimer>, "CancelTimer"}, 1030 {0x1C, HLE::Wrap<CancelTimer>, "CancelTimer"},
991 {0x1D, HLE::Wrap<ClearTimer>, "ClearTimer"}, 1031 {0x1D, HLE::Wrap<ClearTimer>, "ClearTimer"},
992 {0x1E, HLE::Wrap<CreateMemoryBlock>, "CreateMemoryBlock"}, 1032 {0x1E, HLE::Wrap<CreateMemoryBlock>, "CreateMemoryBlock"},
993 {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"}, 1033 {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"},
994 {0x20, HLE::Wrap<UnmapMemoryBlock>, "UnmapMemoryBlock"}, 1034 {0x20, HLE::Wrap<UnmapMemoryBlock>, "UnmapMemoryBlock"},
995 {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, 1035 {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"},
996 {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"}, 1036 {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"},
997 {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"}, 1037 {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"},
998 {0x24, HLE::Wrap<WaitSynchronization1>, "WaitSynchronization1"}, 1038 {0x24, HLE::Wrap<WaitSynchronization1>, "WaitSynchronization1"},
999 {0x25, HLE::Wrap<WaitSynchronizationN>, "WaitSynchronizationN"}, 1039 {0x25, HLE::Wrap<WaitSynchronizationN>, "WaitSynchronizationN"},
1000 {0x26, nullptr, "SignalAndWait"}, 1040 {0x26, nullptr, "SignalAndWait"},
1001 {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"}, 1041 {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"},
1002 {0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"}, 1042 {0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"},
1003 {0x29, nullptr, "GetHandleInfo"}, 1043 {0x29, nullptr, "GetHandleInfo"},
1004 {0x2A, HLE::Wrap<GetSystemInfo>, "GetSystemInfo"}, 1044 {0x2A, HLE::Wrap<GetSystemInfo>, "GetSystemInfo"},
1005 {0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"}, 1045 {0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"},
1006 {0x2C, nullptr, "GetThreadInfo"}, 1046 {0x2C, nullptr, "GetThreadInfo"},
1007 {0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"}, 1047 {0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"},
1008 {0x2E, nullptr, "SendSyncRequest1"}, 1048 {0x2E, nullptr, "SendSyncRequest1"},
1009 {0x2F, nullptr, "SendSyncRequest2"}, 1049 {0x2F, nullptr, "SendSyncRequest2"},
1010 {0x30, nullptr, "SendSyncRequest3"}, 1050 {0x30, nullptr, "SendSyncRequest3"},
1011 {0x31, nullptr, "SendSyncRequest4"}, 1051 {0x31, nullptr, "SendSyncRequest4"},
1012 {0x32, HLE::Wrap<SendSyncRequest>, "SendSyncRequest"}, 1052 {0x32, HLE::Wrap<SendSyncRequest>, "SendSyncRequest"},
1013 {0x33, nullptr, "OpenProcess"}, 1053 {0x33, nullptr, "OpenProcess"},
1014 {0x34, nullptr, "OpenThread"}, 1054 {0x34, nullptr, "OpenThread"},
1015 {0x35, HLE::Wrap<GetProcessId>, "GetProcessId"}, 1055 {0x35, HLE::Wrap<GetProcessId>, "GetProcessId"},
1016 {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"}, 1056 {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"},
1017 {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"}, 1057 {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"},
1018 {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"}, 1058 {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"},
1019 {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"}, 1059 {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"},
1020 {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, 1060 {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"},
1021 {0x3B, nullptr, "GetThreadContext"}, 1061 {0x3B, nullptr, "GetThreadContext"},
1022 {0x3C, HLE::Wrap<Break>, "Break"}, 1062 {0x3C, HLE::Wrap<Break>, "Break"},
1023 {0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"}, 1063 {0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"},
1024 {0x3E, nullptr, "ControlPerformanceCounter"}, 1064 {0x3E, nullptr, "ControlPerformanceCounter"},
1025 {0x3F, nullptr, "Unknown"}, 1065 {0x3F, nullptr, "Unknown"},
1026 {0x40, nullptr, "Unknown"}, 1066 {0x40, nullptr, "Unknown"},
1027 {0x41, nullptr, "Unknown"}, 1067 {0x41, nullptr, "Unknown"},
1028 {0x42, nullptr, "Unknown"}, 1068 {0x42, nullptr, "Unknown"},
1029 {0x43, nullptr, "Unknown"}, 1069 {0x43, nullptr, "Unknown"},
1030 {0x44, nullptr, "Unknown"}, 1070 {0x44, nullptr, "Unknown"},
1031 {0x45, nullptr, "Unknown"}, 1071 {0x45, nullptr, "Unknown"},
1032 {0x46, nullptr, "Unknown"}, 1072 {0x46, nullptr, "Unknown"},
1033 {0x47, HLE::Wrap<CreatePort>, "CreatePort"}, 1073 {0x47, HLE::Wrap<CreatePort>, "CreatePort"},
1034 {0x48, nullptr, "CreateSessionToPort"}, 1074 {0x48, nullptr, "CreateSessionToPort"},
1035 {0x49, nullptr, "CreateSession"}, 1075 {0x49, nullptr, "CreateSession"},
1036 {0x4A, nullptr, "AcceptSession"}, 1076 {0x4A, nullptr, "AcceptSession"},
1037 {0x4B, nullptr, "ReplyAndReceive1"}, 1077 {0x4B, nullptr, "ReplyAndReceive1"},
1038 {0x4C, nullptr, "ReplyAndReceive2"}, 1078 {0x4C, nullptr, "ReplyAndReceive2"},
1039 {0x4D, nullptr, "ReplyAndReceive3"}, 1079 {0x4D, nullptr, "ReplyAndReceive3"},
1040 {0x4E, nullptr, "ReplyAndReceive4"}, 1080 {0x4E, nullptr, "ReplyAndReceive4"},
1041 {0x4F, nullptr, "ReplyAndReceive"}, 1081 {0x4F, nullptr, "ReplyAndReceive"},
1042 {0x50, nullptr, "BindInterrupt"}, 1082 {0x50, nullptr, "BindInterrupt"},
1043 {0x51, nullptr, "UnbindInterrupt"}, 1083 {0x51, nullptr, "UnbindInterrupt"},
1044 {0x52, nullptr, "InvalidateProcessDataCache"}, 1084 {0x52, nullptr, "InvalidateProcessDataCache"},
1045 {0x53, nullptr, "StoreProcessDataCache"}, 1085 {0x53, nullptr, "StoreProcessDataCache"},
1046 {0x54, nullptr, "FlushProcessDataCache"}, 1086 {0x54, nullptr, "FlushProcessDataCache"},
1047 {0x55, nullptr, "StartInterProcessDma"}, 1087 {0x55, nullptr, "StartInterProcessDma"},
1048 {0x56, nullptr, "StopDma"}, 1088 {0x56, nullptr, "StopDma"},
1049 {0x57, nullptr, "GetDmaState"}, 1089 {0x57, nullptr, "GetDmaState"},
1050 {0x58, nullptr, "RestartDma"}, 1090 {0x58, nullptr, "RestartDma"},
1051 {0x59, nullptr, "Unknown"}, 1091 {0x59, nullptr, "Unknown"},
1052 {0x5A, nullptr, "Unknown"}, 1092 {0x5A, nullptr, "Unknown"},
1053 {0x5B, nullptr, "Unknown"}, 1093 {0x5B, nullptr, "Unknown"},
1054 {0x5C, nullptr, "Unknown"}, 1094 {0x5C, nullptr, "Unknown"},
1055 {0x5D, nullptr, "Unknown"}, 1095 {0x5D, nullptr, "Unknown"},
1056 {0x5E, nullptr, "Unknown"}, 1096 {0x5E, nullptr, "Unknown"},
1057 {0x5F, nullptr, "Unknown"}, 1097 {0x5F, nullptr, "Unknown"},
1058 {0x60, nullptr, "DebugActiveProcess"}, 1098 {0x60, nullptr, "DebugActiveProcess"},
1059 {0x61, nullptr, "BreakDebugProcess"}, 1099 {0x61, nullptr, "BreakDebugProcess"},
1060 {0x62, nullptr, "TerminateDebugProcess"}, 1100 {0x62, nullptr, "TerminateDebugProcess"},
1061 {0x63, nullptr, "GetProcessDebugEvent"}, 1101 {0x63, nullptr, "GetProcessDebugEvent"},
1062 {0x64, nullptr, "ContinueDebugEvent"}, 1102 {0x64, nullptr, "ContinueDebugEvent"},
1063 {0x65, nullptr, "GetProcessList"}, 1103 {0x65, nullptr, "GetProcessList"},
1064 {0x66, nullptr, "GetThreadList"}, 1104 {0x66, nullptr, "GetThreadList"},
1065 {0x67, nullptr, "GetDebugThreadContext"}, 1105 {0x67, nullptr, "GetDebugThreadContext"},
1066 {0x68, nullptr, "SetDebugThreadContext"}, 1106 {0x68, nullptr, "SetDebugThreadContext"},
1067 {0x69, nullptr, "QueryDebugProcessMemory"}, 1107 {0x69, nullptr, "QueryDebugProcessMemory"},
1068 {0x6A, nullptr, "ReadProcessMemory"}, 1108 {0x6A, nullptr, "ReadProcessMemory"},
1069 {0x6B, nullptr, "WriteProcessMemory"}, 1109 {0x6B, nullptr, "WriteProcessMemory"},
1070 {0x6C, nullptr, "SetHardwareBreakPoint"}, 1110 {0x6C, nullptr, "SetHardwareBreakPoint"},
1071 {0x6D, nullptr, "GetDebugThreadParam"}, 1111 {0x6D, nullptr, "GetDebugThreadParam"},
1072 {0x6E, nullptr, "Unknown"}, 1112 {0x6E, nullptr, "Unknown"},
1073 {0x6F, nullptr, "Unknown"}, 1113 {0x6F, nullptr, "Unknown"},
1074 {0x70, nullptr, "ControlProcessMemory"}, 1114 {0x70, nullptr, "ControlProcessMemory"},
1075 {0x71, nullptr, "MapProcessMemory"}, 1115 {0x71, nullptr, "MapProcessMemory"},
1076 {0x72, nullptr, "UnmapProcessMemory"}, 1116 {0x72, nullptr, "UnmapProcessMemory"},
1077 {0x73, nullptr, "CreateCodeSet"}, 1117 {0x73, nullptr, "CreateCodeSet"},
1078 {0x74, nullptr, "RandomStub"}, 1118 {0x74, nullptr, "RandomStub"},
1079 {0x75, nullptr, "CreateProcess"}, 1119 {0x75, nullptr, "CreateProcess"},
1080 {0x76, nullptr, "TerminateProcess"}, 1120 {0x76, nullptr, "TerminateProcess"},
1081 {0x77, nullptr, "SetProcessResourceLimits"}, 1121 {0x77, nullptr, "SetProcessResourceLimits"},
1082 {0x78, nullptr, "CreateResourceLimit"}, 1122 {0x78, nullptr, "CreateResourceLimit"},
1083 {0x79, nullptr, "SetResourceLimitValues"}, 1123 {0x79, nullptr, "SetResourceLimitValues"},
1084 {0x7A, nullptr, "AddCodeSegment"}, 1124 {0x7A, nullptr, "AddCodeSegment"},
1085 {0x7B, nullptr, "Backdoor"}, 1125 {0x7B, nullptr, "Backdoor"},
1086 {0x7C, nullptr, "KernelSetState"}, 1126 {0x7C, nullptr, "KernelSetState"},
1087 {0x7D, HLE::Wrap<QueryProcessMemory>, "QueryProcessMemory"}, 1127 {0x7D, HLE::Wrap<QueryProcessMemory>, "QueryProcessMemory"},
1088}; 1128};
1089 1129
1090static const FunctionDef* GetSVCInfo(u32 func_num) { 1130static const FunctionDef* GetSVCInfo(u32 func_num) {