diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/set/set_sys.cpp | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index ddab0e36f..225062c0f 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 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 "common/assert.h" | ||
| 5 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 6 | #include "core/file_sys/system_archive/system_version.h" | 7 | #include "core/file_sys/system_archive/system_version.h" |
| 7 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| @@ -11,50 +12,63 @@ | |||
| 11 | 12 | ||
| 12 | namespace Service::Set { | 13 | namespace Service::Set { |
| 13 | 14 | ||
| 14 | void SET_SYS::GetFirmwareVersion(Kernel::HLERequestContext& ctx) { | 15 | constexpr u64 SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET = 0x05; |
| 15 | LOG_DEBUG(Service_SET, "called"); | 16 | |
| 17 | constexpr ResultCode ERROR_FAILED_MOUNT_ARCHIVE(ErrorModule::FS, 3223); | ||
| 18 | constexpr ResultCode ERROR_READ_TOO_LARGE(ErrorModule::FS, 3005); | ||
| 19 | constexpr ResultCode ERROR_INVALID_NAME(ErrorModule::FS, 6001); | ||
| 20 | |||
| 21 | enum class GetFirmwareVersionType { | ||
| 22 | Version1, | ||
| 23 | Version2, | ||
| 24 | }; | ||
| 25 | |||
| 26 | namespace { | ||
| 27 | void GetFirmwareVersionImpl(Kernel::HLERequestContext& ctx, GetFirmwareVersionType type) { | ||
| 28 | LOG_WARNING( | ||
| 29 | Service_SET, | ||
| 30 | "called - Using hardcoded firmware version 'YuzuEmulated Firmware for NX 5.1.0-0.0'"); | ||
| 16 | 31 | ||
| 17 | ASSERT(ctx.GetWriteBufferSize() == 0x100, | 32 | ASSERT_MSG(ctx.GetWriteBufferSize() == 0x100, |
| 18 | "FirmwareVersion output buffer must be 0x100 bytes in size!"); | 33 | "FirmwareVersion output buffer must be 0x100 bytes in size!"); |
| 19 | 34 | ||
| 20 | // Instead of using the normal procedure of checking for the real system archive and if it | 35 | // Instead of using the normal procedure of checking for the real system archive and if it |
| 21 | // doesn't exist, synthesizing one, I feel that that would lead to strange bugs because a used | 36 | // doesn't exist, synthesizing one, I feel that that would lead to strange bugs because a |
| 22 | // is using a really old or really new SystemVersion title. The synthesized one ensures | 37 | // used is using a really old or really new SystemVersion title. The synthesized one ensures |
| 23 | // consistence (currently reports as 5.1.0-0.0) | 38 | // consistence (currently reports as 5.1.0-0.0) |
| 24 | const auto archive = FileSys::SystemArchive::SystemVersion(); | 39 | const auto archive = FileSys::SystemArchive::SystemVersion(); |
| 25 | 40 | ||
| 26 | const auto early_exit_failure = [&ctx](const std::string& desc) { | 41 | const auto early_exit_failure = [&ctx](const std::string& desc, ResultCode code) { |
| 27 | LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", | 42 | LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", |
| 28 | desc.c_str()); | 43 | desc.c_str()); |
| 29 | IPC::ResponseBuilder rb{ctx, 2}; | 44 | IPC::ResponseBuilder rb{ctx, 2}; |
| 30 | rb.Push(ResultCode(-1)); | 45 | rb.Push(code); |
| 31 | }; | 46 | }; |
| 32 | 47 | ||
| 33 | if (archive == nullptr) { | 48 | if (archive == nullptr) { |
| 34 | early_exit_failure("The system version archive couldn't be synthesized."); | 49 | early_exit_failure("The system version archive couldn't be synthesized.", |
| 50 | ERROR_FAILED_MOUNT_ARCHIVE); | ||
| 35 | return; | 51 | return; |
| 36 | } | 52 | } |
| 37 | 53 | ||
| 38 | const auto ver_file = archive->GetFile("file"); | 54 | const auto ver_file = archive->GetFile("file"); |
| 39 | if (ver_file == nullptr) { | 55 | if (ver_file == nullptr) { |
| 40 | early_exit_failure("The system version archive didn't contain the file 'file'."); | 56 | early_exit_failure("The system version archive didn't contain the file 'file'.", |
| 57 | ERROR_INVALID_NAME); | ||
| 41 | return; | 58 | return; |
| 42 | } | 59 | } |
| 43 | 60 | ||
| 44 | auto data = ver_file->ReadAllBytes(); | 61 | auto data = ver_file->ReadAllBytes(); |
| 45 | if (data.size() != 0x100) { | 62 | if (data.size() != 0x100) { |
| 46 | early_exit_failure("The system version file 'file' was not the correct size."); | 63 | early_exit_failure("The system version file 'file' was not the correct size.", |
| 64 | ERROR_READ_TOO_LARGE); | ||
| 47 | return; | 65 | return; |
| 48 | } | 66 | } |
| 49 | 67 | ||
| 50 | // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will zero | 68 | // If the command is GetFirmwareVersion (as opposed to GetFirmwareVersion2), hardware will |
| 51 | // out the REVISION_MAJOR and REVISION_MICRO fields, which are u8s at offsets 0x4 and 0x5, | 69 | // zero out the REVISION_MINOR field. |
| 52 | // respectively. This if statement will only execute when the true intended command is | 70 | if (type == GetFirmwareVersionType::Version1) { |
| 53 | // GetFirmwareVersion, and allows removing duplicate code for the implementation of | 71 | data[SYSTEM_VERSION_FILE_MINOR_REVISION_OFFSET] = 0; |
| 54 | // GetFirmwareVersion2. | ||
| 55 | if (ctx.GetCommand() == 3) { | ||
| 56 | data[0x4] = 0x0; | ||
| 57 | data[0x5] = 0x0; | ||
| 58 | } | 72 | } |
| 59 | 73 | ||
| 60 | ctx.WriteBuffer(data); | 74 | ctx.WriteBuffer(data); |
| @@ -62,10 +76,16 @@ void SET_SYS::GetFirmwareVersion(Kernel::HLERequestContext& ctx) { | |||
| 62 | IPC::ResponseBuilder rb{ctx, 2}; | 76 | IPC::ResponseBuilder rb{ctx, 2}; |
| 63 | rb.Push(RESULT_SUCCESS); | 77 | rb.Push(RESULT_SUCCESS); |
| 64 | } | 78 | } |
| 79 | } // namespace | ||
| 80 | |||
| 81 | void SET_SYS::GetFirmwareVersion(Kernel::HLERequestContext& ctx) { | ||
| 82 | LOG_DEBUG(Service_SET, "called"); | ||
| 83 | GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version1); | ||
| 84 | } | ||
| 65 | 85 | ||
| 66 | void SET_SYS::GetFirmwareVersion2(Kernel::HLERequestContext& ctx) { | 86 | void SET_SYS::GetFirmwareVersion2(Kernel::HLERequestContext& ctx) { |
| 67 | LOG_WARNING(Service_SET, "called - delegating to GetFirmwareVersion"); | 87 | LOG_DEBUG(Service_SET, "called"); |
| 68 | GetFirmwareVersion(ctx); | 88 | GetFirmwareVersionImpl(ctx, GetFirmwareVersionType::Version2); |
| 69 | } | 89 | } |
| 70 | 90 | ||
| 71 | void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) { | 91 | void SET_SYS::GetColorSetId(Kernel::HLERequestContext& ctx) { |