diff options
Diffstat (limited to 'src/core/hle')
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 |
| 25 | namespace std { | 23 | namespace std { |
| 26 | template <> | 24 | template <> |
| 27 | struct hash<Service::APT::AppletId> { | 25 | struct 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 | ||
| 38 | namespace HLE { | 36 | namespace HLE { |
| 39 | namespace Applets { | 37 | namespace Applets { |
| 40 | 38 | ||
| 41 | static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets; | 39 | static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets; |
| 42 | static u32 applet_update_event = -1; ///< The CoreTiming event identifier for the Applet update callback. | 40 | static 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 |
| 44 | static const u64 applet_update_interval_us = 16666; | 43 | static 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() { | |||
| 116 | void Shutdown() { | 117 | void 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 | ||
| 15 | class Applet { | 14 | class Applet { |
| 16 | public: | 15 | public: |
| 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 |
| 78 | void Shutdown(); | 77 | void 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 | |||
| 49 | ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parameter) { | 49 | ResultCode 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 | ||
| 68 | void ErrEula::Update() { | 69 | void 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 | ||
| 13 | class ErrEula final : public Applet { | 13 | class ErrEula final : public Applet { |
| 14 | public: | 14 | public: |
| 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 | |||
| 25 | private: | 29 | private: |
| 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 | |||
| 59 | ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& parameter) { | 57 | ResultCode 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 | ||
| 85 | void MiiSelector::Update() { | 85 | void 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 { | |||
| 17 | namespace Applets { | 16 | namespace Applets { |
| 18 | 17 | ||
| 19 | struct MiiConfig { | 18 | struct 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 | ||
| 40 | static_assert(sizeof(MiiConfig) == 0x104, "MiiConfig structure has incorrect size"); | 39 | static_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") | ||
| 42 | ASSERT_REG_POSITION(unk_008, 0x08); | 43 | ASSERT_REG_POSITION(unk_008, 0x08); |
| 43 | ASSERT_REG_POSITION(unk_08C, 0x8C); | 44 | ASSERT_REG_POSITION(unk_08C, 0x8C); |
| 44 | ASSERT_REG_POSITION(unk_090, 0x90); | 45 | ASSERT_REG_POSITION(unk_090, 0x90); |
| @@ -55,22 +56,27 @@ struct MiiResult { | |||
| 55 | INSERT_PADDING_BYTES(2); | 56 | INSERT_PADDING_BYTES(2); |
| 56 | }; | 57 | }; |
| 57 | static_assert(sizeof(MiiResult) == 0x84, "MiiResult structure has incorrect size"); | 58 | static_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") | ||
| 59 | ASSERT_REG_POSITION(unk_0C, 0x0C); | 62 | ASSERT_REG_POSITION(unk_0C, 0x0C); |
| 60 | ASSERT_REG_POSITION(unk_6C, 0x6C); | 63 | ASSERT_REG_POSITION(unk_6C, 0x6C); |
| 61 | #undef ASSERT_REG_POSITION | 64 | #undef ASSERT_REG_POSITION |
| 62 | 65 | ||
| 63 | class MiiSelector final : public Applet { | 66 | class MiiSelector final : public Applet { |
| 64 | public: | 67 | public: |
| 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 | ||
| 62 | ResultCode SoftwareKeyboard::StartImpl(Service::APT::AppletStartupParameter const& parameter) { | 60 | ResultCode 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 | ||
| 54 | class SoftwareKeyboard final : public Applet { | 53 | class SoftwareKeyboard final : public Applet { |
| 55 | public: | 54 | public: |
| 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 @@ | |||
| 20 | namespace ConfigMem { | 19 | namespace ConfigMem { |
| 21 | 20 | ||
| 22 | struct ConfigMemDef { | 21 | struct 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 | }; |
| 50 | static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong"); | 49 | static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, |
| 50 | "Config Memory structure size is wrong"); | ||
| 51 | 51 | ||
| 52 | extern ConfigMemDef config_mem; | 52 | extern 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 | ||
| 15 | namespace HLE { | 15 | namespace 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 |
| 20 | static const ResultCode RESULT_INVALID(0xDEADC0DE); | 20 | static 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 | ||
| 43 | template<ResultCode func(u32, u32, u32, u32)> void Wrap() { | 43 | template <ResultCode func(u32, u32, u32, u32)> |
| 44 | void 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 | ||
| 47 | template<ResultCode func(u32*, u32, u32, u32, u32, u32)> void Wrap(){ | 48 | template <ResultCode func(u32*, u32, u32, u32, u32, u32)> |
| 49 | void Wrap() { | ||
| 48 | u32 param_1 = 0; | 50 | u32 param_1 = 0; |
| 49 | u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; | 51 | u32 retval = func(¶m_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 | ||
| 54 | template<ResultCode func(u32*, s32, u32, u32, u32, s32)> void Wrap() { | 56 | template <ResultCode func(u32*, s32, u32, u32, u32, s32)> |
| 57 | void Wrap() { | ||
| 55 | u32 param_1 = 0; | 58 | u32 param_1 = 0; |
| 56 | u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; | 59 | u32 retval = func(¶m_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 | ||
| 61 | template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() { | 64 | template <ResultCode func(s32*, u32*, s32, bool, s64)> |
| 65 | void Wrap() { | ||
| 62 | s32 param_1 = 0; | 66 | s32 param_1 = 0; |
| 63 | s32 retval = func(¶m_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), | 67 | s32 retval = func(¶m_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 | ||
| 72 | template<ResultCode func(u32, u32, u32, u32, s64)> void Wrap() { | 77 | template <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); | 78 | void Wrap() { |
| 79 | FuncReturn( | ||
| 80 | func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))).raw); | ||
| 74 | } | 81 | } |
| 75 | 82 | ||
| 76 | template<ResultCode func(u32*)> void Wrap(){ | 83 | template <ResultCode func(u32*)> |
| 84 | void Wrap() { | ||
| 77 | u32 param_1 = 0; | 85 | u32 param_1 = 0; |
| 78 | u32 retval = func(¶m_1).raw; | 86 | u32 retval = func(¶m_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 | ||
| 83 | template<ResultCode func(u32, s64)> void Wrap() { | 91 | template <ResultCode func(u32, s64)> |
| 92 | void 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 | ||
| 91 | template<ResultCode func(MemoryInfo*, PageInfo*, u32)> void Wrap() { | 100 | template <ResultCode func(MemoryInfo*, PageInfo*, u32)> |
| 101 | void 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 | ||
| 103 | template<ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> void Wrap() { | 113 | template <ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> |
| 114 | void 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 | ||
| 115 | template<ResultCode func(s32*, u32)> void Wrap(){ | 126 | template <ResultCode func(s32*, u32)> |
| 127 | void Wrap() { | ||
| 116 | s32 param_1 = 0; | 128 | s32 param_1 = 0; |
| 117 | u32 retval = func(¶m_1, PARAM(1)).raw; | 129 | u32 retval = func(¶m_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 | ||
| 122 | template<ResultCode func(u32, s32)> void Wrap() { | 134 | template <ResultCode func(u32, s32)> |
| 135 | void Wrap() { | ||
| 123 | FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw); | 136 | FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw); |
| 124 | } | 137 | } |
| 125 | 138 | ||
| 126 | template<ResultCode func(u32*, u32)> void Wrap(){ | 139 | template <ResultCode func(u32*, u32)> |
| 140 | void Wrap() { | ||
| 127 | u32 param_1 = 0; | 141 | u32 param_1 = 0; |
| 128 | u32 retval = func(¶m_1, PARAM(1)).raw; | 142 | u32 retval = func(¶m_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 | ||
| 133 | template<ResultCode func(u32)> void Wrap() { | 147 | template <ResultCode func(u32)> |
| 148 | void Wrap() { | ||
| 134 | FuncReturn(func(PARAM(0)).raw); | 149 | FuncReturn(func(PARAM(0)).raw); |
| 135 | } | 150 | } |
| 136 | 151 | ||
| 137 | template<ResultCode func(s64*, u32, u32*, u32)> void Wrap(){ | 152 | template <ResultCode func(s64*, u32, u32*, u32)> |
| 138 | FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), | 153 | void 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 | ||
| 142 | template<ResultCode func(u32*, const char*)> void Wrap() { | 159 | template <ResultCode func(u32*, const char*)> |
| 160 | void Wrap() { | ||
| 143 | u32 param_1 = 0; | 161 | u32 param_1 = 0; |
| 144 | u32 retval = func(¶m_1, (char*)Memory::GetPointer(PARAM(1))).raw; | 162 | u32 retval = func(¶m_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 | ||
| 149 | template<ResultCode func(u32*, s32, s32)> void Wrap() { | 167 | template <ResultCode func(u32*, s32, s32)> |
| 168 | void Wrap() { | ||
| 150 | u32 param_1 = 0; | 169 | u32 param_1 = 0; |
| 151 | u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; | 170 | u32 retval = func(¶m_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 | ||
| 156 | template<ResultCode func(s32*, u32, s32)> void Wrap() { | 175 | template <ResultCode func(s32*, u32, s32)> |
| 176 | void Wrap() { | ||
| 157 | s32 param_1 = 0; | 177 | s32 param_1 = 0; |
| 158 | u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; | 178 | u32 retval = func(¶m_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 | ||
| 163 | template<ResultCode func(s64*, u32, s32)> void Wrap() { | 183 | template <ResultCode func(s64*, u32, s32)> |
| 184 | void Wrap() { | ||
| 164 | s64 param_1 = 0; | 185 | s64 param_1 = 0; |
| 165 | u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; | 186 | u32 retval = func(¶m_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 | ||
| 171 | template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() { | 192 | template <ResultCode func(u32*, u32, u32, u32, u32)> |
| 193 | void 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(¶m_1, PARAM(1), PARAM(2), PARAM(3), PARAM(0)).raw; | 196 | u32 retval = func(¶m_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 | ||
| 179 | template<ResultCode func(u32, s64, s64)> void Wrap() { | 201 | template <ResultCode func(u32, s64, s64)> |
| 202 | void 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 | ||
| 185 | template<ResultCode func(s64*, Handle, u32)> void Wrap() { | 208 | template <ResultCode func(s64*, Handle, u32)> |
| 209 | void Wrap() { | ||
| 186 | s64 param_1 = 0; | 210 | s64 param_1 = 0; |
| 187 | u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; | 211 | u32 retval = func(¶m_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 | ||
| 193 | template<ResultCode func(Handle, u32)> void Wrap() { | 217 | template <ResultCode func(Handle, u32)> |
| 218 | void Wrap() { | ||
| 194 | FuncReturn(func(PARAM(0), PARAM(1)).raw); | 219 | FuncReturn(func(PARAM(0), PARAM(1)).raw); |
| 195 | } | 220 | } |
| 196 | 221 | ||
| 197 | template<ResultCode func(Handle*, Handle*, const char*, u32)> void Wrap() { | 222 | template <ResultCode func(Handle*, Handle*, const char*, u32)> |
| 223 | void 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(¶m_1, ¶m_2, reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3)).raw; | 226 | u32 retval = func(¶m_1, ¶m_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 | ||
| 210 | template<u32 func()> void Wrap() { | 238 | template <u32 func()> |
| 239 | void 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 | ||
| 217 | template<s64 func()> void Wrap() { | 246 | template <s64 func()> |
| 247 | void 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 | ||
| 224 | template<void func(s64)> void Wrap() { | 254 | template <void func(s64)> |
| 255 | void Wrap() { | ||
| 225 | func(((s64)PARAM(1) << 32) | PARAM(0)); | 256 | func(((s64)PARAM(1) << 32) | PARAM(0)); |
| 226 | } | 257 | } |
| 227 | 258 | ||
| 228 | template<void func(const char*)> void Wrap() { | 259 | template <void func(const char*)> |
| 260 | void Wrap() { | ||
| 229 | func((char*)Memory::GetPointer(PARAM(0))); | 261 | func((char*)Memory::GetPointer(PARAM(0))); |
| 230 | } | 262 | } |
| 231 | 263 | ||
| 232 | template<void func(u8)> void Wrap() { | 264 | template <void func(u8)> |
| 265 | void 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 @@ | |||
| 15 | namespace { | 14 | namespace { |
| 16 | 15 | ||
| 17 | bool reschedule; ///< If true, immediately reschedules the CPU to a new thread | 16 | bool reschedule; ///< If true, immediately reschedules the CPU to a new thread |
| 18 | |||
| 19 | } | 17 | } |
| 20 | 18 | ||
| 21 | namespace HLE { | 19 | namespace HLE { |
| 22 | 20 | ||
| 23 | void Reschedule(const char *reason) { | 21 | void 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 | ||
| 14 | namespace HLE { | 14 | namespace HLE { |
| 15 | 15 | ||
| 16 | void Reschedule(const char *reason); | 16 | void Reschedule(const char* reason); |
| 17 | bool IsReschedulePending(); | 17 | bool IsReschedulePending(); |
| 18 | void DoneRescheduling(); | 18 | void 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 | ||
| 30 | ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, | 28 | ResultCode 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 | ||
| 13 | namespace Kernel { | 11 | namespace Kernel { |
| @@ -17,16 +15,22 @@ class ServerPort; | |||
| 17 | class ClientPort : public Object { | 15 | class ClientPort : public Object { |
| 18 | public: | 16 | public: |
| 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 | ||
| 31 | protected: | 35 | protected: |
| 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 | ||
| 15 | namespace Kernel { | 13 | namespace 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 | ||
| 11 | namespace Kernel { | 10 | namespace Kernel { |
| @@ -16,7 +15,6 @@ enum class ResetType { | |||
| 16 | Pulse, | 15 | Pulse, |
| 17 | }; | 16 | }; |
| 18 | 17 | ||
| 19 | |||
| 20 | class Event final : public WaitObject { | 18 | class Event final : public WaitObject { |
| 21 | public: | 19 | public: |
| 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 |
| 25 | const ResultCode ERR_OUT_OF_HANDLES(ErrorDescription::OutOfMemory, ErrorModule::Kernel, | 22 | const 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 |
| 28 | const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel, | 25 | const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel, |
| 29 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 26 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| 30 | 27 | ||
| 31 | enum KernelHandle : Handle { | 28 | enum KernelHandle : Handle { |
| 32 | CurrentThread = 0xFFFF8000, | 29 | CurrentThread = 0xFFFF8000, |
| 33 | CurrentProcess = 0xFFFF8001, | 30 | CurrentProcess = 0xFFFF8001, |
| 34 | }; | 31 | }; |
| 35 | 32 | ||
| 36 | enum class HandleType : u32 { | 33 | enum 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 | ||
| 55 | enum { | 52 | enum { |
| 56 | DEFAULT_STACK_SIZE = 0x4000, | 53 | DEFAULT_STACK_SIZE = 0x4000, |
| 57 | }; | 54 | }; |
| 58 | 55 | ||
| 59 | class Object : NonCopyable { | 56 | class 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 |
| 123 | class WaitObject : public Object { | 126 | class WaitObject : public Object { |
| 124 | public: | 127 | public: |
| 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]; | |||
| 31 | static const u32 memory_region_sizes[8][3] = { | 28 | static 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 | ||
| 101 | namespace Memory { | 97 | namespace 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. |
| 112 | static MemoryArea memory_areas[] = { | 108 | static 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 | ||
| 118 | void Init() { | 113 | void 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 | ||
| 13 | namespace Kernel { | 11 | namespace Kernel { |
| @@ -25,7 +23,6 @@ struct MemoryRegionInfo { | |||
| 25 | void MemoryInit(u32 mem_type); | 23 | void MemoryInit(u32 mem_type); |
| 26 | void MemoryShutdown(); | 24 | void MemoryShutdown(); |
| 27 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); | 25 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); |
| 28 | |||
| 29 | } | 26 | } |
| 30 | 27 | ||
| 31 | namespace Memory { | 28 | namespace 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 | ||
| 13 | namespace Kernel { | 11 | namespace 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) { | |||
| 107 | void Process::Run(s32 main_thread_priority, u32 stack_size) { | 106 | void 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 | ||
| 145 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission perms) { | 149 | ResultVal<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 | ||
| 178 | ResultCode Process::HeapFree(VAddr target, u32 size) { | 184 | ResultCode 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() {} | |||
| 272 | Kernel::Process::~Process() {} | 282 | Kernel::Process::~Process() {} |
| 273 | 283 | ||
| 274 | SharedPtr<Process> g_current_process; | 284 | SharedPtr<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 { | |||
| 36 | union ProcessFlags { | 33 | union 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; | |||
| 54 | struct CodeSet final : public Object { | 54 | struct 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 { | |||
| 85 | public: | 91 | public: |
| 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 | ||
| 166 | extern SharedPtr<Process> g_current_process; | 178 | extern 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 | ||
| 11 | namespace Kernel { | 9 | namespace Kernel { |
| @@ -23,70 +21,69 @@ SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) { | |||
| 23 | } | 21 | } |
| 24 | 22 | ||
| 25 | SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { | 23 | SharedPtr<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 | ||
| 39 | s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { | 36 | s32 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 | ||
| 66 | s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { | 63 | s32 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 | ||
| 152 | void ResourceLimitsShutdown() { | 149 | void 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 | ||
| 11 | namespace Kernel { | 10 | namespace Kernel { |
| 12 | 11 | ||
| 13 | enum class ResourceLimitCategory : u8 { | 12 | enum 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 | ||
| 20 | enum ResourceTypes { | 19 | enum 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 | ||
| 33 | class ResourceLimit final : public Object { | 32 | class 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() {} | |||
| 14 | Semaphore::~Semaphore() {} | 13 | Semaphore::~Semaphore() {} |
| 15 | 14 | ||
| 16 | ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, | 15 | ResultVal<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 | ||
| 14 | namespace Kernel { | 12 | namespace 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 | ||
| 28 | std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(u32 max_sessions, std::string name) { | 26 | std::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 | ||
| 14 | namespace Kernel { | 12 | namespace 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 | ||
| 10 | Session::Session() {} | 10 | Session::Session() {} |
| 11 | Session::~Session() {} | 11 | Session::~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 { | |||
| 19 | enum DescriptorType : u32 { | 17 | enum 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 | */ |
| 42 | constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, unsigned int translate_params_size) { | 43 | constexpr 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 | ||
| 46 | union Header { | 49 | union 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 | ||
| 53 | inline Header ParseHeader(u32 header) { | 56 | inline Header ParseHeader(u32 header) { |
| 54 | return{ header }; | 57 | return {header}; |
| 55 | } | 58 | } |
| 56 | 59 | ||
| 57 | constexpr u32 MoveHandleDesc(u32 num_handles = 1) { | 60 | constexpr u32 MoveHandleDesc(u32 num_handles = 1) { |
| @@ -80,27 +83,29 @@ constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { | |||
| 80 | 83 | ||
| 81 | union StaticBufferDescInfo { | 84 | union 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 | ||
| 87 | inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { | 90 | inline 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 | */ |
| 100 | inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { | 104 | inline 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 | ||
| 106 | enum MappedBufferPermissions { | 111 | enum MappedBufferPermissions { |
| @@ -115,12 +120,12 @@ constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { | |||
| 115 | 120 | ||
| 116 | union MappedBufferDescInfo { | 121 | union 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 | ||
| 122 | inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { | 127 | inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { |
| 123 | return{ desc }; | 128 | return {desc}; |
| 124 | } | 129 | } |
| 125 | 130 | ||
| 126 | inline DescriptorType GetDescriptorType(u32 descriptor) { | 131 | inline 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 | */ |
| 155 | inline u32* GetCommandBuffer(const int offset = 0) { | 160 | inline 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 | ||
| 13 | namespace Kernel { | 11 | namespace Kernel { |
| 14 | 12 | ||
| 15 | SharedMemory::SharedMemory() {} | 13 | SharedMemory::SharedMemory() {} |
| 16 | SharedMemory::~SharedMemory() {} | 14 | SharedMemory::~SharedMemory() {} |
| 17 | 15 | ||
| 18 | SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, MemoryPermission permissions, | 16 | SharedPtr<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 | ||
| 74 | SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, | 78 | SharedPtr<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 | ||
| 90 | ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermission permissions, | 97 | ResultCode 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 | ||
| 157 | ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) { | 174 | ResultCode 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 | ||
| 162 | VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { | 180 | VMAPermission 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 |
| 18 | enum class MemoryPermission : u32 { | 16 | enum 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 | ||
| 30 | class SharedMemory final : public Object { | 28 | class 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; | |||
| 46 | static std::vector<SharedPtr<Thread>> thread_list; | 44 | static std::vector<SharedPtr<Thread>> thread_list; |
| 47 | 45 | ||
| 48 | // Lists only ready thread ids. | 46 | // Lists only ready thread ids. |
| 49 | static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> ready_queue; | 47 | static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST + 1> ready_queue; |
| 50 | 48 | ||
| 51 | static Thread* current_thread; | 49 | static 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 | ||
| 324 | void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, bool wait_set_output, bool wait_all) { | 326 | void 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 | ||
| 373 | void Thread::ResumeFromWait() { | 377 | void 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 | */ |
| 451 | static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point, u32 arg) { | 456 | static 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 | ||
| 460 | ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority, | 466 | ResultVal<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. | ||
| 555 | static void ClampPriority(const Thread* thread, s32* priority) { | 565 | static 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 | ||
| 20 | enum ThreadPriority : s32{ | 16 | enum 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 | ||
| 27 | enum ThreadProcessorId : s32 { | 23 | enum 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 | ||
| 35 | enum ThreadStatus { | 31 | enum 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 | ||
| 45 | namespace Kernel { | 41 | namespace 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 | */ |
| 211 | void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, bool wait_set_output, bool wait_all); | 220 | void 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 | ||
| 15 | namespace Kernel { | 13 | namespace Kernel { |
| 16 | 14 | ||
| @@ -41,7 +39,7 @@ bool Timer::ShouldWait() { | |||
| 41 | } | 39 | } |
| 42 | 40 | ||
| 43 | void Timer::Acquire() { | 41 | void 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 |
| 75 | static void TimerCallback(u64 timer_handle, int cycles_late) { | 73 | static 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 | ||
| 103 | void TimersShutdown() { | 102 | void 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 | ||
| 16 | static const char* GetMemoryStateName(MemoryState state) { | 14 | static 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 | ||
| 25 | bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { | 23 | bool 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 | ||
| 72 | ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, | 69 | ResultVal<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 | ||
| 92 | ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * memory, u32 size, MemoryState state) { | 91 | ResultVal<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 | ||
| 109 | ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler) { | 109 | ResultVal<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) { | |||
| 191 | void VMManager::LogLayout(Log::Level log_level) const { | 193 | void 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 | ||
| 202 | VMManager::VMAIter VMManager::StripIterConstness(const VMAHandle & iter) { | 205 | VMManager::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 | ||
| 16 | namespace Kernel { | 14 | namespace Kernel { |
| 17 | 15 | ||
| 18 | const ResultCode ERR_INVALID_ADDRESS{ // 0xE0E01BF5 | 16 | const 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 | ||
| 22 | const ResultCode ERR_INVALID_ADDRESS_STATE{ // 0xE0A01BF5 | 20 | const 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 | ||
| 26 | enum class VMAType : u8 { | 24 | enum 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 |
| 116 | public: | 114 | public: |
| 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. |
| 248 | inline ResultCode UnimplementedFunction(ErrorModule module) { | 253 | inline 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) { | |||
| 285 | template <typename T> | 290 | template <typename T> |
| 286 | class ResultVal { | 291 | class ResultVal { |
| 287 | public: | 292 | public: |
| 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: | |||
| 390 | private: | 406 | private: |
| 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 | ||
| 70 | const Interface::FunctionInfo FunctionTable[] = { | 69 | const 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 | ||
| 16 | namespace Service { | 14 | namespace Service { |
| 17 | namespace AM { | 15 | namespace AM { |
| 18 | 16 | ||
| 19 | static std::array<u32, 3> am_content_count = { 0, 0, 0 }; | 17 | static std::array<u32, 3> am_content_count = {0, 0, 0}; |
| 20 | static std::array<u32, 3> am_titles_count = { 0, 0, 0 }; | 18 | static std::array<u32, 3> am_titles_count = {0, 0, 0}; |
| 21 | static std::array<u32, 3> am_titles_list_count = { 0, 0, 0 }; | 19 | static std::array<u32, 3> am_titles_list_count = {0, 0, 0}; |
| 22 | static u32 am_ticket_count = 0; | 20 | static u32 am_ticket_count = 0; |
| 23 | static u32 am_ticket_list_count = 0; | 21 | static 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 | ||
| 35 | void FindContentInfos(Service::Interface* self) { | 34 | void 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 | ||
| 50 | void ListContentInfos(Service::Interface* self) { | 51 | void 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 | ||
| 66 | void DeleteContents(Service::Interface* self) { | 69 | void 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 | ||
| 80 | void GetTitleList(Service::Interface* self) { | 84 | void 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 | ||
| 94 | void GetTitleInfo(Service::Interface* self) { | 100 | void 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 | ||
| 129 | void GetNumContentInfos(Service::Interface* self) { | 137 | void 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 | ||
| 146 | void GetTicketCount(Service::Interface* self) { | 154 | void 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 | ||
| 154 | void GetTicketList(Service::Interface* self) { | 162 | void 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 | ||
| 168 | void Init() { | 178 | void Init() { |
| @@ -174,9 +184,7 @@ void Init() { | |||
| 174 | AddService(new AM_U_Interface); | 184 | AddService(new AM_U_Interface); |
| 175 | } | 185 | } |
| 176 | 186 | ||
| 177 | void Shutdown() { | 187 | void 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 { | |||
| 9 | namespace AM { | 9 | namespace AM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 22 | AM_APP_Interface::AM_APP_Interface() { | 22 | AM_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 { | |||
| 9 | namespace AM { | 9 | namespace AM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 69 | AM_NET_Interface::AM_NET_Interface() { | 69 | AM_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 { | |||
| 9 | namespace AM { | 9 | namespace AM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 35 | AM_SYS_Interface::AM_SYS_Interface() { | 35 | AM_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 { | |||
| 9 | namespace AM { | 9 | namespace AM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 48 | AM_U_Interface::AM_U_Interface() { | 48 | AM_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 | ||
| 24 | namespace Service { | 22 | namespace Service { |
| 25 | namespace APT { | 23 | namespace APT { |
| @@ -30,7 +28,7 @@ static bool shared_font_relocated = false; | |||
| 30 | 28 | ||
| 31 | static Kernel::SharedPtr<Kernel::Mutex> lock; | 29 | static Kernel::SharedPtr<Kernel::Mutex> lock; |
| 32 | static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event | 30 | static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event |
| 33 | static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event | 31 | static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event |
| 34 | 32 | ||
| 35 | static u32 cpu_percent; ///< CPU time available to the running application | 33 | static u32 cpu_percent; ///< CPU time available to the running application |
| 36 | 34 | ||
| @@ -51,7 +49,7 @@ void SendParameter(const MessageParameter& parameter) { | |||
| 51 | void Initialize(Service::Interface* self) { | 49 | void 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 | ||
| 122 | void Enable(Service::Interface* self) { | 123 | void 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) { | |||
| 159 | void InquireNotification(Service::Interface* self) { | 160 | void 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 | ||
| 167 | void SendParameter(Service::Interface* self) { | 168 | void 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 | ||
| 201 | void ReceiveParameter(Service::Interface* self) { | 205 | void 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 | ||
| 245 | void CancelParameter(Service::Interface* self) { | 250 | void 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 | ||
| 259 | void PrepareToStartApplication(Service::Interface* self) { | 265 | void 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 | ||
| 277 | void StartApplication(Service::Interface* self) { | 285 | void 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 | ||
| 294 | void AppletUtility(Service::Interface* self) { | 303 | void 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 | ||
| 311 | void SetAppCpuTimeLimit(Service::Interface* self) { | 321 | void 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 | ||
| 399 | void GetScreenCapPostPermission(Service::Interface* self) { | 410 | void 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 | ||
| 408 | void GetAppletInfo(Service::Interface* self) { | 420 | void 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 | ||
| 12 | namespace Service { | 11 | namespace 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 |
| 48 | enum class SignalType : u32 { | 47 | enum 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 |
| 59 | enum class AppletId : u32 { | 58 | enum 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 | ||
| 91 | enum class StartupArgumentType : u32 { | 90 | enum 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 | ||
| 97 | enum class ScreencapPostPermission : u32 { | 96 | enum 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); | |||
| 182 | void GetAppletInfo(Service::Interface* self); | 181 | void 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 { | |||
| 9 | namespace APT { | 9 | namespace APT { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 42 | APT_A_Interface::APT_A_Interface() { | 42 | APT_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 { | |||
| 9 | namespace APT { | 9 | namespace APT { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 102 | APT_S_Interface::APT_S_Interface() { | 102 | APT_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 { | |||
| 9 | namespace APT { | 9 | namespace APT { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 102 | APT_U_Interface::APT_U_Interface() { | 102 | APT_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 | ||
| 10 | namespace Service { | 10 | namespace Service { |
| 11 | namespace BOSS { | 11 | namespace BOSS { |
| @@ -17,8 +17,7 @@ void Init() { | |||
| 17 | AddService(new BOSS_U_Interface); | 17 | AddService(new BOSS_U_Interface); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void Shutdown() { | 20 | void 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 | ||
| 13 | BOSS_P_Interface::BOSS_P_Interface() { | 13 | BOSS_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 { | |||
| 8 | namespace BOSS { | 8 | namespace BOSS { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const 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 | ||
| 17 | BOSS_U_Interface::BOSS_U_Interface() { | 17 | BOSS_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 | ||
| 73 | void SetReceiving(Service::Interface* self) { | 72 | void 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 | ||
| 95 | void SetTransferLines(Service::Interface* self) { | 94 | void 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 | ||
| 110 | void GetMaxLines(Service::Interface* self) { | 109 | void 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 | ||
| 124 | void GetTransferBytes(Service::Interface* self) { | 123 | void GetTransferBytes(Service::Interface* self) { |
| @@ -136,7 +135,7 @@ void GetTransferBytes(Service::Interface* self) { | |||
| 136 | void SetTrimming(Service::Interface* self) { | 135 | void 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) { | |||
| 148 | void SetTrimmingParamsCenter(Service::Interface* self) { | 147 | void 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 | ||
| 164 | void Activate(Service::Interface* self) { | 163 | void 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 | ||
| 176 | void FlipImage(Service::Interface* self) { | 174 | void 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 | ||
| 190 | void SetSize(Service::Interface* self) { | 188 | void 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 | ||
| 204 | void SetFrameRate(Service::Interface* self) { | 202 | void 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 | ||
| 217 | void GetStereoCameraCalibrationData(Service::Interface* self) { | 215 | void 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 | ||
| 302 | void Shutdown() { | 304 | void 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 | ||
| 14 | namespace Service { | 13 | namespace Service { |
| 15 | namespace CAM { | 14 | namespace CAM { |
| 16 | 15 | ||
| 17 | enum class Port : u8 { | 16 | enum 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 | ||
| 24 | enum class CameraSelect : u8 { | 18 | enum 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 | ||
| 35 | enum class Effect : u8 { | 29 | enum 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 | ||
| 44 | enum class Context : u8 { | 38 | enum 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 | ||
| 51 | enum class Flip : u8 { | 45 | enum 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 | ||
| 58 | enum class Size : u8 { | 52 | enum 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 | ||
| 70 | enum class FrameRate : u8 { | 64 | enum 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 | ||
| 86 | enum class ShutterSoundType : u8 { | 80 | enum 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 | ||
| 92 | enum class WhiteBalance : u8 { | 86 | enum 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 | ||
| 109 | enum class PhotoMode : u8 { | 103 | enum 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 | ||
| 117 | enum class LensCorrection : u8 { | 111 | enum 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 | ||
| 126 | enum class Contrast : u8 { | 120 | enum 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 | ||
| 143 | enum class OutputFormat : u8 { | 137 | enum 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. |
| 149 | struct StereoCameraCalibrationData { | 143 | struct 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 | }; |
| 166 | static_assert(sizeof(StereoCameraCalibrationData) == 64, "StereoCameraCalibrationData structure size is wrong"); | 160 | static_assert(sizeof(StereoCameraCalibrationData) == 64, |
| 161 | "StereoCameraCalibrationData structure size is wrong"); | ||
| 167 | 162 | ||
| 168 | struct PackageParameterCameraSelect { | 163 | struct 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 | ||
| 191 | static_assert(sizeof(PackageParameterCameraSelect) == 28, "PackageParameterCameraSelect structure size is wrong"); | 186 | static_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 { | |||
| 8 | namespace CAM { | 8 | namespace 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 | ||
| 13 | CAM_C_Interface::CAM_C_Interface() { | 13 | CAM_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 { | |||
| 8 | namespace CAM { | 8 | namespace 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 | ||
| 13 | CAM_Q_Interface::CAM_Q_Interface() { | 13 | CAM_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 { | |||
| 8 | namespace CAM { | 8 | namespace 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 | ||
| 13 | CAM_S_Interface::CAM_S_Interface() { | 13 | CAM_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 { | |||
| 9 | namespace CAM { | 9 | namespace CAM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 76 | CAM_U_Interface::CAM_U_Interface() { | 76 | CAM_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 | ||
| 13 | namespace Service { | 12 | namespace Service { |
| 14 | namespace CECD { | 13 | namespace CECD { |
| @@ -28,7 +27,7 @@ void GetCecStateAbbreviated(Service::Interface* self) { | |||
| 28 | void GetCecInfoEventHandle(Service::Interface* self) { | 27 | void 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) { | |||
| 37 | void GetChangeStateEventHandle(Service::Interface* self) { | 36 | void 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 | ||
| 54 | void Shutdown() { | 54 | void 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; | |||
| 11 | namespace CECD { | 11 | namespace CECD { |
| 12 | 12 | ||
| 13 | enum class CecStateAbbreviated { | 13 | enum 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 { | |||
| 8 | namespace CECD { | 8 | namespace 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 | ||
| 13 | CECD_S_Interface::CECD_S_Interface() { | 13 | CECD_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 { | |||
| 9 | namespace CECD { | 9 | namespace CECD { |
| 10 | 10 | ||
| 11 | static const Interface::FunctionInfo FunctionTable[] = { | 11 | static 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 | ||
| 18 | CECD_U_Interface::CECD_U_Interface() { | 18 | CECD_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 | ||
| 23 | namespace Service { | 21 | namespace Service { |
| 24 | namespace CFG { | 22 | namespace 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 | */ |
| 35 | struct SaveFileConfig { | 33 | struct 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 | }; |
| 41 | static_assert(sizeof(SaveFileConfig) == 0x455C, "SaveFileConfig header must be exactly 0x455C bytes"); | 42 | static_assert(sizeof(SaveFileConfig) == 0x455C, |
| 43 | "SaveFileConfig header must be exactly 0x455C bytes"); | ||
| 42 | 44 | ||
| 43 | enum ConfigBlockID { | 45 | enum 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 | ||
| 57 | struct UsernameBlock { | 59 | struct UsernameBlock { |
| @@ -68,8 +70,8 @@ struct BirthdayBlock { | |||
| 68 | static_assert(sizeof(BirthdayBlock) == 2, "BirthdayBlock must be exactly 2 bytes"); | 70 | static_assert(sizeof(BirthdayBlock) == 2, "BirthdayBlock must be exactly 2 bytes"); |
| 69 | 71 | ||
| 70 | struct ConsoleModelInfo { | 72 | struct 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 | }; |
| 74 | static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes"); | 76 | static_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 | }; |
| 80 | static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); | 82 | static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); |
| 81 | |||
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | static const u64 CFG_SAVE_ID = 0x00010017; | 85 | static const u64 CFG_SAVE_ID = 0x00010017; |
| 85 | static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; | 86 | static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; |
| 86 | static const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; | 87 | static const ConsoleModelInfo CONSOLE_MODEL = {NINTENDO_3DS_XL, {0, 0, 0}}; |
| 87 | static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; | 88 | static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; |
| 88 | static const UsernameBlock CONSOLE_USERNAME_BLOCK = { u"CITRA", 0, 0 }; | 89 | static const UsernameBlock CONSOLE_USERNAME_BLOCK = {u"CITRA", 0, 0}; |
| 89 | static const BirthdayBlock PROFILE_BIRTHDAY = { 3, 25 }; // March 25th, 2014 | 90 | static const BirthdayBlock PROFILE_BIRTHDAY = {3, 25}; // March 25th, 2014 |
| 90 | static const u8 SOUND_OUTPUT_MODE = SOUND_SURROUND; | 91 | static const u8 SOUND_OUTPUT_MODE = SOUND_SURROUND; |
| 91 | static const u8 UNITED_STATES_COUNTRY_ID = 49; | 92 | static 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 |
| 93 | static const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID }; | 94 | static 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 | */ |
| 100 | static const std::array<float, 8> STEREO_CAMERA_SETTINGS = {{ | 101 | static 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 | }; |
| 104 | static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); | 105 | static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, |
| 106 | "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); | ||
| 105 | 107 | ||
| 106 | static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; | 108 | static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; |
| 107 | static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; | 109 | static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; |
| 108 | 110 | ||
| 109 | static Service::FS::ArchiveHandle cfg_system_save_data_archive; | 111 | static Service::FS::ArchiveHandle cfg_system_save_data_archive; |
| 110 | static const std::vector<u8> cfg_system_savedata_id = { 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00 }; | 112 | static const std::vector<u8> cfg_system_savedata_id = { |
| 113 | 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, | ||
| 114 | }; | ||
| 111 | 115 | ||
| 112 | void GetCountryCodeString(Service::Interface* self) { | 116 | void 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() { | |||
| 452 | ResultCode LoadConfigNANDSaveFile() { | 486 | ResultCode 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 | ||
| 494 | void Shutdown() { | 531 | void Shutdown() {} |
| 495 | } | ||
| 496 | 532 | ||
| 497 | void SetUsername(const std::u16string& name) { | 533 | void 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 | ||
| 517 | void SetBirthday(u8 month, u8 day) { | 553 | void 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 | ||
| 12 | union ResultCode; | 11 | union ResultCode; |
| @@ -40,16 +39,13 @@ enum SystemLanguage { | |||
| 40 | LANGUAGE_TW = 11 | 39 | LANGUAGE_TW = 11 |
| 41 | }; | 40 | }; |
| 42 | 41 | ||
| 43 | enum SoundOutputMode { | 42 | enum 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 |
| 50 | struct SaveConfigBlockEntry { | 45 | struct 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); | |||
| 244 | ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input); | 241 | ResultCode 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 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 58 | CFG_I_Interface::CFG_I_Interface() { | 58 | CFG_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 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 35 | CFG_S_Interface::CFG_S_Interface() { | 35 | CFG_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 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 25 | CFG_U_Interface::CFG_U_Interface() { | 25 | CFG_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 @@ | |||
| 15 | namespace CSND_SND { | 15 | namespace CSND_SND { |
| 16 | 16 | ||
| 17 | const Interface::FunctionInfo FunctionTable[] = { | 17 | const 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 | ||
| 59 | void ExecuteType0Commands(Service::Interface* self) { | 59 | void 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 | ||
| 31 | void Initialize(Service::Interface* self); | 31 | void 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 | ||
| 11 | namespace Service { | 11 | namespace Service { |
| 12 | namespace DLP { | 12 | namespace DLP { |
| @@ -17,8 +17,7 @@ void Init() { | |||
| 17 | AddService(new DLP_SRVR_Interface); | 17 | AddService(new DLP_SRVR_Interface); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | void Shutdown() { | 20 | void 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 { | |||
| 8 | namespace DLP { | 8 | namespace DLP { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const Interface::FunctionInfo FunctionTable[] = { |
| 11 | {0x000100C3, nullptr, "Initialize"}, | 11 | {0x000100C3, nullptr, "Initialize"}, {0x00110000, nullptr, "GetWirelessRebootPassphrase"}, |
| 12 | {0x00110000, nullptr, "GetWirelessRebootPassphrase"}, | ||
| 13 | }; | 12 | }; |
| 14 | 13 | ||
| 15 | DLP_CLNT_Interface::DLP_CLNT_Interface() { | 14 | DLP_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 { | |||
| 8 | namespace DLP { | 8 | namespace DLP { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const Interface::FunctionInfo FunctionTable[] = { |
| 11 | {0x00010083, nullptr, "Initialize"}, | 11 | {0x00010083, nullptr, "Initialize"}, {0x000F0000, nullptr, "GetWirelessRebootPassphrase"}, |
| 12 | {0x000F0000, nullptr, "GetWirelessRebootPassphrase"}, | ||
| 13 | }; | 12 | }; |
| 14 | 13 | ||
| 15 | DLP_FKCL_Interface::DLP_FKCL_Interface() { | 14 | DLP_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 | ||
| 22 | const Interface::FunctionInfo FunctionTable[] = { | 22 | const 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 | ||
| 29 | DLP_SRVR_Interface::DLP_SRVR_Interface() { | 29 | DLP_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 { | |||
| 23 | static Kernel::SharedPtr<Kernel::Event> semaphore_event; | 20 | static Kernel::SharedPtr<Kernel::Event> semaphore_event; |
| 24 | 21 | ||
| 25 | /// There are three types of interrupts | 22 | /// There are three types of interrupts |
| 26 | enum class InterruptType { | 23 | enum class InterruptType { Zero, One, Pipe }; |
| 27 | Zero, One, Pipe | ||
| 28 | }; | ||
| 29 | constexpr size_t NUM_INTERRUPT_TYPE = 3; | 24 | constexpr size_t NUM_INTERRUPT_TYPE = 3; |
| 30 | 25 | ||
| 31 | class InterruptEvents final { | 26 | class 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) { | |||
| 126 | static void LoadComponent(Service::Interface* self) { | 121 | static 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) { | |||
| 187 | static void FlushDataCache(Service::Interface* self) { | 185 | static 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 | ||
| 514 | const Interface::FunctionInfo FunctionTable[] = { | 534 | const 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 | ||
| 11 | namespace DSP { | 10 | namespace 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 | ||
| 88 | enum { | 87 | enum { PrefetchAbort = 0, DataAbort = 1, UndefInstr = 2, VectorFP = 3 }; |
| 89 | PrefetchAbort = 0, | ||
| 90 | DataAbort = 1, | ||
| 91 | UndefInstr = 2, | ||
| 92 | VectorFP = 3 | ||
| 93 | }; | ||
| 94 | 88 | ||
| 95 | static std::string GetErrInfo3Type(u8 type_code) { | 89 | static 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 | ||
| 179 | const Interface::FunctionInfo FunctionTable[] = { | 175 | const 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 | ||
| 12 | namespace Service { | 11 | namespace Service { |
| 13 | namespace FRD { | 12 | namespace 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 | ||
| 68 | void GetFriendAttributeFlags(Service::Interface* self) { | 68 | void 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 | ||
| 85 | void GetMyFriendKey(Service::Interface* self) { | 86 | void 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 | ||
| 109 | void Shutdown() { | 110 | void 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 | ||
| 13 | FRD_A_Interface::FRD_A_Interface() { | 13 | FRD_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 { | |||
| 9 | namespace FRD { | 9 | namespace FRD { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 67 | FRD_U_Interface::FRD_U_Interface() { | 67 | FRD_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 |
| 36 | namespace std { | 33 | namespace std { |
| 37 | template <> | 34 | template <> |
| 38 | struct hash<Service::FS::ArchiveIdCode> { | 35 | struct 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. |
| 58 | const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::FS, | 55 | const 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. |
| 62 | const ResultCode ERR_INVALID_ARCHIVE_HANDLE(ErrorDescription::FS_ArchiveNotMounted, ErrorModule::FS, | 59 | const 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 |
| 66 | enum class FileCommand : u32 { | 64 | enum 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 |
| 84 | enum class DirectoryCommand : u32 { | 82 | enum 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 | ||
| 91 | File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path & path) | 89 | File::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 | ||
| 94 | File::~File() {} | 92 | File::~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 | ||
| 211 | Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path & path) | 201 | Directory::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 | ||
| 214 | Directory::~Directory() {} | 205 | Directory::~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 |
| 306 | ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code) { | 295 | ResultCode 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 | ||
| 317 | ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, | 308 | ResultVal<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 | ||
| 339 | ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, | 331 | ResultCode 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 | ||
| 371 | ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size) { | 365 | ResultCode 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 | ||
| 390 | ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, | 385 | ResultCode 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 | ||
| 411 | ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, | 408 | ResultVal<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 | ||
| 434 | ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path) { | 431 | ResultCode 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 | ||
| 443 | ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path) { | 441 | ResultVal<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 | ||
| 452 | ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) { | 451 | ResultCode 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 | ||
| 477 | ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { | 479 | ResultCode 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 |
| 30 | enum class ArchiveIdCode : u32 { | 28 | enum 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 |
| 42 | enum class MediaType : u32 { | 40 | enum class MediaType : u32 { NAND = 0, SDMC = 1 }; |
| 43 | NAND = 0, | ||
| 44 | SDMC = 1 | ||
| 45 | }; | ||
| 46 | 41 | ||
| 47 | typedef u64 ArchiveHandle; | 42 | typedef 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 | */ |
| 93 | ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code); | 92 | ResultCode 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 | */ |
| 102 | ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, | 102 | ResultVal<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 | */ |
| 121 | ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, | 122 | ResultCode 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 | */ |
| 139 | ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size); | 142 | ResultCode 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 | */ |
| 157 | ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, | 161 | ResultCode 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 | */ |
| 166 | ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, | 172 | ResultVal<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 | */ |
| 184 | ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path = FileSys::Path()); | 190 | ResultCode 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 | */ |
| 193 | ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path); | 200 | ResultVal<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 | */ |
| 205 | ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info); | 213 | ResultCode 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) { | |||
| 98 | static void OpenFileDirectly(Service::Interface* self) { | 99 | static 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) { | |||
| 370 | static void OpenArchive(Service::Interface* self) { | 384 | static 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 | ||
| 836 | const Interface::FunctionInfo FunctionTable[] = { | 862 | const 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 |
| 22 | GraphicsDebugger g_debugger; | 19 | GraphicsDebugger g_debugger; |
| @@ -29,12 +26,15 @@ const static u32 REGS_BEGIN = 0x1EB00000; | |||
| 29 | 26 | ||
| 30 | namespace GSP_GPU { | 27 | namespace GSP_GPU { |
| 31 | 28 | ||
| 32 | const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED(ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, | 29 | const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED( |
| 33 | ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02A01 | 30 | ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, ErrorSummary::InvalidArgument, |
| 31 | ErrorLevel::Usage); // 0xE0E02A01 | ||
| 34 | const ResultCode ERR_GSP_REGS_MISALIGNED(ErrorDescription::MisalignedSize, ErrorModule::GX, | 32 | const ResultCode ERR_GSP_REGS_MISALIGNED(ErrorDescription::MisalignedSize, ErrorModule::GX, |
| 35 | ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02BF2 | 33 | ErrorSummary::InvalidArgument, |
| 34 | ErrorLevel::Usage); // 0xE0E02BF2 | ||
| 36 | const ResultCode ERR_GSP_REGS_INVALID_SIZE(ErrorDescription::InvalidSize, ErrorModule::GX, | 35 | const 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 |
| 40 | Kernel::SharedPtr<Kernel::Event> g_interrupt_event; | 40 | Kernel::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 | */ |
| 75 | static void WriteSingleHWReg(u32 base_address, u32 data) { | 75 | static 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 | */ |
| 127 | static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr data_vaddr, VAddr masks_vaddr) { | 129 | static 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) { | |||
| 305 | static void FlushDataCache(Service::Interface* self) { | 322 | static 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 | ||
| 681 | const Interface::FunctionInfo FunctionTable[] = { | 708 | const 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 |
| 22 | enum class InterruptId : u8 { | 20 | enum 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 |
| 33 | enum class CommandId : u32 { | 31 | enum 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 | }; |
| 66 | static_assert(sizeof(InterruptRelayQueue) == 0x40, | 64 | static_assert(sizeof(InterruptRelayQueue) == 0x40, "InterruptRelayQueue struct has incorrect size"); |
| 67 | "InterruptRelayQueue struct has incorrect size"); | ||
| 68 | 65 | ||
| 69 | struct FrameBufferInfo { | 66 | struct 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 | }; |
| 79 | static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size"); | 76 | static_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 |
| 94 | static_assert(offsetof(FrameBufferUpdate, framebuffer_info[1]) == 0x20, "FrameBufferInfo element has incorrect alignment"); | 91 | static_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 @@ | |||
| 10 | namespace GSP_LCD { | 10 | namespace GSP_LCD { |
| 11 | 11 | ||
| 12 | const Interface::FunctionInfo FunctionTable[] = { | 12 | const 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 | ||
| 21 | namespace Service { | 17 | namespace Service { |
| @@ -37,11 +33,13 @@ static u32 next_accelerometer_index; | |||
| 37 | static u32 next_gyroscope_index; | 33 | static u32 next_gyroscope_index; |
| 38 | 34 | ||
| 39 | static int enable_accelerometer_count = 0; // positive means enabled | 35 | static int enable_accelerometer_count = 0; // positive means enabled |
| 40 | static int enable_gyroscope_count = 0; // positive means enabled | 36 | static int enable_gyroscope_count = 0; // positive means enabled |
| 41 | 37 | ||
| 42 | static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { | 38 | static 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() { | |||
| 188 | void GetIPCHandles(Service::Interface* self) { | 188 | void 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], ¶m, sizeof(param)); | 264 | memcpy(&cmd_buff[2], ¶m, 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 | ||
| 304 | void Shutdown() { | 302 | void 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 | ||
| 17 | namespace Service { | 16 | namespace 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 | ||
| 183 | ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0); | 182 | ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0); |
| 184 | ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A); | 183 | ASSERT_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 |
| 190 | const PadState PAD_NONE = {{0}}; | 189 | const PadState PAD_NONE = {{0}}; |
| 191 | const PadState PAD_A = {{1u << 0}}; | 190 | const PadState PAD_A = {{1u << 0}}; |
| 192 | const PadState PAD_B = {{1u << 1}}; | 191 | const PadState PAD_B = {{1u << 1}}; |
| 193 | const PadState PAD_SELECT = {{1u << 2}}; | 192 | const PadState PAD_SELECT = {{1u << 2}}; |
| 194 | const PadState PAD_START = {{1u << 3}}; | 193 | const PadState PAD_START = {{1u << 3}}; |
| 195 | const PadState PAD_RIGHT = {{1u << 4}}; | 194 | const PadState PAD_RIGHT = {{1u << 4}}; |
| 196 | const PadState PAD_LEFT = {{1u << 5}}; | 195 | const PadState PAD_LEFT = {{1u << 5}}; |
| 197 | const PadState PAD_UP = {{1u << 6}}; | 196 | const PadState PAD_UP = {{1u << 6}}; |
| 198 | const PadState PAD_DOWN = {{1u << 7}}; | 197 | const PadState PAD_DOWN = {{1u << 7}}; |
| 199 | const PadState PAD_R = {{1u << 8}}; | 198 | const PadState PAD_R = {{1u << 8}}; |
| 200 | const PadState PAD_L = {{1u << 9}}; | 199 | const PadState PAD_L = {{1u << 9}}; |
| 201 | const PadState PAD_X = {{1u << 10}}; | 200 | const PadState PAD_X = {{1u << 10}}; |
| 202 | const PadState PAD_Y = {{1u << 11}}; | 201 | const PadState PAD_Y = {{1u << 11}}; |
| 203 | 202 | ||
| 204 | const PadState PAD_ZL = {{1u << 14}}; | 203 | const PadState PAD_ZL = {{1u << 14}}; |
| 205 | const PadState PAD_ZR = {{1u << 15}}; | 204 | const PadState PAD_ZR = {{1u << 15}}; |
| 206 | 205 | ||
| 207 | const PadState PAD_TOUCH = {{1u << 20}}; | 206 | const PadState PAD_TOUCH = {{1u << 20}}; |
| 208 | 207 | ||
| 209 | const PadState PAD_C_RIGHT = {{1u << 24}}; | 208 | const PadState PAD_C_RIGHT = {{1u << 24}}; |
| 210 | const PadState PAD_C_LEFT = {{1u << 25}}; | 209 | const PadState PAD_C_LEFT = {{1u << 25}}; |
| 211 | const PadState PAD_C_UP = {{1u << 26}}; | 210 | const PadState PAD_C_UP = {{1u << 26}}; |
| 212 | const PadState PAD_C_DOWN = {{1u << 27}}; | 211 | const PadState PAD_C_DOWN = {{1u << 27}}; |
| 213 | const PadState PAD_CIRCLE_RIGHT = {{1u << 28}}; | 212 | const PadState PAD_CIRCLE_RIGHT = {{1u << 28}}; |
| 214 | const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; | 213 | const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; |
| 215 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; | 214 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; |
| 216 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; | 215 | const 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 |
| 307 | void Shutdown(); | 306 | void 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 { | |||
| 9 | namespace HID { | 9 | namespace HID { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 24 | HID_SPVR_Interface::HID_SPVR_Interface() { | 24 | HID_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 { | |||
| 9 | namespace HID { | 9 | namespace HID { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 24 | HID_U_Interface::HID_U_Interface() { | 24 | HID_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 @@ | |||
| 10 | namespace HTTP_C { | 10 | namespace HTTP_C { |
| 11 | 11 | ||
| 12 | const Interface::FunctionInfo FunctionTable[] = { | 12 | const 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 | ||
| 14 | namespace Service { | 13 | namespace Service { |
| 15 | namespace IR { | 14 | namespace 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 { | |||
| 9 | namespace IR { | 9 | namespace IR { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 18 | IR_RST_Interface::IR_RST_Interface() { | 18 | IR_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 { | |||
| 8 | namespace IR { | 8 | namespace IR { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const 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 | ||
| 31 | IR_U_Interface::IR_U_Interface() { | 33 | IR_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 { | |||
| 9 | namespace IR { | 9 | namespace IR { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 40 | IR_User_Interface::IR_User_Interface() { | 40 | IR_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 @@ | |||
| 14 | namespace LDR_RO { | 13 | namespace LDR_RO { |
| 15 | 14 | ||
| 16 | static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F | 15 | static 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 | ||
| 19 | static ResultCode CROFormatError(u32 description) { | 19 | static 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 | ||
| 23 | const std::array<int, 17> CROHelper::ENTRY_SIZE {{ | 24 | const 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 | ||
| 43 | const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS {{ | 38 | const 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 | ||
| 50 | VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { | 42 | VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { |
| @@ -63,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { | |||
| 63 | } | 55 | } |
| 64 | 56 | ||
| 65 | ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType relocation_type, | 57 | ResultCode 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 | ||
| 269 | ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, | 250 | ResultVal<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 | ||
| 410 | ResultCode CROHelper::RebaseImportIndexedSymbolTable() { | 397 | ResultCode 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 | ||
| 432 | ResultCode CROHelper::RebaseImportAnonymousSymbolTable() { | 421 | ResultCode 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 | ||
| 529 | ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) { | 521 | ResultCode 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 | ||
| 875 | ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { | 884 | ResultCode 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 | ||
| 903 | ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { | 913 | ResultCode 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 | ||
| 1073 | ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, | 1091 | ResultCode 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 | ||
| 34 | static constexpr u32 CRO_HEADER_SIZE = 0x138; | 35 | static 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. |
| 38 | class CROHelper final { | 39 | class CROHelper final { |
| 39 | public: | 40 | public: |
| 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 | ||
| 19 | namespace LDR_RO { | 18 | namespace LDR_RO { |
| 20 | 19 | ||
| 21 | static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 | 20 | static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 |
| 22 | ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); | 21 | ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, |
| 23 | static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 | 22 | ErrorLevel::Permanent); |
| 24 | ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); | 23 | static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 |
| 25 | static 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); |
| 27 | static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 | 26 | static 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, |
| 29 | static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2 | 28 | ErrorLevel::Usage); |
| 30 | ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); | 29 | static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 |
| 31 | static 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); |
| 33 | static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 | 32 | static 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, |
| 35 | static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D | 34 | ErrorLevel::Permanent); |
| 36 | ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); | 35 | static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F |
| 37 | static 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); |
| 38 | static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 | ||
| 39 | ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState, | ||
| 40 | ErrorLevel::Permanent); | ||
| 41 | static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D | ||
| 42 | ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, | ||
| 43 | ErrorLevel::Permanent); | ||
| 44 | static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830 | ||
| 45 | ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, | ||
| 46 | ErrorSummary::WrongArgument, ErrorLevel::Permanent); | ||
| 39 | 47 | ||
| 40 | static MemorySynchronizer memory_synchronizer; | 48 | static MemorySynchronizer memory_synchronizer; |
| 41 | 49 | ||
| @@ -44,10 +52,10 @@ static VAddr loaded_crs; ///< the virtual address of the static module | |||
| 44 | 52 | ||
| 45 | static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { | 53 | static 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) { | |||
| 66 | static void Initialize(Service::Interface* self) { | 74 | static 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) { | |||
| 186 | static void LoadCRR(Service::Interface* self) { | 199 | static 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) { | |||
| 218 | static void UnloadCRR(Service::Interface* self) { | 232 | static 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 | */ |
| 264 | static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { | 279 | static 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 | */ |
| 465 | static void UnloadCRO(Service::Interface* self) { | 489 | static 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) { | |||
| 558 | static void LinkCRO(Service::Interface* self) { | 583 | static 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) { | |||
| 620 | static void UnlinkCRO(Service::Interface* self) { | 645 | static 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) { | |||
| 682 | static void Shutdown(Service::Interface* self) { | 707 | static 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 | ||
| 726 | const Interface::FunctionInfo FunctionTable[] = { | 751 | const 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 @@ | |||
| 14 | namespace LDR_RO { | 12 | namespace LDR_RO { |
| 15 | 13 | ||
| 16 | auto MemorySynchronizer::FindMemoryBlock(VAddr mapping, VAddr original) { | 14 | auto 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 @@ | |||
| 10 | namespace MIC_U { | 10 | namespace MIC_U { |
| 11 | 11 | ||
| 12 | const Interface::FunctionInfo FunctionTable[] = { | 12 | const 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 | ||
| 11 | namespace Service { | 11 | namespace Service { |
| 12 | namespace NDM { | 12 | namespace NDM { |
| 13 | 13 | ||
| 14 | enum : u32 { | 14 | enum : 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 | ||
| 19 | static DaemonMask daemon_bit_mask = DaemonMask::Default; | 19 | static DaemonMask daemon_bit_mask = DaemonMask::Default; |
| 20 | static DaemonMask default_daemon_bit_mask = DaemonMask::Default; | 20 | static DaemonMask default_daemon_bit_mask = DaemonMask::Default; |
| 21 | static std::array<DaemonStatus, 4> daemon_status = { DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle }; | 21 | static std::array<DaemonStatus, 4> daemon_status = { |
| 22 | DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, | ||
| 23 | }; | ||
| 22 | static ExclusiveState exclusive_state = ExclusiveState::None; | 24 | static ExclusiveState exclusive_state = ExclusiveState::None; |
| 23 | static u32 scan_interval = DEFAULT_SCAN_INTERVAL; | 25 | static u32 scan_interval = DEFAULT_SCAN_INTERVAL; |
| 24 | static u32 retry_interval = DEFAULT_RETRY_INTERVAL; | 26 | static u32 retry_interval = DEFAULT_RETRY_INTERVAL; |
| @@ -72,7 +74,8 @@ void UnlockState(Service::Interface* self) { | |||
| 72 | void SuspendDaemons(Service::Interface* self) { | 74 | void 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 | ||
| 231 | void Shutdown() { | 234 | void 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; | |||
| 13 | namespace NDM { | 13 | namespace NDM { |
| 14 | 14 | ||
| 15 | enum class Daemon : u32 { | 15 | enum 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 | ||
| 22 | enum class DaemonMask : u32 { | 22 | enum 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 | ||
| 32 | enum class DaemonStatus : u32 { | 32 | enum 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 | ||
| 39 | enum class ExclusiveState : u32 { | 34 | enum 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 | */ |
| 206 | void GetRetryInterval(Service::Interface* self); | 201 | void 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 | */ |
| 238 | void GetDefaultDaemons(Service::Interface* self); | 233 | void GetDefaultDaemons(Service::Interface* self); |
| 239 | 234 | ||
| @@ -252,5 +247,5 @@ void Init(); | |||
| 252 | /// Shutdown NDM service | 247 | /// Shutdown NDM service |
| 253 | void Shutdown(); | 248 | void 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 { | |||
| 9 | namespace NDM { | 9 | namespace NDM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 12 | namespace Service { | 11 | namespace Service { |
| 13 | namespace NEWS { | 12 | namespace NEWS { |
| @@ -19,8 +18,7 @@ void Init() { | |||
| 19 | AddService(new NEWS_U_Interface); | 18 | AddService(new NEWS_U_Interface); |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | void Shutdown() { | 21 | void 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 { | |||
| 9 | namespace NEWS { | 9 | namespace NEWS { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 27 | NEWS_S_Interface::NEWS_S_Interface() { | 27 | NEWS_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 { | |||
| 8 | namespace NEWS { | 8 | namespace NEWS { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const Interface::FunctionInfo FunctionTable[] = { |
| 11 | {0x000100C6, nullptr, "AddNotification"}, | 11 | {0x000100C6, nullptr, "AddNotification"}, |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | NEWS_U_Interface::NEWS_U_Interface() { | 14 | NEWS_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 | ||
| 14 | namespace Service { | 13 | namespace Service { |
| 15 | namespace NIM { | 14 | namespace NIM { |
| @@ -31,8 +30,7 @@ void Init() { | |||
| 31 | AddService(new NIM_U_Interface); | 30 | AddService(new NIM_U_Interface); |
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | void Shutdown() { | 33 | void 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 { | |||
| 8 | namespace NIM { | 8 | namespace NIM { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const 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 | ||
| 21 | NIM_AOC_Interface::NIM_AOC_Interface() { | 21 | NIM_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 { | |||
| 8 | namespace NIM { | 8 | namespace NIM { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const 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 | ||
| 17 | NIM_S_Interface::NIM_S_Interface() { | 17 | NIM_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 { | |||
| 9 | namespace NIM { | 9 | namespace NIM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 20 | NIM_U_Interface::NIM_U_Interface() { | 20 | NIM_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 @@ | |||
| 10 | namespace NS_S { | 10 | namespace NS_S { |
| 11 | 11 | ||
| 12 | const Interface::FunctionInfo FunctionTable[] = { | 12 | const 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) { | |||
| 54 | static void RecvBeaconBroadcastData(Service::Interface* self) { | 53 | static 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 | */ |
| 93 | static void Initialize(Service::Interface* self) { | 93 | static 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 | ||
| 108 | const Interface::FunctionInfo FunctionTable[] = { | 109 | const 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 @@ | |||
| 10 | namespace PM_APP { | 10 | namespace PM_APP { |
| 11 | 11 | ||
| 12 | const Interface::FunctionInfo FunctionTable[] = { | 12 | const 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 | ||
| 15 | namespace Service { | 15 | namespace Service { |
| 16 | namespace PTM { | 16 | namespace PTM { |
| 17 | 17 | ||
| 18 | /// Values for the default gamecoin.dat file | 18 | /// Values for the default gamecoin.dat file |
| 19 | static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 }; | 19 | static 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 |
| 22 | static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0}; | 22 | static 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 | ||
| 139 | void Shutdown() { | 147 | void 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 |
| 16 | enum class ChargeLevels : u32 { | 16 | enum 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 | */ |
| 28 | struct GameCoin { | 29 | struct 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 { | |||
| 8 | namespace PTM { | 8 | namespace PTM { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const 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 | ||
| 17 | PTM_Play_Interface::PTM_Play_Interface() { | 17 | PTM_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 { | |||
| 13 | public: | 13 | public: |
| 14 | PTM_Play_Interface(); | 14 | PTM_Play_Interface(); |
| 15 | 15 | ||
| 16 | std::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 { | |||
| 9 | namespace PTM { | 9 | namespace PTM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 45 | PTM_Sysm_Interface::PTM_Sysm_Interface() { | 45 | PTM_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 { | |||
| 9 | namespace PTM { | 9 | namespace PTM { |
| 10 | 10 | ||
| 11 | const Interface::FunctionInfo FunctionTable[] = { | 11 | const 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 | ||
| 29 | PTM_U_Interface::PTM_U_Interface() { | 29 | PTM_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 | ||
| 44 | namespace Service { | 42 | namespace 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 | */ |
| 53 | static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { | 51 | static 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. |
| 30 | public: | 27 | public: |
| 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 | ||
| 51 | protected: | 50 | protected: |
| 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 | ||
| 63 | private: | 61 | private: |
| 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 | ||
| 58 | static const s32 SOCKET_ERROR_VALUE = -1; | 56 | static const s32 SOCKET_ERROR_VALUE = -1; |
| @@ -63,83 +61,83 @@ static const s32 SOCKET_ERROR_VALUE = -1; | |||
| 63 | namespace SOC_U { | 61 | namespace 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 |
| 66 | static const std::unordered_map<int, int> error_map = { { | 64 | static 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 |
| 156 | static const std::unordered_map<int, int> sockopt_map = { { | 154 | static 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 { | |||
| 265 | union CTRSockAddr { | 265 | union 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 | ||
| 777 | static void InitializeSockets(Service::Interface* self) { | 785 | static 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 | ||
| 867 | const Interface::FunctionInfo FunctionTable[] = { | 875 | const 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 | ||
| 152 | const Interface::FunctionInfo FunctionTable[] = { | 153 | const 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 | ||
| 61 | const Interface::FunctionInfo FunctionTable[] = { | 61 | const 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; | |||
| 39 | static u32 spacial_dithering_enabled = 0; | 37 | static u32 spacial_dithering_enabled = 0; |
| 40 | 38 | ||
| 41 | static const CoefficientSet standard_coefficients[4] = { | 39 | static 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 | ||
| 48 | ResultCode ConversionConfiguration::SetInputLineWidth(u16 width) { | 46 | ResultCode 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) { | |||
| 61 | ResultCode ConversionConfiguration::SetInputLines(u16 lines) { | 59 | ResultCode 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 | ||
| 76 | ResultCode ConversionConfiguration::SetStandardCoefficient(StandardCoefficient standard_coefficient) { | 74 | ResultCode 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 | ||
| 301 | static void SetSendingU(Service::Interface* self) { | 302 | static 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 | ||
| 316 | static void SetSendingV(Service::Interface* self) { | 319 | static 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 | ||
| 331 | static void SetSendingYUYV(Service::Interface* self) { | 336 | static 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 | ||
| 493 | static void GetCoefficient(Service::Interface* self) { | 502 | static 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 | ||
| 657 | static void PingProcess(Service::Interface* self) { | 671 | static 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 | |||
| 703 | static void GetPackageParameter(Service::Interface* self) { | 716 | static 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 | ||
| 713 | const Interface::FunctionInfo FunctionTable[] = { | 726 | const 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 | ||
| 54 | static void UpdateTimeCallback(u64 userdata, int cycles_late) { | 53 | static 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 | ||
| 33 | struct SharedPageDef { | 32 | struct 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 | }; |
| 55 | static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong"); | 54 | static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, |
| 55 | "Shared page structure size is wrong"); | ||
| 56 | 56 | ||
| 57 | extern SharedPageDef shared_page; | 57 | extern 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; | |||
| 40 | namespace SVC { | 36 | namespace SVC { |
| 41 | 37 | ||
| 42 | const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, | 38 | const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, |
| 43 | ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA | 39 | ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA |
| 44 | const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, | 40 | const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, |
| 45 | ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E | 41 | ErrorSummary::InvalidArgument, |
| 46 | 42 | ErrorLevel::Usage); // 0xE0E0181E | |
| 47 | const ResultCode ERR_MISALIGNED_ADDRESS{ // 0xE0E01BF1 | 43 | |
| 48 | ErrorDescription::MisalignedAddress, ErrorModule::OS, | 44 | const ResultCode ERR_MISALIGNED_ADDRESS{// 0xE0E01BF1 |
| 49 | ErrorSummary::InvalidArgument, ErrorLevel::Usage}; | 45 | ErrorDescription::MisalignedAddress, ErrorModule::OS, |
| 50 | const ResultCode ERR_MISALIGNED_SIZE{ // 0xE0E01BF2 | 46 | ErrorSummary::InvalidArgument, ErrorLevel::Usage}; |
| 51 | ErrorDescription::MisalignedSize, ErrorModule::OS, | 47 | const ResultCode ERR_MISALIGNED_SIZE{// 0xE0E01BF2 |
| 52 | ErrorSummary::InvalidArgument, ErrorLevel::Usage}; | 48 | ErrorDescription::MisalignedSize, ErrorModule::OS, |
| 53 | const ResultCode ERR_INVALID_COMBINATION{ // 0xE0E01BEE | 49 | ErrorSummary::InvalidArgument, ErrorLevel::Usage}; |
| 54 | ErrorDescription::InvalidCombination, ErrorModule::OS, | 50 | const ResultCode ERR_INVALID_COMBINATION{// 0xE0E01BEE |
| 55 | ErrorSummary::InvalidArgument, ErrorLevel::Usage}; | 51 | ErrorDescription::InvalidCombination, ErrorModule::OS, |
| 52 | ErrorSummary::InvalidArgument, ErrorLevel::Usage}; | ||
| 56 | 53 | ||
| 57 | enum ControlMemoryOperation { | 54 | enum 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 |
| 75 | static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { | 72 | static 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 | ||
| 190 | static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { | 196 | static 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 |
| 275 | static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) { | 281 | static 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 |
| 389 | static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds) { | 400 | static 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) { | |||
| 423 | static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { | 443 | static 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 |
| 436 | static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, | 457 | static 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 |
| 452 | static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, | 474 | static 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 |
| 468 | static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { | 491 | static 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) { | |||
| 576 | static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | 603 | static 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) { | |||
| 588 | static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { | 616 | static 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 |
| 643 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, Handle process_handle, u32 addr) { | 672 | static 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) { | |||
| 783 | static s64 GetSystemTick() { | 814 | static 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 |
| 791 | static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, | 823 | static 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 | ||
| 839 | static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name, u32 max_sessions) { | 875 | static 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 | ||
| 951 | namespace { | 991 | namespace { |
| 952 | struct FunctionDef { | 992 | struct 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 | ||
| 961 | static const FunctionDef SVC_Table[] = { | 1001 | static 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 | ||
| 1090 | static const FunctionDef* GetSVCInfo(u32 func_num) { | 1130 | static const FunctionDef* GetSVCInfo(u32 func_num) { |