From ba91f070e851223d8799d8afbac71da4d0e4a502 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 17 Sep 2023 09:33:56 -0700 Subject: [PATCH 001/238] mesosphere: remove nostartfiles from specs files (should only be passed to linker wrapper) --- mesosphere/kernel/kernel.specs | 2 +- mesosphere/kernel_ldr/kernel_ldr.specs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mesosphere/kernel/kernel.specs b/mesosphere/kernel/kernel.specs index b849ab5cf..7ca30e94d 100644 --- a/mesosphere/kernel/kernel.specs +++ b/mesosphere/kernel/kernel.specs @@ -1,7 +1,7 @@ %rename link old_link *link: -%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib -nostartfiles +%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib *startfile: crti%O%s crtbegin%O%s diff --git a/mesosphere/kernel_ldr/kernel_ldr.specs b/mesosphere/kernel_ldr/kernel_ldr.specs index 1c6fb7205..593f42369 100644 --- a/mesosphere/kernel_ldr/kernel_ldr.specs +++ b/mesosphere/kernel_ldr/kernel_ldr.specs @@ -1,7 +1,7 @@ %rename link old_link *link: -%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel_ldr.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib -nostartfiles +%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel_ldr.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib *startfile: crti%O%s crtbegin%O%s From 6b72dbd22d1a36fed20faa020ec6175c095194bb Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 1 Sep 2023 20:12:53 -0400 Subject: [PATCH 002/238] haze: refactor constant use for cleaner separation --- troposphere/haze/include/haze/common.hpp | 2 - .../haze/include/haze/ptp_responder.hpp | 12 +- .../haze/include/haze/ptp_responder_types.hpp | 177 ++++++++++++++ troposphere/haze/source/ptp_responder.cpp | 224 ++++-------------- 4 files changed, 226 insertions(+), 189 deletions(-) create mode 100644 troposphere/haze/include/haze/ptp_responder_types.hpp diff --git a/troposphere/haze/include/haze/common.hpp b/troposphere/haze/include/haze/common.hpp index 5ebaf5861..2859b0d50 100644 --- a/troposphere/haze/include/haze/common.hpp +++ b/troposphere/haze/include/haze/common.hpp @@ -42,6 +42,4 @@ namespace haze { using Result = ::ams::Result; - static constexpr u32 UsbBulkPacketBufferSize = 1_MB; - } diff --git a/troposphere/haze/include/haze/ptp_responder.hpp b/troposphere/haze/include/haze/ptp_responder.hpp index eac5aa330..7f1b177eb 100644 --- a/troposphere/haze/include/haze/ptp_responder.hpp +++ b/troposphere/haze/include/haze/ptp_responder.hpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace haze { @@ -30,12 +31,13 @@ namespace haze { FileSystemProxy m_fs; PtpUsbBulkContainer m_request_header; PtpObjectHeap *m_object_heap; + PtpBuffers* m_buffers; u32 m_send_object_id; bool m_session_open; PtpObjectDatabase m_object_database; public: - constexpr explicit PtpResponder() : m_usb_server(), m_fs(), m_request_header(), m_object_heap(), m_send_object_id(), m_session_open(), m_object_database() { /* ... */ } + constexpr explicit PtpResponder() : m_usb_server(), m_fs(), m_request_header(), m_object_heap(), m_buffers(), m_send_object_id(), m_session_open(), m_object_database() { /* ... */ } Result Initialize(EventReactor *reactor, PtpObjectHeap *object_heap); void Finalize(); @@ -48,10 +50,14 @@ namespace haze { Result HandleCommandRequest(PtpDataParser &dp); void ForceCloseSession(); - template - Result WriteResponse(PtpResponseCode code, Data &&data); + Result WriteResponse(PtpResponseCode code, const void* data, size_t size); Result WriteResponse(PtpResponseCode code); + template requires (util::is_pod::value) + Result WriteResponse(PtpResponseCode code, const Data &data) { + R_RETURN(this->WriteResponse(code, std::addressof(data), sizeof(data))); + } + /* PTP operations. */ Result GetDeviceInfo(PtpDataParser &dp); Result OpenSession(PtpDataParser &dp); diff --git a/troposphere/haze/include/haze/ptp_responder_types.hpp b/troposphere/haze/include/haze/ptp_responder_types.hpp new file mode 100644 index 000000000..3e307f9d3 --- /dev/null +++ b/troposphere/haze/include/haze/ptp_responder_types.hpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include + +namespace haze { + + constexpr UsbCommsInterfaceInfo MtpInterfaceInfo = { + .bInterfaceClass = 0x06, + .bInterfaceSubClass = 0x01, + .bInterfaceProtocol = 0x01, + }; + + /* This is a VID:PID recognized by libmtp. */ + constexpr u16 SwitchMtpIdVendor = 0x057e; + constexpr u16 SwitchMtpIdProduct = 0x201d; + + /* Constants used for MTP GetDeviceInfo response. */ + constexpr u16 MtpStandardVersion = 100; + constexpr u32 MtpVendorExtensionId = 6; + constexpr auto MtpVendorExtensionDesc = "microsoft.com: 1.0;"; + constexpr u16 MtpFunctionalModeDefault = 0; + constexpr auto MtpDeviceManufacturer = "Nintendo"; + constexpr auto MtpDeviceModel = "Nintendo Switch"; + + enum StorageId : u32 { + StorageId_SdmcFs = 0xffffffffu - 1, + }; + + constexpr PtpOperationCode SupportedOperationCodes[] = { + PtpOperationCode_GetDeviceInfo, + PtpOperationCode_OpenSession, + PtpOperationCode_CloseSession, + PtpOperationCode_GetStorageIds, + PtpOperationCode_GetStorageInfo, + PtpOperationCode_GetObjectHandles, + PtpOperationCode_GetObjectInfo, + PtpOperationCode_GetObject, + PtpOperationCode_SendObjectInfo, + PtpOperationCode_SendObject, + PtpOperationCode_DeleteObject, + PtpOperationCode_MtpGetObjectPropsSupported, + PtpOperationCode_MtpGetObjectPropDesc, + PtpOperationCode_MtpGetObjectPropValue, + PtpOperationCode_MtpSetObjectPropValue, + }; + + constexpr const PtpEventCode SupportedEventCodes[] = { /* ... */ }; + constexpr const PtpDevicePropertyCode SupportedDeviceProperties[] = { /* ... */ }; + constexpr const PtpObjectFormatCode SupportedCaptureFormats[] = { /* ... */ }; + + constexpr const PtpObjectFormatCode SupportedPlaybackFormats[] = { + PtpObjectFormatCode_Undefined, + PtpObjectFormatCode_Association, + }; + + constexpr const PtpObjectPropertyCode SupportedObjectProperties[] = { + PtpObjectPropertyCode_StorageId, + PtpObjectPropertyCode_ObjectFormat, + PtpObjectPropertyCode_ObjectSize, + PtpObjectPropertyCode_ObjectFileName, + PtpObjectPropertyCode_ParentObject, + PtpObjectPropertyCode_PersistentUniqueObjectIdentifier, + }; + + constexpr bool IsSupportedObjectPropertyCode(PtpObjectPropertyCode c) { + for (size_t i = 0; i < util::size(SupportedObjectProperties); i++) { + if (SupportedObjectProperties[i] == c) { + return true; + } + } + + return false; + } + + constexpr const StorageId SupportedStorageIds[] = { + StorageId_SdmcFs, + }; + + struct PtpStorageInfo { + PtpStorageType storage_type; + PtpFilesystemType filesystem_type; + PtpAccessCapability access_capability; + u64 max_capacity; + u64 free_space_in_bytes; + u32 free_space_in_images; + const char *storage_description; + const char *volume_label; + }; + + constexpr PtpStorageInfo DefaultStorageInfo = { + .storage_type = PtpStorageType_FixedRam, + .filesystem_type = PtpFilesystemType_GenericHierarchical, + .access_capability = PtpAccessCapability_ReadWrite, + .max_capacity = 0, + .free_space_in_bytes = 0, + .free_space_in_images = 0, + .storage_description = "", + .volume_label = "", + }; + + struct PtpObjectInfo { + StorageId storage_id; + PtpObjectFormatCode object_format; + PtpProtectionStatus protection_status; + u32 object_compressed_size; + u16 thumb_format; + u32 thumb_compressed_size; + u32 thumb_width; + u32 thumb_height; + u32 image_width; + u32 image_height; + u32 image_depth; + u32 parent_object; + PtpAssociationType association_type; + u32 association_desc; + u32 sequence_number; + const char *filename; + const char *capture_date; + const char *modification_date; + const char *keywords; + }; + + constexpr PtpObjectInfo DefaultObjectInfo = { + .storage_id = StorageId_SdmcFs, + .object_format = {}, + .protection_status = PtpProtectionStatus_NoProtection, + .object_compressed_size = 0, + .thumb_format = 0, + .thumb_compressed_size = 0, + .thumb_width = 0, + .thumb_height = 0, + .image_width = 0, + .image_height = 0, + .image_depth = 0, + .parent_object = PtpGetObjectHandles_RootParent, + .association_type = PtpAssociationType_Undefined, + .association_desc = 0, + .sequence_number = 0, + .filename = nullptr, + .capture_date = "", + .modification_date = "", + .keywords = "", + }; + + constexpr u32 UsbBulkPacketBufferSize = 1_MB; + constexpr u64 FsBufferSize = UsbBulkPacketBufferSize; + constexpr s64 DirectoryReadSize = 32; + + struct PtpBuffers { + char filename_string_buffer[PtpStringMaxLength + 1]; + char capture_date_string_buffer[PtpStringMaxLength + 1]; + char modification_date_string_buffer[PtpStringMaxLength + 1]; + char keywords_string_buffer[PtpStringMaxLength + 1]; + + FsDirectoryEntry file_system_entry_buffer[DirectoryReadSize]; + u8 file_system_data_buffer[FsBufferSize]; + + alignas(4_KB) u8 usb_bulk_write_buffer[UsbBulkPacketBufferSize]; + alignas(4_KB) u8 usb_bulk_read_buffer[UsbBulkPacketBufferSize]; + }; + +} diff --git a/troposphere/haze/source/ptp_responder.cpp b/troposphere/haze/source/ptp_responder.cpp index 6086c2cce..97f427431 100644 --- a/troposphere/haze/source/ptp_responder.cpp +++ b/troposphere/haze/source/ptp_responder.cpp @@ -16,167 +16,22 @@ #include #include #include +#include namespace haze { namespace { - constexpr UsbCommsInterfaceInfo MtpInterfaceInfo = { - .bInterfaceClass = 0x06, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x01, - }; - - /* This is a VID:PID recognized by libmtp. */ - constexpr u16 SwitchMtpIdVendor = 0x057e; - constexpr u16 SwitchMtpIdProduct = 0x201d; - - /* Constants used for MTP GetDeviceInfo response. */ - constexpr u16 MtpStandardVersion = 100; - constexpr u32 MtpVendorExtensionId = 6; - constexpr auto MtpVendorExtensionDesc = "microsoft.com: 1.0;"; - constexpr u16 MtpFunctionalModeDefault = 0; - constexpr auto MtpDeviceManufacturer = "Nintendo"; - constexpr auto MtpDeviceModel = "Nintendo Switch"; - - enum StorageId : u32 { - StorageId_SdmcFs = 0xffffffffu - 1, - }; - - constexpr PtpOperationCode SupportedOperationCodes[] = { - PtpOperationCode_GetDeviceInfo, - PtpOperationCode_OpenSession, - PtpOperationCode_CloseSession, - PtpOperationCode_GetStorageIds, - PtpOperationCode_GetStorageInfo, - PtpOperationCode_GetObjectHandles, - PtpOperationCode_GetObjectInfo, - PtpOperationCode_GetObject, - PtpOperationCode_SendObjectInfo, - PtpOperationCode_SendObject, - PtpOperationCode_DeleteObject, - PtpOperationCode_MtpGetObjectPropsSupported, - PtpOperationCode_MtpGetObjectPropDesc, - PtpOperationCode_MtpGetObjectPropValue, - PtpOperationCode_MtpSetObjectPropValue, - }; - - constexpr const PtpEventCode SupportedEventCodes[] = { /* ... */ }; - constexpr const PtpDevicePropertyCode SupportedDeviceProperties[] = { /* ... */ }; - constexpr const PtpObjectFormatCode SupportedCaptureFormats[] = { /* ... */ }; - - constexpr const PtpObjectFormatCode SupportedPlaybackFormats[] = { - PtpObjectFormatCode_Undefined, - PtpObjectFormatCode_Association, - }; - - constexpr const PtpObjectPropertyCode SupportedObjectProperties[] = { - PtpObjectPropertyCode_StorageId, - PtpObjectPropertyCode_ObjectFormat, - PtpObjectPropertyCode_ObjectSize, - PtpObjectPropertyCode_ObjectFileName, - PtpObjectPropertyCode_ParentObject, - PtpObjectPropertyCode_PersistentUniqueObjectIdentifier, - }; - - constexpr bool IsSupportedObjectPropertyCode(PtpObjectPropertyCode c) { - for (size_t i = 0; i < util::size(SupportedObjectProperties); i++) { - if (SupportedObjectProperties[i] == c) { - return true; - } - } - - return false; + PtpBuffers* GetBuffers() { + static constinit PtpBuffers buffers = {}; + return std::addressof(buffers); } - constexpr const StorageId SupportedStorageIds[] = { - StorageId_SdmcFs, - }; - - struct PtpStorageInfo { - PtpStorageType storage_type; - PtpFilesystemType filesystem_type; - PtpAccessCapability access_capability; - u64 max_capacity; - u64 free_space_in_bytes; - u32 free_space_in_images; - const char *storage_description; - const char *volume_label; - }; - - constexpr PtpStorageInfo DefaultStorageInfo = { - .storage_type = PtpStorageType_FixedRam, - .filesystem_type = PtpFilesystemType_GenericHierarchical, - .access_capability = PtpAccessCapability_ReadWrite, - .max_capacity = 0, - .free_space_in_bytes = 0, - .free_space_in_images = 0, - .storage_description = "", - .volume_label = "", - }; - - struct PtpObjectInfo { - StorageId storage_id; - PtpObjectFormatCode object_format; - PtpProtectionStatus protection_status; - u32 object_compressed_size; - u16 thumb_format; - u32 thumb_compressed_size; - u32 thumb_width; - u32 thumb_height; - u32 image_width; - u32 image_height; - u32 image_depth; - u32 parent_object; - PtpAssociationType association_type; - u32 association_desc; - u32 sequence_number; - const char *filename; - const char *capture_date; - const char *modification_date; - const char *keywords; - }; - - constexpr PtpObjectInfo DefaultObjectInfo = { - .storage_id = StorageId_SdmcFs, - .object_format = {}, - .protection_status = PtpProtectionStatus_NoProtection, - .object_compressed_size = 0, - .thumb_format = 0, - .thumb_compressed_size = 0, - .thumb_width = 0, - .thumb_height = 0, - .image_width = 0, - .image_height = 0, - .image_depth = 0, - .parent_object = PtpGetObjectHandles_RootParent, - .association_type = PtpAssociationType_Undefined, - .association_desc = 0, - .sequence_number = 0, - .filename = nullptr, - .capture_date = "", - .modification_date = "", - .keywords = "", - }; - - constexpr s64 DirectoryReadSize = 32; - constexpr u64 FsBufferSize = haze::UsbBulkPacketBufferSize; - - constinit char g_filename_str[PtpStringMaxLength + 1] = {}; - constinit char g_capture_date_str[PtpStringMaxLength + 1] = {}; - constinit char g_modification_date_str[PtpStringMaxLength + 1] = {}; - constinit char g_keywords_str[PtpStringMaxLength + 1] = {}; - - constinit FsDirectoryEntry g_dir_entries[DirectoryReadSize] = {}; - constinit u8 g_fs_buffer[FsBufferSize] = {}; - - alignas(4_KB) constinit u8 g_bulk_write_buffer[haze::UsbBulkPacketBufferSize] = {}; - alignas(4_KB) constinit u8 g_bulk_read_buffer[haze::UsbBulkPacketBufferSize] = {}; - } Result PtpResponder::Initialize(EventReactor *reactor, PtpObjectHeap *object_heap) { m_object_heap = object_heap; + m_buffers = GetBuffers(); /* Configure fs proxy. */ m_fs.Initialize(reactor, fsdevGetDeviceFileSystem("sdmc")); @@ -246,7 +101,7 @@ namespace haze { } Result PtpResponder::HandleRequestImpl() { - PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); R_TRY(dp.Read(std::addressof(m_request_header))); switch (m_request_header.type) { @@ -287,22 +142,21 @@ namespace haze { } } - template - Result PtpResponder::WriteResponse(PtpResponseCode code, Data &&data) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); - R_TRY(db.AddResponseHeader(m_request_header, code, sizeof(Data))); - R_TRY(db.Add(data)); + Result PtpResponder::WriteResponse(PtpResponseCode code, const void* data, size_t size) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + R_TRY(db.AddResponseHeader(m_request_header, code, size)); + R_TRY(db.AddBuffer(reinterpret_cast(data), size)); R_RETURN(db.Commit()); } Result PtpResponder::WriteResponse(PtpResponseCode code) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); R_TRY(db.AddResponseHeader(m_request_header, code, 0)); R_RETURN(db.Commit()); } Result PtpResponder::GetDeviceInfo(PtpDataParser &dp) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); /* Write the device info data. */ R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { @@ -361,7 +215,7 @@ namespace haze { Result PtpResponder::GetStorageIds(PtpDataParser &dp) { R_TRY(dp.Finalize()); - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); /* Write the storage ID array. */ R_TRY(db.WriteVariableLengthData(m_request_header, [&] { @@ -373,7 +227,7 @@ namespace haze { } Result PtpResponder::GetStorageInfo(PtpDataParser &dp) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); PtpStorageInfo storage_info(DefaultStorageInfo); /* Get the storage ID the client requested information for. */ @@ -418,7 +272,7 @@ namespace haze { } Result PtpResponder::GetObjectHandles(PtpDataParser &dp) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); /* Get the object ID the client requested enumeration for. */ u32 storage_id, object_format_code, association_object_handle; @@ -462,12 +316,14 @@ namespace haze { while (true) { /* Get the next batch. */ s64 read_count = 0; - R_TRY(m_fs.ReadDirectory(std::addressof(dir), std::addressof(read_count), DirectoryReadSize, g_dir_entries)); + R_TRY(m_fs.ReadDirectory(std::addressof(dir), std::addressof(read_count), DirectoryReadSize, m_buffers->file_system_entry_buffer)); /* Write to output. */ for (s64 i = 0; i < read_count; i++) { + const char *name = m_buffers->file_system_entry_buffer[i].name; u32 handle; - R_TRY(m_object_database.CreateAndRegisterObjectId(obj->GetName(), g_dir_entries[i].name, obj->GetObjectId(), std::addressof(handle))); + + R_TRY(m_object_database.CreateAndRegisterObjectId(obj->GetName(), name, obj->GetObjectId(), std::addressof(handle))); R_TRY(db.Add(handle)); } @@ -485,7 +341,7 @@ namespace haze { } Result PtpResponder::GetObjectInfo(PtpDataParser &dp) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); /* Get the object ID the client requested info for. */ u32 object_id; @@ -564,7 +420,7 @@ namespace haze { } Result PtpResponder::GetObject(PtpDataParser &dp) { - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); /* Get the object ID the client requested. */ u32 object_id; @@ -594,12 +450,12 @@ namespace haze { while (true) { /* Get the next batch. */ u64 bytes_read; - R_TRY(m_fs.ReadFile(std::addressof(file), offset, g_fs_buffer, FsBufferSize, FsReadOption_None, std::addressof(bytes_read))); + R_TRY(m_fs.ReadFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, FsBufferSize, FsReadOption_None, std::addressof(bytes_read))); offset += bytes_read; /* Write to output. */ - R_TRY(db.AddBuffer(g_fs_buffer, bytes_read)); + R_TRY(db.AddBuffer(m_buffers->file_system_data_buffer, bytes_read)); /* If we read fewer bytes than the batch size, we're done. */ if (bytes_read < FsBufferSize) { @@ -621,7 +477,7 @@ namespace haze { R_TRY(rdp.Read(std::addressof(parent_object))); R_TRY(rdp.Finalize()); - PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); PtpObjectInfo info(DefaultObjectInfo); /* Ensure we have a data header. */ @@ -647,10 +503,10 @@ namespace haze { R_TRY(dp.Read(std::addressof(info.association_type))); R_TRY(dp.Read(std::addressof(info.association_desc))); R_TRY(dp.Read(std::addressof(info.sequence_number))); - R_TRY(dp.ReadString(g_filename_str)); - R_TRY(dp.ReadString(g_capture_date_str)); - R_TRY(dp.ReadString(g_modification_date_str)); - R_TRY(dp.ReadString(g_keywords_str)); + R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); + R_TRY(dp.ReadString(m_buffers->capture_date_string_buffer)); + R_TRY(dp.ReadString(m_buffers->modification_date_string_buffer)); + R_TRY(dp.ReadString(m_buffers->keywords_string_buffer)); R_TRY(dp.Finalize()); /* Rewrite requests for creating in storage directories. */ @@ -669,7 +525,7 @@ namespace haze { /* Create the object in the database. */ PtpObject *obj; - R_TRY(m_object_database.CreateOrFindObject(parentobj->GetName(), g_filename_str, parentobj->GetObjectId(), std::addressof(obj))); + R_TRY(m_object_database.CreateOrFindObject(parentobj->GetName(), m_buffers->filename_string_buffer, parentobj->GetObjectId(), std::addressof(obj))); /* Ensure we maintain a clean state on failure. */ ON_RESULT_FAILURE { m_object_database.DeleteObject(obj); }; @@ -697,7 +553,7 @@ namespace haze { R_TRY(rdp.Finalize()); - PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); /* Ensure we have a data header. */ PtpUsbBulkContainer data_header; @@ -730,10 +586,10 @@ namespace haze { while (true) { /* Read as many bytes as we can. */ u32 bytes_received; - const Result read_res = dp.ReadBuffer(g_fs_buffer, FsBufferSize, std::addressof(bytes_received)); + const Result read_res = dp.ReadBuffer(m_buffers->file_system_data_buffer, FsBufferSize, std::addressof(bytes_received)); /* Write to the file. */ - R_TRY(m_fs.WriteFile(std::addressof(file), offset, g_fs_buffer, bytes_received, 0)); + R_TRY(m_fs.WriteFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_received, 0)); offset += bytes_received; @@ -786,7 +642,7 @@ namespace haze { Result PtpResponder::GetObjectPropsSupported(PtpDataParser &dp) { R_TRY(dp.Finalize()); - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); /* Write information about all object properties we can support. */ R_TRY(db.WriteVariableLengthData(m_request_header, [&] { @@ -809,7 +665,7 @@ namespace haze { R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); /* Begin writing information about the property code. */ - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); R_TRY(db.WriteVariableLengthData(m_request_header, [&] { R_TRY(db.Add(property_code)); @@ -913,7 +769,7 @@ namespace haze { }; /* Begin writing the requested object property. */ - PtpDataBuilder db(g_bulk_write_buffer, std::addressof(m_usb_server)); + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); R_TRY(db.WriteVariableLengthData(m_request_header, [&] { switch (property_code) { @@ -969,7 +825,7 @@ namespace haze { R_TRY(rdp.Read(std::addressof(property_code))); R_TRY(rdp.Finalize()); - PtpDataParser dp(g_bulk_read_buffer, std::addressof(m_usb_server)); + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); /* Ensure we have a data header. */ PtpUsbBulkContainer data_header; @@ -986,12 +842,12 @@ namespace haze { R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); /* We are reading a file name. */ - R_TRY(dp.ReadString(g_filename_str)); + R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); R_TRY(dp.Finalize()); /* Ensure we can actually process the new name. */ - const bool is_empty = g_filename_str[0] == '\x00'; - const bool contains_slashes = std::strchr(g_filename_str, '/') != nullptr; + const bool is_empty = m_buffers->filename_string_buffer[0] == '\x00'; + const bool contains_slashes = std::strchr(m_buffers->filename_string_buffer, '/') != nullptr; R_UNLESS(!is_empty && !contains_slashes, haze::ResultInvalidPropertyValue()); /* Add a new object in the database with the new name. */ @@ -1005,7 +861,7 @@ namespace haze { *pathsep = '\x00'; ON_SCOPE_EXIT { *pathsep = '/'; }; - R_TRY(m_object_database.CreateOrFindObject(obj->GetName(), g_filename_str, obj->GetParentId(), std::addressof(newobj))); + R_TRY(m_object_database.CreateOrFindObject(obj->GetName(), m_buffers->filename_string_buffer, obj->GetParentId(), std::addressof(newobj))); } { From 9e0daff46edda6da338f7d9c3b80b89f6c1db041 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 1 Sep 2023 20:16:06 -0400 Subject: [PATCH 003/238] haze: split operations by type --- troposphere/haze/source/ptp_responder.cpp | 740 ------------------ .../source/ptp_responder_mtp_operations.cpp | 280 +++++++ .../source/ptp_responder_ptp_operations.cpp | 507 ++++++++++++ 3 files changed, 787 insertions(+), 740 deletions(-) create mode 100644 troposphere/haze/source/ptp_responder_mtp_operations.cpp create mode 100644 troposphere/haze/source/ptp_responder_ptp_operations.cpp diff --git a/troposphere/haze/source/ptp_responder.cpp b/troposphere/haze/source/ptp_responder.cpp index 97f427431..ffba26229 100644 --- a/troposphere/haze/source/ptp_responder.cpp +++ b/troposphere/haze/source/ptp_responder.cpp @@ -155,744 +155,4 @@ namespace haze { R_RETURN(db.Commit()); } - Result PtpResponder::GetDeviceInfo(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Write the device info data. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { - R_TRY(db.Add(MtpStandardVersion)); - R_TRY(db.Add(MtpVendorExtensionId)); - R_TRY(db.Add(MtpStandardVersion)); - R_TRY(db.AddString(MtpVendorExtensionDesc)); - R_TRY(db.Add(MtpFunctionalModeDefault)); - R_TRY(db.AddArray(SupportedOperationCodes, util::size(SupportedOperationCodes))); - R_TRY(db.AddArray(SupportedEventCodes, util::size(SupportedEventCodes))); - R_TRY(db.AddArray(SupportedDeviceProperties, util::size(SupportedDeviceProperties))); - R_TRY(db.AddArray(SupportedCaptureFormats, util::size(SupportedCaptureFormats))); - R_TRY(db.AddArray(SupportedPlaybackFormats, util::size(SupportedPlaybackFormats))); - R_TRY(db.AddString(MtpDeviceManufacturer)); - R_TRY(db.AddString(MtpDeviceModel)); - R_TRY(db.AddString(GetFirmwareVersion())); - R_TRY(db.AddString(GetSerialNumber())); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::OpenSession(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - /* Close, if we're already open. */ - this->ForceCloseSession(); - - /* Initialize the database. */ - m_session_open = true; - m_object_database.Initialize(m_object_heap); - - /* Create the root storages. */ - PtpObject *object; - R_TRY(m_object_database.CreateOrFindObject("", "", PtpGetObjectHandles_RootParent, std::addressof(object))); - - /* Register the root storages. */ - m_object_database.RegisterObject(object, StorageId_SdmcFs); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::CloseSession(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - this->ForceCloseSession(); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetStorageIds(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Write the storage ID array. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - R_RETURN(db.AddArray(SupportedStorageIds, util::size(SupportedStorageIds))); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetStorageInfo(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - PtpStorageInfo storage_info(DefaultStorageInfo); - - /* Get the storage ID the client requested information for. */ - u32 storage_id; - R_TRY(dp.Read(std::addressof(storage_id))); - R_TRY(dp.Finalize()); - - /* Get the info from fs. */ - switch (storage_id) { - case StorageId_SdmcFs: - { - s64 total_space, free_space; - R_TRY(m_fs.GetTotalSpace("/", std::addressof(total_space))); - R_TRY(m_fs.GetFreeSpace("/", std::addressof(free_space))); - - storage_info.max_capacity = total_space; - storage_info.free_space_in_bytes = free_space; - storage_info.free_space_in_images = 0; - storage_info.storage_description = "SD Card"; - } - break; - default: - R_THROW(haze::ResultInvalidStorageId()); - } - - /* Write the storage info data. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { - R_TRY(db.Add(storage_info.storage_type)); - R_TRY(db.Add(storage_info.filesystem_type)); - R_TRY(db.Add(storage_info.access_capability)); - R_TRY(db.Add(storage_info.max_capacity)); - R_TRY(db.Add(storage_info.free_space_in_bytes)); - R_TRY(db.Add(storage_info.free_space_in_images)); - R_TRY(db.AddString(storage_info.storage_description)); - R_TRY(db.AddString(storage_info.volume_label)); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectHandles(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID the client requested enumeration for. */ - u32 storage_id, object_format_code, association_object_handle; - R_TRY(dp.Read(std::addressof(storage_id))); - R_TRY(dp.Read(std::addressof(object_format_code))); - R_TRY(dp.Read(std::addressof(association_object_handle))); - R_TRY(dp.Finalize()); - - /* Handle top-level requests. */ - if (storage_id == PtpGetObjectHandles_AllStorage) { - storage_id = StorageId_SdmcFs; - } - - /* Rewrite requests for enumerating storage directories. */ - if (association_object_handle == PtpGetObjectHandles_RootParent) { - association_object_handle = storage_id; - } - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(association_object_handle); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Try to read the object as a directory. */ - FsDir dir; - R_TRY(m_fs.OpenDirectory(obj->GetName(), FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles, std::addressof(dir))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseDirectory(std::addressof(dir)); }; - - /* Count how many entries are in the directory. */ - s64 entry_count = 0; - R_TRY(m_fs.GetDirectoryEntryCount(std::addressof(dir), std::addressof(entry_count))); - - /* Begin writing. */ - R_TRY(db.AddDataHeader(m_request_header, sizeof(u32) + (entry_count * sizeof(u32)))); - R_TRY(db.Add(static_cast(entry_count))); - - /* Enumerate the directory, writing results to the data builder as we progress. */ - /* TODO: How should we handle the directory contents changing during enumeration? */ - /* Is this even feasible to handle? */ - while (true) { - /* Get the next batch. */ - s64 read_count = 0; - R_TRY(m_fs.ReadDirectory(std::addressof(dir), std::addressof(read_count), DirectoryReadSize, m_buffers->file_system_entry_buffer)); - - /* Write to output. */ - for (s64 i = 0; i < read_count; i++) { - const char *name = m_buffers->file_system_entry_buffer[i].name; - u32 handle; - - R_TRY(m_object_database.CreateAndRegisterObjectId(obj->GetName(), name, obj->GetObjectId(), std::addressof(handle))); - R_TRY(db.Add(handle)); - } - - /* If we read fewer than the batch size, we're done. */ - if (read_count < DirectoryReadSize) { - break; - } - } - - /* Flush the data response. */ - R_TRY(db.Commit()); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectInfo(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID the client requested info for. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Build info about the object. */ - PtpObjectInfo object_info(DefaultObjectInfo); - - if (object_id == StorageId_SdmcFs) { - /* The SD Card directory has some special properties. */ - object_info.object_format = PtpObjectFormatCode_Association; - object_info.association_type = PtpAssociationType_GenericFolder; - object_info.filename = "SD Card"; - } else { - /* Figure out what type of object this is. */ - FsDirEntryType entry_type; - R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); - - /* Get the size, if we are requesting info about a file. */ - s64 size = 0; - if (entry_type == FsDirEntryType_File) { - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); - } - - object_info.filename = std::strrchr(obj->GetName(), '/') + 1; - object_info.object_compressed_size = size; - object_info.parent_object = obj->GetParentId(); - - if (entry_type == FsDirEntryType_Dir) { - object_info.object_format = PtpObjectFormatCode_Association; - object_info.association_type = PtpAssociationType_GenericFolder; - } else { - object_info.object_format = PtpObjectFormatCode_Undefined; - object_info.association_type = PtpAssociationType_Undefined; - } - } - - /* Write the object info data. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { - R_TRY(db.Add(object_info.storage_id)); - R_TRY(db.Add(object_info.object_format)); - R_TRY(db.Add(object_info.protection_status)); - R_TRY(db.Add(object_info.object_compressed_size)); - R_TRY(db.Add(object_info.thumb_format)); - R_TRY(db.Add(object_info.thumb_compressed_size)); - R_TRY(db.Add(object_info.thumb_width)); - R_TRY(db.Add(object_info.thumb_height)); - R_TRY(db.Add(object_info.image_width)); - R_TRY(db.Add(object_info.image_height)); - R_TRY(db.Add(object_info.image_depth)); - R_TRY(db.Add(object_info.parent_object)); - R_TRY(db.Add(object_info.association_type)); - R_TRY(db.Add(object_info.association_desc)); - R_TRY(db.Add(object_info.sequence_number)); - R_TRY(db.AddString(object_info.filename)); - R_TRY(db.AddString(object_info.capture_date)); - R_TRY(db.AddString(object_info.modification_date)); - R_TRY(db.AddString(object_info.keywords)); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObject(PtpDataParser &dp) { - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Get the object ID the client requested. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Get the file's size. */ - s64 size = 0; - R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); - - /* Send the header and file size. */ - R_TRY(db.AddDataHeader(m_request_header, size)); - - /* Begin reading the file, writing data to the builder as we progress. */ - s64 offset = 0; - while (true) { - /* Get the next batch. */ - u64 bytes_read; - R_TRY(m_fs.ReadFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, FsBufferSize, FsReadOption_None, std::addressof(bytes_read))); - - offset += bytes_read; - - /* Write to output. */ - R_TRY(db.AddBuffer(m_buffers->file_system_data_buffer, bytes_read)); - - /* If we read fewer bytes than the batch size, we're done. */ - if (bytes_read < FsBufferSize) { - break; - } - } - - /* Flush the data response. */ - R_TRY(db.Commit()); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::SendObjectInfo(PtpDataParser &rdp) { - /* Get the storage ID and parent object and flush the request packet. */ - u32 storage_id, parent_object; - R_TRY(rdp.Read(std::addressof(storage_id))); - R_TRY(rdp.Read(std::addressof(parent_object))); - R_TRY(rdp.Finalize()); - - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - PtpObjectInfo info(DefaultObjectInfo); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Read in the object info. */ - R_TRY(dp.Read(std::addressof(info.storage_id))); - R_TRY(dp.Read(std::addressof(info.object_format))); - R_TRY(dp.Read(std::addressof(info.protection_status))); - R_TRY(dp.Read(std::addressof(info.object_compressed_size))); - R_TRY(dp.Read(std::addressof(info.thumb_format))); - R_TRY(dp.Read(std::addressof(info.thumb_compressed_size))); - R_TRY(dp.Read(std::addressof(info.thumb_width))); - R_TRY(dp.Read(std::addressof(info.thumb_height))); - R_TRY(dp.Read(std::addressof(info.image_width))); - R_TRY(dp.Read(std::addressof(info.image_height))); - R_TRY(dp.Read(std::addressof(info.image_depth))); - R_TRY(dp.Read(std::addressof(info.parent_object))); - R_TRY(dp.Read(std::addressof(info.association_type))); - R_TRY(dp.Read(std::addressof(info.association_desc))); - R_TRY(dp.Read(std::addressof(info.sequence_number))); - R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); - R_TRY(dp.ReadString(m_buffers->capture_date_string_buffer)); - R_TRY(dp.ReadString(m_buffers->modification_date_string_buffer)); - R_TRY(dp.ReadString(m_buffers->keywords_string_buffer)); - R_TRY(dp.Finalize()); - - /* Rewrite requests for creating in storage directories. */ - if (parent_object == PtpGetObjectHandles_RootParent) { - parent_object = storage_id; - } - - /* Check if we know about the parent object. If we don't, it's an error. */ - auto * const parentobj = m_object_database.GetObjectById(parent_object); - R_UNLESS(parentobj != nullptr, haze::ResultInvalidObjectId()); - - /* Make a new object with the intended name. */ - PtpNewObjectInfo new_object_info; - new_object_info.storage_id = StorageId_SdmcFs; - new_object_info.parent_object_id = parent_object == storage_id ? 0 : parent_object; - - /* Create the object in the database. */ - PtpObject *obj; - R_TRY(m_object_database.CreateOrFindObject(parentobj->GetName(), m_buffers->filename_string_buffer, parentobj->GetObjectId(), std::addressof(obj))); - - /* Ensure we maintain a clean state on failure. */ - ON_RESULT_FAILURE { m_object_database.DeleteObject(obj); }; - - /* Register the object with a new ID. */ - m_object_database.RegisterObject(obj); - new_object_info.object_id = obj->GetObjectId(); - - /* Create the object on the filesystem. */ - if (info.object_format == PtpObjectFormatCode_Association) { - R_TRY(m_fs.CreateDirectory(obj->GetName())); - m_send_object_id = 0; - } else { - R_TRY(m_fs.CreateFile(obj->GetName(), 0, 0)); - m_send_object_id = new_object_info.object_id; - } - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok, new_object_info)); - } - - Result PtpResponder::SendObject(PtpDataParser &rdp) { - /* Reset SendObject object ID on exit. */ - ON_SCOPE_EXIT { m_send_object_id = 0; }; - - R_TRY(rdp.Finalize()); - - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(m_send_object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Lock the object as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write | FsOpenMode_Append, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - /* Truncate the file after locking for write. */ - s64 offset = 0; - R_TRY(m_fs.SetFileSize(std::addressof(file), 0)); - - /* Expand to the needed size. */ - if (data_header.length > sizeof(PtpUsbBulkContainer)) { - R_TRY(m_fs.SetFileSize(std::addressof(file), data_header.length - sizeof(PtpUsbBulkContainer))); - } - - /* Begin writing to the filesystem. */ - while (true) { - /* Read as many bytes as we can. */ - u32 bytes_received; - const Result read_res = dp.ReadBuffer(m_buffers->file_system_data_buffer, FsBufferSize, std::addressof(bytes_received)); - - /* Write to the file. */ - R_TRY(m_fs.WriteFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_received, 0)); - - offset += bytes_received; - - /* If we received fewer bytes than the batch size, we're done. */ - if (haze::ResultEndOfTransmission::Includes(read_res)) { - break; - } - - R_TRY(read_res); - } - - /* Truncate the file to the received size. */ - R_TRY(m_fs.SetFileSize(std::addressof(file), offset)); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::DeleteObject(PtpDataParser &dp) { - /* Get the object ID and flush the request packet. */ - u32 object_id; - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Finalize()); - - /* Disallow deleting the storage root. */ - R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Figure out what type of object this is. */ - FsDirEntryType entry_type; - R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); - - /* Remove the object from the filesystem. */ - if (entry_type == FsDirEntryType_Dir) { - R_TRY(m_fs.DeleteDirectoryRecursively(obj->GetName())); - } else { - R_TRY(m_fs.DeleteFile(obj->GetName())); - } - - /* Remove the object from the database. */ - m_object_database.DeleteObject(obj); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectPropsSupported(PtpDataParser &dp) { - R_TRY(dp.Finalize()); - - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - /* Write information about all object properties we can support. */ - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - R_RETURN(db.AddArray(SupportedObjectProperties, util::size(SupportedObjectProperties))); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectPropDesc(PtpDataParser &dp) { - PtpObjectPropertyCode property_code; - u16 object_format; - - R_TRY(dp.Read(std::addressof(property_code))); - R_TRY(dp.Read(std::addressof(object_format))); - R_TRY(dp.Finalize()); - - /* Ensure we have a valid property code before continuing. */ - R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); - - /* Begin writing information about the property code. */ - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - R_TRY(db.Add(property_code)); - - /* Each property code corresponds to a different pattern, which contains the data type, */ - /* whether the property can be set for an object, and the default value of the property. */ - switch (property_code) { - case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: - { - R_TRY(db.Add(PtpDataTypeCode_U128)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(0)); - } - case PtpObjectPropertyCode_ObjectSize: - { - R_TRY(db.Add(PtpDataTypeCode_U64)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(0)); - } - break; - case PtpObjectPropertyCode_StorageId: - case PtpObjectPropertyCode_ParentObject: - { - R_TRY(db.Add(PtpDataTypeCode_U32)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(StorageId_SdmcFs)); - } - break; - case PtpObjectPropertyCode_ObjectFormat: - { - R_TRY(db.Add(PtpDataTypeCode_U16)); - R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); - R_TRY(db.Add(PtpObjectFormatCode_Undefined)); - } - break; - case PtpObjectPropertyCode_ObjectFileName: - { - R_TRY(db.Add(PtpDataTypeCode_String)); - R_TRY(db.Add(PtpPropertyGetSetFlag_GetSet)); - R_TRY(db.AddString("")); - } - break; - HAZE_UNREACHABLE_DEFAULT_CASE(); - } - - /* Group code is a required part of the response, but doesn't seem to be used for anything. */ - R_TRY(db.Add(PtpPropertyGroupCode_Default)); - - /* We don't use the form flag. */ - R_TRY(db.Add(PtpPropertyFormFlag_None)); - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::GetObjectPropValue(PtpDataParser &dp) { - u32 object_id; - PtpObjectPropertyCode property_code; - - R_TRY(dp.Read(std::addressof(object_id))); - R_TRY(dp.Read(std::addressof(property_code))); - R_TRY(dp.Finalize()); - - /* Disallow renaming the storage root. */ - R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); - - /* Ensure we have a valid property code before continuing. */ - R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* Define helper for getting the object type. */ - const auto GetObjectType = [&] (FsDirEntryType *out_entry_type) { - R_RETURN(m_fs.GetEntryType(obj->GetName(), out_entry_type)); - }; - - /* Define helper for getting the object size. */ - const auto GetObjectSize = [&] (s64 *out_size) { - *out_size = 0; - - /* Check if this is a directory. */ - FsDirEntryType entry_type; - R_TRY(GetObjectType(std::addressof(entry_type))); - - /* If it is, we're done. */ - R_SUCCEED_IF(entry_type == FsDirEntryType_Dir); - - /* Otherwise, open as a file. */ - FsFile file; - R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); - - /* Ensure we maintain a clean state on exit. */ - ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; - - R_RETURN(m_fs.GetFileSize(std::addressof(file), out_size)); - }; - - /* Begin writing the requested object property. */ - PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); - - R_TRY(db.WriteVariableLengthData(m_request_header, [&] { - switch (property_code) { - case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: - { - R_TRY(db.Add(object_id)); - } - break; - case PtpObjectPropertyCode_ObjectSize: - { - s64 size; - R_TRY(GetObjectSize(std::addressof(size))); - R_TRY(db.Add(size)); - } - break; - case PtpObjectPropertyCode_StorageId: - { - R_TRY(db.Add(StorageId_SdmcFs)); - } - break; - case PtpObjectPropertyCode_ParentObject: - { - R_TRY(db.Add(obj->GetParentId())); - } - break; - case PtpObjectPropertyCode_ObjectFormat: - { - FsDirEntryType entry_type; - R_TRY(GetObjectType(std::addressof(entry_type))); - R_TRY(db.Add(entry_type == FsDirEntryType_File ? PtpObjectFormatCode_Undefined : PtpObjectFormatCode_Association)); - } - break; - case PtpObjectPropertyCode_ObjectFileName: - { - R_TRY(db.AddString(std::strrchr(obj->GetName(), '/') + 1)); - } - break; - HAZE_UNREACHABLE_DEFAULT_CASE(); - } - - R_SUCCEED(); - })); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } - - Result PtpResponder::SetObjectPropValue(PtpDataParser &rdp) { - u32 object_id; - PtpObjectPropertyCode property_code; - - R_TRY(rdp.Read(std::addressof(object_id))); - R_TRY(rdp.Read(std::addressof(property_code))); - R_TRY(rdp.Finalize()); - - PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); - - /* Ensure we have a data header. */ - PtpUsbBulkContainer data_header; - R_TRY(dp.Read(std::addressof(data_header))); - R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); - R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); - R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); - - /* Ensure we have a valid property code before continuing. */ - R_UNLESS(property_code == PtpObjectPropertyCode_ObjectFileName, haze::ResultUnknownPropertyCode()); - - /* Check if we know about the object. If we don't, it's an error. */ - auto * const obj = m_object_database.GetObjectById(object_id); - R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); - - /* We are reading a file name. */ - R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); - R_TRY(dp.Finalize()); - - /* Ensure we can actually process the new name. */ - const bool is_empty = m_buffers->filename_string_buffer[0] == '\x00'; - const bool contains_slashes = std::strchr(m_buffers->filename_string_buffer, '/') != nullptr; - R_UNLESS(!is_empty && !contains_slashes, haze::ResultInvalidPropertyValue()); - - /* Add a new object in the database with the new name. */ - PtpObject *newobj; - { - /* Find the last path separator in the existing object name. */ - char *pathsep = std::strrchr(obj->m_name, '/'); - HAZE_ASSERT(pathsep != nullptr); - - /* Temporarily mark the path separator as null to facilitate processing. */ - *pathsep = '\x00'; - ON_SCOPE_EXIT { *pathsep = '/'; }; - - R_TRY(m_object_database.CreateOrFindObject(obj->GetName(), m_buffers->filename_string_buffer, obj->GetParentId(), std::addressof(newobj))); - } - - { - /* Ensure we maintain a clean state on failure. */ - ON_RESULT_FAILURE { - if (!newobj->GetIsRegistered()) { - /* Only delete if the object was not registered. */ - /* Otherwise, we would remove an object that still exists. */ - m_object_database.DeleteObject(newobj); - } - }; - - /* Get the old object type. */ - FsDirEntryType entry_type; - R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); - - /* Attempt to rename the object on the filesystem. */ - if (entry_type == FsDirEntryType_Dir) { - R_TRY(m_fs.RenameDirectory(obj->GetName(), newobj->GetName())); - } else { - R_TRY(m_fs.RenameFile(obj->GetName(), newobj->GetName())); - } - } - - /* Unregister and free the old object. */ - m_object_database.DeleteObject(obj); - - /* Register the new object. */ - m_object_database.RegisterObject(newobj, object_id); - - /* Write the success response. */ - R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); - } } diff --git a/troposphere/haze/source/ptp_responder_mtp_operations.cpp b/troposphere/haze/source/ptp_responder_mtp_operations.cpp new file mode 100644 index 000000000..973aa98a1 --- /dev/null +++ b/troposphere/haze/source/ptp_responder_mtp_operations.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + +namespace haze { + + Result PtpResponder::GetObjectPropsSupported(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Write information about all object properties we can support. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + R_RETURN(db.AddArray(SupportedObjectProperties, util::size(SupportedObjectProperties))); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectPropDesc(PtpDataParser &dp) { + PtpObjectPropertyCode property_code; + u16 object_format; + + R_TRY(dp.Read(std::addressof(property_code))); + R_TRY(dp.Read(std::addressof(object_format))); + R_TRY(dp.Finalize()); + + /* Ensure we have a valid property code before continuing. */ + R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); + + /* Begin writing information about the property code. */ + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + R_TRY(db.Add(property_code)); + + /* Each property code corresponds to a different pattern, which contains the data type, */ + /* whether the property can be set for an object, and the default value of the property. */ + switch (property_code) { + case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: + { + R_TRY(db.Add(PtpDataTypeCode_U128)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(0)); + } + case PtpObjectPropertyCode_ObjectSize: + { + R_TRY(db.Add(PtpDataTypeCode_U64)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(0)); + } + break; + case PtpObjectPropertyCode_StorageId: + case PtpObjectPropertyCode_ParentObject: + { + R_TRY(db.Add(PtpDataTypeCode_U32)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(StorageId_SdmcFs)); + } + break; + case PtpObjectPropertyCode_ObjectFormat: + { + R_TRY(db.Add(PtpDataTypeCode_U16)); + R_TRY(db.Add(PtpPropertyGetSetFlag_Get)); + R_TRY(db.Add(PtpObjectFormatCode_Undefined)); + } + break; + case PtpObjectPropertyCode_ObjectFileName: + { + R_TRY(db.Add(PtpDataTypeCode_String)); + R_TRY(db.Add(PtpPropertyGetSetFlag_GetSet)); + R_TRY(db.AddString("")); + } + break; + HAZE_UNREACHABLE_DEFAULT_CASE(); + } + + /* Group code is a required part of the response, but doesn't seem to be used for anything. */ + R_TRY(db.Add(PtpPropertyGroupCode_Default)); + + /* We don't use the form flag. */ + R_TRY(db.Add(PtpPropertyFormFlag_None)); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectPropValue(PtpDataParser &dp) { + u32 object_id; + PtpObjectPropertyCode property_code; + + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Read(std::addressof(property_code))); + R_TRY(dp.Finalize()); + + /* Disallow renaming the storage root. */ + R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); + + /* Ensure we have a valid property code before continuing. */ + R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Define helper for getting the object type. */ + const auto GetObjectType = [&] (FsDirEntryType *out_entry_type) { + R_RETURN(m_fs.GetEntryType(obj->GetName(), out_entry_type)); + }; + + /* Define helper for getting the object size. */ + const auto GetObjectSize = [&] (s64 *out_size) { + *out_size = 0; + + /* Check if this is a directory. */ + FsDirEntryType entry_type; + R_TRY(GetObjectType(std::addressof(entry_type))); + + /* If it is, we're done. */ + R_SUCCEED_IF(entry_type == FsDirEntryType_Dir); + + /* Otherwise, open as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + R_RETURN(m_fs.GetFileSize(std::addressof(file), out_size)); + }; + + /* Begin writing the requested object property. */ + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + switch (property_code) { + case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: + { + R_TRY(db.Add(object_id)); + } + break; + case PtpObjectPropertyCode_ObjectSize: + { + s64 size; + R_TRY(GetObjectSize(std::addressof(size))); + R_TRY(db.Add(size)); + } + break; + case PtpObjectPropertyCode_StorageId: + { + R_TRY(db.Add(StorageId_SdmcFs)); + } + break; + case PtpObjectPropertyCode_ParentObject: + { + R_TRY(db.Add(obj->GetParentId())); + } + break; + case PtpObjectPropertyCode_ObjectFormat: + { + FsDirEntryType entry_type; + R_TRY(GetObjectType(std::addressof(entry_type))); + R_TRY(db.Add(entry_type == FsDirEntryType_File ? PtpObjectFormatCode_Undefined : PtpObjectFormatCode_Association)); + } + break; + case PtpObjectPropertyCode_ObjectFileName: + { + R_TRY(db.AddString(std::strrchr(obj->GetName(), '/') + 1)); + } + break; + HAZE_UNREACHABLE_DEFAULT_CASE(); + } + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::SetObjectPropValue(PtpDataParser &rdp) { + u32 object_id; + PtpObjectPropertyCode property_code; + + R_TRY(rdp.Read(std::addressof(object_id))); + R_TRY(rdp.Read(std::addressof(property_code))); + R_TRY(rdp.Finalize()); + + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Ensure we have a valid property code before continuing. */ + R_UNLESS(property_code == PtpObjectPropertyCode_ObjectFileName, haze::ResultUnknownPropertyCode()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* We are reading a file name. */ + R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); + R_TRY(dp.Finalize()); + + /* Ensure we can actually process the new name. */ + const bool is_empty = m_buffers->filename_string_buffer[0] == '\x00'; + const bool contains_slashes = std::strchr(m_buffers->filename_string_buffer, '/') != nullptr; + R_UNLESS(!is_empty && !contains_slashes, haze::ResultInvalidPropertyValue()); + + /* Add a new object in the database with the new name. */ + PtpObject *newobj; + { + /* Find the last path separator in the existing object name. */ + char *pathsep = std::strrchr(obj->m_name, '/'); + HAZE_ASSERT(pathsep != nullptr); + + /* Temporarily mark the path separator as null to facilitate processing. */ + *pathsep = '\x00'; + ON_SCOPE_EXIT { *pathsep = '/'; }; + + R_TRY(m_object_database.CreateOrFindObject(obj->GetName(), m_buffers->filename_string_buffer, obj->GetParentId(), std::addressof(newobj))); + } + + { + /* Ensure we maintain a clean state on failure. */ + ON_RESULT_FAILURE { + if (!newobj->GetIsRegistered()) { + /* Only delete if the object was not registered. */ + /* Otherwise, we would remove an object that still exists. */ + m_object_database.DeleteObject(newobj); + } + }; + + /* Get the old object type. */ + FsDirEntryType entry_type; + R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); + + /* Attempt to rename the object on the filesystem. */ + if (entry_type == FsDirEntryType_Dir) { + R_TRY(m_fs.RenameDirectory(obj->GetName(), newobj->GetName())); + } else { + R_TRY(m_fs.RenameFile(obj->GetName(), newobj->GetName())); + } + } + + /* Unregister and free the old object. */ + m_object_database.DeleteObject(obj); + + /* Register the new object. */ + m_object_database.RegisterObject(newobj, object_id); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + +} diff --git a/troposphere/haze/source/ptp_responder_ptp_operations.cpp b/troposphere/haze/source/ptp_responder_ptp_operations.cpp new file mode 100644 index 000000000..4213a5061 --- /dev/null +++ b/troposphere/haze/source/ptp_responder_ptp_operations.cpp @@ -0,0 +1,507 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + +namespace haze { + + Result PtpResponder::GetDeviceInfo(PtpDataParser &dp) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Write the device info data. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { + R_TRY(db.Add(MtpStandardVersion)); + R_TRY(db.Add(MtpVendorExtensionId)); + R_TRY(db.Add(MtpStandardVersion)); + R_TRY(db.AddString(MtpVendorExtensionDesc)); + R_TRY(db.Add(MtpFunctionalModeDefault)); + R_TRY(db.AddArray(SupportedOperationCodes, util::size(SupportedOperationCodes))); + R_TRY(db.AddArray(SupportedEventCodes, util::size(SupportedEventCodes))); + R_TRY(db.AddArray(SupportedDeviceProperties, util::size(SupportedDeviceProperties))); + R_TRY(db.AddArray(SupportedCaptureFormats, util::size(SupportedCaptureFormats))); + R_TRY(db.AddArray(SupportedPlaybackFormats, util::size(SupportedPlaybackFormats))); + R_TRY(db.AddString(MtpDeviceManufacturer)); + R_TRY(db.AddString(MtpDeviceModel)); + R_TRY(db.AddString(GetFirmwareVersion())); + R_TRY(db.AddString(GetSerialNumber())); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::OpenSession(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + /* Close, if we're already open. */ + this->ForceCloseSession(); + + /* Initialize the database. */ + m_session_open = true; + m_object_database.Initialize(m_object_heap); + + /* Create the root storages. */ + PtpObject *object; + R_TRY(m_object_database.CreateOrFindObject("", "", PtpGetObjectHandles_RootParent, std::addressof(object))); + + /* Register the root storages. */ + m_object_database.RegisterObject(object, StorageId_SdmcFs); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::CloseSession(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + this->ForceCloseSession(); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetStorageIds(PtpDataParser &dp) { + R_TRY(dp.Finalize()); + + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Write the storage ID array. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + R_RETURN(db.AddArray(SupportedStorageIds, util::size(SupportedStorageIds))); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetStorageInfo(PtpDataParser &dp) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + PtpStorageInfo storage_info(DefaultStorageInfo); + + /* Get the storage ID the client requested information for. */ + u32 storage_id; + R_TRY(dp.Read(std::addressof(storage_id))); + R_TRY(dp.Finalize()); + + /* Get the info from fs. */ + switch (storage_id) { + case StorageId_SdmcFs: + { + s64 total_space, free_space; + R_TRY(m_fs.GetTotalSpace("/", std::addressof(total_space))); + R_TRY(m_fs.GetFreeSpace("/", std::addressof(free_space))); + + storage_info.max_capacity = total_space; + storage_info.free_space_in_bytes = free_space; + storage_info.free_space_in_images = 0; + storage_info.storage_description = "SD Card"; + } + break; + default: + R_THROW(haze::ResultInvalidStorageId()); + } + + /* Write the storage info data. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { + R_TRY(db.Add(storage_info.storage_type)); + R_TRY(db.Add(storage_info.filesystem_type)); + R_TRY(db.Add(storage_info.access_capability)); + R_TRY(db.Add(storage_info.max_capacity)); + R_TRY(db.Add(storage_info.free_space_in_bytes)); + R_TRY(db.Add(storage_info.free_space_in_images)); + R_TRY(db.AddString(storage_info.storage_description)); + R_TRY(db.AddString(storage_info.volume_label)); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectHandles(PtpDataParser &dp) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID the client requested enumeration for. */ + u32 storage_id, object_format_code, association_object_handle; + R_TRY(dp.Read(std::addressof(storage_id))); + R_TRY(dp.Read(std::addressof(object_format_code))); + R_TRY(dp.Read(std::addressof(association_object_handle))); + R_TRY(dp.Finalize()); + + /* Handle top-level requests. */ + if (storage_id == PtpGetObjectHandles_AllStorage) { + storage_id = StorageId_SdmcFs; + } + + /* Rewrite requests for enumerating storage directories. */ + if (association_object_handle == PtpGetObjectHandles_RootParent) { + association_object_handle = storage_id; + } + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(association_object_handle); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Try to read the object as a directory. */ + FsDir dir; + R_TRY(m_fs.OpenDirectory(obj->GetName(), FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles, std::addressof(dir))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseDirectory(std::addressof(dir)); }; + + /* Count how many entries are in the directory. */ + s64 entry_count = 0; + R_TRY(m_fs.GetDirectoryEntryCount(std::addressof(dir), std::addressof(entry_count))); + + /* Begin writing. */ + R_TRY(db.AddDataHeader(m_request_header, sizeof(u32) + (entry_count * sizeof(u32)))); + R_TRY(db.Add(static_cast(entry_count))); + + /* Enumerate the directory, writing results to the data builder as we progress. */ + /* TODO: How should we handle the directory contents changing during enumeration? */ + /* Is this even feasible to handle? */ + while (true) { + /* Get the next batch. */ + s64 read_count = 0; + R_TRY(m_fs.ReadDirectory(std::addressof(dir), std::addressof(read_count), DirectoryReadSize, m_buffers->file_system_entry_buffer)); + + /* Write to output. */ + for (s64 i = 0; i < read_count; i++) { + const char *name = m_buffers->file_system_entry_buffer[i].name; + u32 handle; + + R_TRY(m_object_database.CreateAndRegisterObjectId(obj->GetName(), name, obj->GetObjectId(), std::addressof(handle))); + R_TRY(db.Add(handle)); + } + + /* If we read fewer than the batch size, we're done. */ + if (read_count < DirectoryReadSize) { + break; + } + } + + /* Flush the data response. */ + R_TRY(db.Commit()); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObjectInfo(PtpDataParser &dp) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID the client requested info for. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Build info about the object. */ + PtpObjectInfo object_info(DefaultObjectInfo); + + if (object_id == StorageId_SdmcFs) { + /* The SD Card directory has some special properties. */ + object_info.object_format = PtpObjectFormatCode_Association; + object_info.association_type = PtpAssociationType_GenericFolder; + object_info.filename = "SD Card"; + } else { + /* Figure out what type of object this is. */ + FsDirEntryType entry_type; + R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); + + /* Get the size, if we are requesting info about a file. */ + s64 size = 0; + if (entry_type == FsDirEntryType_File) { + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); + } + + object_info.filename = std::strrchr(obj->GetName(), '/') + 1; + object_info.object_compressed_size = size; + object_info.parent_object = obj->GetParentId(); + + if (entry_type == FsDirEntryType_Dir) { + object_info.object_format = PtpObjectFormatCode_Association; + object_info.association_type = PtpAssociationType_GenericFolder; + } else { + object_info.object_format = PtpObjectFormatCode_Undefined; + object_info.association_type = PtpAssociationType_Undefined; + } + } + + /* Write the object info data. */ + R_TRY(db.WriteVariableLengthData(m_request_header, [&] () { + R_TRY(db.Add(object_info.storage_id)); + R_TRY(db.Add(object_info.object_format)); + R_TRY(db.Add(object_info.protection_status)); + R_TRY(db.Add(object_info.object_compressed_size)); + R_TRY(db.Add(object_info.thumb_format)); + R_TRY(db.Add(object_info.thumb_compressed_size)); + R_TRY(db.Add(object_info.thumb_width)); + R_TRY(db.Add(object_info.thumb_height)); + R_TRY(db.Add(object_info.image_width)); + R_TRY(db.Add(object_info.image_height)); + R_TRY(db.Add(object_info.image_depth)); + R_TRY(db.Add(object_info.parent_object)); + R_TRY(db.Add(object_info.association_type)); + R_TRY(db.Add(object_info.association_desc)); + R_TRY(db.Add(object_info.sequence_number)); + R_TRY(db.AddString(object_info.filename)); + R_TRY(db.AddString(object_info.capture_date)); + R_TRY(db.AddString(object_info.modification_date)); + R_TRY(db.AddString(object_info.keywords)); + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::GetObject(PtpDataParser &dp) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID the client requested. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Get the file's size. */ + s64 size = 0; + R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(size))); + + /* Send the header and file size. */ + R_TRY(db.AddDataHeader(m_request_header, size)); + + /* Begin reading the file, writing data to the builder as we progress. */ + s64 offset = 0; + while (true) { + /* Get the next batch. */ + u64 bytes_read; + R_TRY(m_fs.ReadFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, FsBufferSize, FsReadOption_None, std::addressof(bytes_read))); + + offset += bytes_read; + + /* Write to output. */ + R_TRY(db.AddBuffer(m_buffers->file_system_data_buffer, bytes_read)); + + /* If we read fewer bytes than the batch size, we're done. */ + if (bytes_read < FsBufferSize) { + break; + } + } + + /* Flush the data response. */ + R_TRY(db.Commit()); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::SendObjectInfo(PtpDataParser &rdp) { + /* Get the storage ID and parent object and flush the request packet. */ + u32 storage_id, parent_object; + R_TRY(rdp.Read(std::addressof(storage_id))); + R_TRY(rdp.Read(std::addressof(parent_object))); + R_TRY(rdp.Finalize()); + + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); + PtpObjectInfo info(DefaultObjectInfo); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Read in the object info. */ + R_TRY(dp.Read(std::addressof(info.storage_id))); + R_TRY(dp.Read(std::addressof(info.object_format))); + R_TRY(dp.Read(std::addressof(info.protection_status))); + R_TRY(dp.Read(std::addressof(info.object_compressed_size))); + R_TRY(dp.Read(std::addressof(info.thumb_format))); + R_TRY(dp.Read(std::addressof(info.thumb_compressed_size))); + R_TRY(dp.Read(std::addressof(info.thumb_width))); + R_TRY(dp.Read(std::addressof(info.thumb_height))); + R_TRY(dp.Read(std::addressof(info.image_width))); + R_TRY(dp.Read(std::addressof(info.image_height))); + R_TRY(dp.Read(std::addressof(info.image_depth))); + R_TRY(dp.Read(std::addressof(info.parent_object))); + R_TRY(dp.Read(std::addressof(info.association_type))); + R_TRY(dp.Read(std::addressof(info.association_desc))); + R_TRY(dp.Read(std::addressof(info.sequence_number))); + R_TRY(dp.ReadString(m_buffers->filename_string_buffer)); + R_TRY(dp.ReadString(m_buffers->capture_date_string_buffer)); + R_TRY(dp.ReadString(m_buffers->modification_date_string_buffer)); + R_TRY(dp.ReadString(m_buffers->keywords_string_buffer)); + R_TRY(dp.Finalize()); + + /* Rewrite requests for creating in storage directories. */ + if (parent_object == PtpGetObjectHandles_RootParent) { + parent_object = storage_id; + } + + /* Check if we know about the parent object. If we don't, it's an error. */ + auto * const parentobj = m_object_database.GetObjectById(parent_object); + R_UNLESS(parentobj != nullptr, haze::ResultInvalidObjectId()); + + /* Make a new object with the intended name. */ + PtpNewObjectInfo new_object_info; + new_object_info.storage_id = StorageId_SdmcFs; + new_object_info.parent_object_id = parent_object == storage_id ? 0 : parent_object; + + /* Create the object in the database. */ + PtpObject *obj; + R_TRY(m_object_database.CreateOrFindObject(parentobj->GetName(), m_buffers->filename_string_buffer, parentobj->GetObjectId(), std::addressof(obj))); + + /* Ensure we maintain a clean state on failure. */ + ON_RESULT_FAILURE { m_object_database.DeleteObject(obj); }; + + /* Register the object with a new ID. */ + m_object_database.RegisterObject(obj); + new_object_info.object_id = obj->GetObjectId(); + + /* Create the object on the filesystem. */ + if (info.object_format == PtpObjectFormatCode_Association) { + R_TRY(m_fs.CreateDirectory(obj->GetName())); + m_send_object_id = 0; + } else { + R_TRY(m_fs.CreateFile(obj->GetName(), 0, 0)); + m_send_object_id = new_object_info.object_id; + } + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok, new_object_info)); + } + + Result PtpResponder::SendObject(PtpDataParser &rdp) { + /* Reset SendObject object ID on exit. */ + ON_SCOPE_EXIT { m_send_object_id = 0; }; + + R_TRY(rdp.Finalize()); + + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(m_send_object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write | FsOpenMode_Append, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Truncate the file after locking for write. */ + s64 offset = 0; + R_TRY(m_fs.SetFileSize(std::addressof(file), 0)); + + /* Expand to the needed size. */ + if (data_header.length > sizeof(PtpUsbBulkContainer)) { + R_TRY(m_fs.SetFileSize(std::addressof(file), data_header.length - sizeof(PtpUsbBulkContainer))); + } + + /* Begin writing to the filesystem. */ + while (true) { + /* Read as many bytes as we can. */ + u32 bytes_received; + const Result read_res = dp.ReadBuffer(m_buffers->file_system_data_buffer, FsBufferSize, std::addressof(bytes_received)); + + /* Write to the file. */ + R_TRY(m_fs.WriteFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_received, 0)); + + offset += bytes_received; + + /* If we received fewer bytes than the batch size, we're done. */ + if (haze::ResultEndOfTransmission::Includes(read_res)) { + break; + } + + R_TRY(read_res); + } + + /* Truncate the file to the received size. */ + R_TRY(m_fs.SetFileSize(std::addressof(file), offset)); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::DeleteObject(PtpDataParser &dp) { + /* Get the object ID and flush the request packet. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Disallow deleting the storage root. */ + R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Figure out what type of object this is. */ + FsDirEntryType entry_type; + R_TRY(m_fs.GetEntryType(obj->GetName(), std::addressof(entry_type))); + + /* Remove the object from the filesystem. */ + if (entry_type == FsDirEntryType_Dir) { + R_TRY(m_fs.DeleteDirectoryRecursively(obj->GetName())); + } else { + R_TRY(m_fs.DeleteFile(obj->GetName())); + } + + /* Remove the object from the database. */ + m_object_database.DeleteObject(obj); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + +} From 92a8c8eb8852d7db73e2d7d27b2ea6cbacc63302 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 1 Sep 2023 20:55:22 -0400 Subject: [PATCH 004/238] haze: implement android operations --- troposphere/haze/include/haze/ptp.hpp | 5 + .../haze/include/haze/ptp_responder.hpp | 7 + .../haze/include/haze/ptp_responder_types.hpp | 5 + troposphere/haze/include/haze/results.hpp | 1 + troposphere/haze/source/ptp_responder.cpp | 10 +- .../ptp_responder_android_operations.cpp | 203 ++++++++++++++++++ 6 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 troposphere/haze/source/ptp_responder_android_operations.cpp diff --git a/troposphere/haze/include/haze/ptp.hpp b/troposphere/haze/include/haze/ptp.hpp index 771b126ce..beca16842 100644 --- a/troposphere/haze/include/haze/ptp.hpp +++ b/troposphere/haze/include/haze/ptp.hpp @@ -72,6 +72,11 @@ namespace haze { PtpOperationCode_GetFilesystemManifest = 0x1023, PtpOperationCode_GetStreamInfo = 0x1024, PtpOperationCode_GetStream = 0x1025, + PtpOperationCode_AndroidGetPartialObject64 = 0x95c1, + PtpOperationCode_AndroidSendPartialObject = 0x95c2, + PtpOperationCode_AndroidTruncateObject = 0x95c3, + PtpOperationCode_AndroidBeginEditObject = 0x95c4, + PtpOperationCode_AndroidEndEditObject = 0x95c5, PtpOperationCode_MtpGetObjectPropsSupported = 0x9801, PtpOperationCode_MtpGetObjectPropDesc = 0x9802, PtpOperationCode_MtpGetObjectPropValue = 0x9803, diff --git a/troposphere/haze/include/haze/ptp_responder.hpp b/troposphere/haze/include/haze/ptp_responder.hpp index 7f1b177eb..9bd1328e5 100644 --- a/troposphere/haze/include/haze/ptp_responder.hpp +++ b/troposphere/haze/include/haze/ptp_responder.hpp @@ -71,6 +71,13 @@ namespace haze { Result SendObject(PtpDataParser &dp); Result DeleteObject(PtpDataParser &dp); + /* Android operations. */ + Result GetPartialObject64(PtpDataParser &dp); + Result SendPartialObject(PtpDataParser &dp); + Result TruncateObject(PtpDataParser &dp); + Result BeginEditObject(PtpDataParser &dp); + Result EndEditObject(PtpDataParser &dp); + /* MTP operations. */ Result GetObjectPropsSupported(PtpDataParser &dp); Result GetObjectPropDesc(PtpDataParser &dp); diff --git a/troposphere/haze/include/haze/ptp_responder_types.hpp b/troposphere/haze/include/haze/ptp_responder_types.hpp index 3e307f9d3..d11416437 100644 --- a/troposphere/haze/include/haze/ptp_responder_types.hpp +++ b/troposphere/haze/include/haze/ptp_responder_types.hpp @@ -57,6 +57,11 @@ namespace haze { PtpOperationCode_MtpGetObjectPropDesc, PtpOperationCode_MtpGetObjectPropValue, PtpOperationCode_MtpSetObjectPropValue, + PtpOperationCode_AndroidGetPartialObject64, + PtpOperationCode_AndroidSendPartialObject, + PtpOperationCode_AndroidTruncateObject, + PtpOperationCode_AndroidBeginEditObject, + PtpOperationCode_AndroidEndEditObject, }; constexpr const PtpEventCode SupportedEventCodes[] = { /* ... */ }; diff --git a/troposphere/haze/include/haze/results.hpp b/troposphere/haze/include/haze/results.hpp index fec0e84de..e8c501ffc 100644 --- a/troposphere/haze/include/haze/results.hpp +++ b/troposphere/haze/include/haze/results.hpp @@ -37,5 +37,6 @@ namespace haze { R_DEFINE_ERROR_RESULT(UnknownRequestType, 13); R_DEFINE_ERROR_RESULT(UnknownPropertyCode, 14); R_DEFINE_ERROR_RESULT(InvalidPropertyValue, 15); + R_DEFINE_ERROR_RESULT(InvalidArgument, 16); } diff --git a/troposphere/haze/source/ptp_responder.cpp b/troposphere/haze/source/ptp_responder.cpp index ffba26229..ad8d4abb8 100644 --- a/troposphere/haze/source/ptp_responder.cpp +++ b/troposphere/haze/source/ptp_responder.cpp @@ -22,7 +22,7 @@ namespace haze { namespace { - PtpBuffers* GetBuffers() { + PtpBuffers *GetBuffers() { static constinit PtpBuffers buffers = {}; return std::addressof(buffers); } @@ -91,6 +91,9 @@ namespace haze { R_CATCH(haze::ResultInvalidPropertyValue) { R_TRY(this->WriteResponse(PtpResponseCode_MtpInvalidObjectPropValue)); } + R_CATCH(haze::ResultInvalidArgument) { + R_TRY(this->WriteResponse(PtpResponseCode_GeneralError)); + } R_CATCH_MODULE(fs) { /* Errors from fs are typically recoverable. */ R_TRY(this->WriteResponse(PtpResponseCode_GeneralError)); @@ -131,6 +134,11 @@ namespace haze { case PtpOperationCode_MtpGetObjectPropDesc: R_RETURN(this->GetObjectPropDesc(dp)); break; case PtpOperationCode_MtpGetObjectPropValue: R_RETURN(this->GetObjectPropValue(dp)); break; case PtpOperationCode_MtpSetObjectPropValue: R_RETURN(this->SetObjectPropValue(dp)); break; + case PtpOperationCode_AndroidGetPartialObject64: R_RETURN(this->GetPartialObject64(dp)); break; + case PtpOperationCode_AndroidSendPartialObject: R_RETURN(this->SendPartialObject(dp)); break; + case PtpOperationCode_AndroidTruncateObject: R_RETURN(this->TruncateObject(dp)); break; + case PtpOperationCode_AndroidBeginEditObject: R_RETURN(this->BeginEditObject(dp)); break; + case PtpOperationCode_AndroidEndEditObject: R_RETURN(this->EndEditObject(dp)); break; default: R_THROW(haze::ResultOperationNotSupported()); } } diff --git a/troposphere/haze/source/ptp_responder_android_operations.cpp b/troposphere/haze/source/ptp_responder_android_operations.cpp new file mode 100644 index 000000000..aef13011e --- /dev/null +++ b/troposphere/haze/source/ptp_responder_android_operations.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include +#include + +namespace haze { + + Result PtpResponder::GetPartialObject64(PtpDataParser &dp) { + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + /* Get the object ID, offset, and size for the file we want to read. */ + u32 object_id, size; + u64 offset; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Read(std::addressof(offset))); + R_TRY(dp.Read(std::addressof(size))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Get the file's size. */ + s64 file_size = 0; + R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(file_size))); + + /* Ensure the requested offset and size are within range. */ + R_UNLESS(offset + size > offset, haze::ResultInvalidArgument()); + R_UNLESS(static_cast(file_size) <= offset + size, haze::ResultInvalidArgument()); + + /* Send the header and data size. */ + R_TRY(db.AddDataHeader(m_request_header, size)); + + /* Begin reading the file, writing data to the builder as we progress. */ + s64 size_remaining = size; + while (true) { + /* Get the next batch. */ + u64 bytes_to_read = std::min(FsBufferSize, size_remaining); + u64 bytes_read; + + R_TRY(m_fs.ReadFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_to_read, FsReadOption_None, std::addressof(bytes_read))); + + size_remaining -= bytes_read; + offset += bytes_read; + + /* Write to output. */ + R_TRY(db.AddBuffer(m_buffers->file_system_data_buffer, bytes_read)); + + /* If we read fewer bytes than the batch size, or have read enough data, we're done. */ + if (bytes_read < FsBufferSize || size_remaining == 0) { + break; + } + } + + /* Flush the data response. */ + R_TRY(db.Commit()); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::SendPartialObject(PtpDataParser &rdp) { + /* Get the object ID, offset, and size for the file we want to write. */ + u32 object_id, size; + u64 offset; + R_TRY(rdp.Read(std::addressof(object_id))); + R_TRY(rdp.Read(std::addressof(size))); + R_TRY(rdp.Read(std::addressof(offset))); + R_TRY(rdp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(m_send_object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write | FsOpenMode_Append, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Get the file's size. */ + s64 file_size = 0; + R_TRY(m_fs.GetFileSize(std::addressof(file), std::addressof(file_size))); + + /* Ensure the requested offset and size are within range. */ + R_UNLESS(offset + size > offset, haze::ResultInvalidArgument()); + R_UNLESS(static_cast(file_size) <= offset, haze::ResultInvalidArgument()); + + /* Prepare a data parser for the data we are about to receive. */ + PtpDataParser dp(m_buffers->usb_bulk_read_buffer, std::addressof(m_usb_server)); + + /* Ensure we have a data header. */ + PtpUsbBulkContainer data_header; + R_TRY(dp.Read(std::addressof(data_header))); + R_UNLESS(data_header.type == PtpUsbBulkContainerType_Data, haze::ResultUnknownRequestType()); + R_UNLESS(data_header.code == m_request_header.code, haze::ResultOperationNotSupported()); + R_UNLESS(data_header.trans_id == m_request_header.trans_id, haze::ResultOperationNotSupported()); + + /* Begin writing to the filesystem. */ + s64 size_remaining = size; + while (true) { + /* Read as many bytes as we can. */ + u32 bytes_received; + const Result read_res = dp.ReadBuffer(m_buffers->file_system_data_buffer, FsBufferSize, std::addressof(bytes_received)); + + /* Write to the file. */ + u32 bytes_to_write = std::min(size_remaining, bytes_received); + R_TRY(m_fs.WriteFile(std::addressof(file), offset, m_buffers->file_system_data_buffer, bytes_to_write, 0)); + + size_remaining -= bytes_to_write; + offset += bytes_to_write; + + /* If we received fewer bytes than the batch size, or have written enough data, we're done. */ + if (haze::ResultEndOfTransmission::Includes(read_res) || size_remaining == 0) { + break; + } + + R_TRY(read_res); + } + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::TruncateObject(PtpDataParser &dp) { + /* Get the object ID and size for the file we want to truncate. */ + u32 object_id; + u64 size; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Read(std::addressof(size))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Lock the object as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Write, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + /* Truncate the file. */ + R_TRY(m_fs.SetFileSize(std::addressof(file), size)); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::BeginEditObject(PtpDataParser &dp) { + /* Get the object ID we are going to begin editing. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* We don't implement transactions, so write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + Result PtpResponder::EndEditObject(PtpDataParser &dp) { + /* Get the object ID we are going to finish editing. */ + u32 object_id; + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Finalize()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* We don't implement transactions, so write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + + +} From 159f8d384b453d310a39c189d22196eea2267b22 Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 11 Oct 2023 17:51:27 -0400 Subject: [PATCH 005/238] dmnt.gen2: enable attach to arbitrary program id --- .../include/stratosphere/pm/pm_dmnt_api.hpp | 1 + .../libstratosphere/source/pm/pm_dmnt_api.cpp | 7 +++++++ .../source/dmnt2_gdb_server_impl.cpp | 19 +++++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp index 7a896ae66..4a5d53fa0 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_dmnt_api.hpp @@ -28,6 +28,7 @@ namespace ams::pm::dmnt { Result GetProcessId(os::ProcessId *out_process_id, const ncm::ProgramId program_id); Result GetApplicationProcessId(os::ProcessId *out_process_id); Result HookToCreateApplicationProcess(os::NativeHandle *out_handle); + Result HookToCreateProcess(os::NativeHandle *out_handle, const ncm::ProgramId program_id); Result AtmosphereGetProcessInfo(os::NativeHandle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); #if defined(ATMOSPHERE_OS_HORIZON) diff --git a/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp b/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp index 2eed37653..559e21475 100644 --- a/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp +++ b/libraries/libstratosphere/source/pm/pm_dmnt_api.cpp @@ -44,6 +44,13 @@ namespace ams::pm::dmnt { R_SUCCEED(); } + Result HookToCreateProcess(os::NativeHandle *out_handle, const ncm::ProgramId program_id) { + Event evt; + R_TRY(pmdmntHookToCreateProcess(std::addressof(evt), static_cast(program_id))); + *out_handle = evt.revent; + R_SUCCEED(); + } + Result AtmosphereGetProcessInfo(os::NativeHandle *out_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { *out_handle = os::InvalidNativeHandle; *out_loc = {}; diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp index 379687bde..ddb0d8fbc 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp @@ -2105,9 +2105,24 @@ namespace ams::dmnt { ParsePrefix(command, "0x"); /* Decode program id. */ - const u64 program_id = DecodeHex(command); + const ncm::ProgramId program_id(DecodeHex(command)); - AppendReplyFormat(reply_cur, reply_end, "[TODO] wait for program id 0x%lx\n", program_id); + /* Wait for the process to be created. */ + { + /* Get hook to creation of process with program id. */ + os::NativeHandle h; + R_ABORT_UNLESS(pm::dmnt::HookToCreateProcess(std::addressof(h), program_id)); + + /* Wait for event. */ + os::SystemEvent hook_event(h, true, os::InvalidNativeHandle, false, os::EventClearMode_AutoClear); + hook_event.Wait(); + } + + /* Get process id. */ + R_ABORT_UNLESS(pm::dmnt::GetProcessId(std::addressof(m_wait_process_id), program_id)); + + /* Note that we're attaching. */ + AppendReplyFormat(reply_cur, reply_end, "Send `attach 0x%lx` to attach.\n", m_wait_process_id.value); } else { std::memcpy(m_reply_cur, command, std::strlen(command) + 1); AppendReplyFormat(reply_cur, reply_end, "Unknown command `%s`\n", m_reply_cur); From add4b3fdc324e4e0f90075c6134f22ce6d86dca9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 10 Oct 2023 22:45:59 -0700 Subject: [PATCH 006/238] utils: update erpt script --- utilities/erpt.py | 84 +++-- utilities/nxo64.py | 823 ++++++++++++++++++++++++++++++++------------- 2 files changed, 649 insertions(+), 258 deletions(-) diff --git a/utilities/erpt.py b/utilities/erpt.py index 3920a3d98..12739661b 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -61,6 +61,9 @@ else: DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, DT_SYMBOLIC, DT_REL, DT_RELSZ, DT_RELENT, DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL, DT_BIND_NOW, DT_INIT_ARRAY, DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = iter_range(31) + +DT_RELRSZ, DT_RELR, DT_RELRENT = 0x23, 0x24, 0x25 + DT_GNU_HASH = 0x6ffffef5 DT_VERSYM = 0x6ffffff0 DT_RELACOUNT = 0x6ffffff9 @@ -84,6 +87,8 @@ R_ARM_GLOB_DAT = 21 R_ARM_JUMP_SLOT = 22 R_ARM_RELATIVE = 23 +R_FAKE_RELR = -1 + R_AARCH64_ABS64 = 257 R_AARCH64_GLOB_DAT = 1025 R_AARCH64_JUMP_SLOT = 1026 @@ -231,6 +236,8 @@ CATEGORIES = { 137 : 'BuiltInWirelessOUIInfo', 138 : 'WirelessAPOUIInfo', 139 : 'EthernetAdapterOUIInfo', + 140 : 'NANDTypeInfo', + 141 : 'MicroSDTypeInfo', } FIELD_TYPES = { @@ -258,15 +265,7 @@ FIELD_FLAGS = { } def get_full(nxo): - full = nxo.text[0] - if nxo.ro[2] >= len(full): - full += b'\x00' * (nxo.ro[2] - len(full)) - else: - full = full[:nxo.ro[2]] - full += nxo.ro[0] - if nxo.data[2] > len(full): - full += b'\x00' * (nxo.data[2] - len(full)) - full += nxo.data[0] + full = nxo.full[:] undef_count = 0 for s in nxo.symbols: @@ -303,6 +302,8 @@ def get_full(nxo): return z[:target] + pk(' compressed_size - compressed = compressed[len(compressed) - compressed_size:] - if not (compressed_size + uncompressed_addl_size): - return b'' - compressed = bytes_to_list(compressed) - decompressed = bytes_to_list(decompressed) - index = compressed_size - init_index - outindex = decompressed_size - while outindex > 0: - index -= 1 - control = compressed[index] - for i in iter_range(8): - if control & 0x80: - if index < 2: - raise ValueError('Compression out of bounds!') - index -= 2 - segmentoffset = compressed[index] | (compressed[index+1] << 8) - segmentsize = ((segmentoffset >> 12) & 0xF) + 3 - segmentoffset &= 0x0FFF - segmentoffset += 2 - if outindex < segmentsize: - raise ValueError('Compression out of bounds!') - for j in iter_range(segmentsize): - if outindex + segmentoffset >= decompressed_size: - raise ValueError('Compression out of bounds!') - data = decompressed[outindex+segmentoffset] - outindex -= 1 - decompressed[outindex] = data - else: - if outindex < 1: - raise ValueError('Compression out of bounds!') - outindex -= 1 - index -= 1 - decompressed[outindex] = compressed[index] - control <<= 1 - control &= 0xFF - if not outindex: - break - return list_to_bytes(decompressed) +def get_file_size(f): + filesize = 0 + try: + filesize = f.size() + except: + ptell = f.tell() + f.seek(0, 2) + filesize = f.tell() + f.seek(ptell) + return filesize class BinFile(object): def __init__(self, li): @@ -96,11 +48,19 @@ class BinFile(object): return out[0] return out elif arg is None: - return self._f.read() + return self.read_to_end() else: out = self._f.read(arg) + if isinstance(arg, (int,long)) and len(out) != arg: + pass #print 'warning: read of %d bytes got %d bytes' % (arg, len(out)) return out + def read_to_end(self): + return self.read(self.size()-self.tell()) + + def size(self): + return get_file_size(self._f) + def read_from(self, arg, offset): old = self.tell() try: @@ -113,6 +73,9 @@ class BinFile(object): def seek(self, off): self._f.seek(off) + def skip(self, dist): + self.seek(self.tell()+dist) + def close(self): self._f.close() @@ -123,7 +86,10 @@ class BinFile(object): (DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA, DT_RELASZ, DT_RELAENT, DT_STRSZ, DT_SYMENT, DT_INIT, DT_FINI, DT_SONAME, DT_RPATH, DT_SYMBOLIC, DT_REL, DT_RELSZ, DT_RELENT, DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL, DT_BIND_NOW, DT_INIT_ARRAY, - DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = iter_range(31) + DT_FINI_ARRAY, DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH, DT_FLAGS) = xrange(31) + +DT_RELRSZ, DT_RELR, DT_RELRENT = 0x23, 0x24, 0x25 + DT_GNU_HASH = 0x6ffffef5 DT_VERSYM = 0x6ffffff0 DT_RELACOUNT = 0x6ffffff9 @@ -147,6 +113,8 @@ R_ARM_GLOB_DAT = 21 R_ARM_JUMP_SLOT = 22 R_ARM_RELATIVE = 23 +R_FAKE_RELR = -1 + R_AARCH64_ABS64 = 257 R_AARCH64_GLOB_DAT = 1025 R_AARCH64_JUMP_SLOT = 1026 @@ -204,6 +172,7 @@ def suffixed_name(name, suffix): class SegmentBuilder(object): def __init__(self): self.segments = [] + self._sections = [] def add_segment(self, start, size, name, kind): r = Range(start, size) @@ -213,19 +182,24 @@ class SegmentBuilder(object): def add_section(self, name, start, end=None, size=None): assert end is None or size is None - if size == 0: - return if size is None: size = end-start - assert size > 0 - r = Range(start, size) - for i in self.segments: - if i.range.includes(r): - i.add_section(Section(r, name)) - return - assert False, "no containing segment for %r" % (name,) + if size > 0: + #assert size > 0 + r = Range(start, size) + self._sections.append((r, name)) + + def _add_sections_to_segments(self): + for r, name in self._sections: + for i in self.segments: + if i.range.includes(r): + i.add_section(Section(r, name)) + break + else: + assert False, 'no containing segment for %r' % (name,) def flatten(self): + self._add_sections_to_segments() self.segments.sort(key=lambda s: s.range.start) parts = [] for segment in self.segments: @@ -263,40 +237,14 @@ class ElfSym(object): class NxoFileBase(object): - # segment = (content, file offset, vaddr, vsize) - def __init__(self, text, ro, data, bsssize): - self.text = text - self.ro = ro - self.data = data - self.bsssize = bsssize - self.textoff = text[2] - self.textsize = text[3] - self.rodataoff = ro[2] - self.rodatasize = ro[3] - self.dataoff = data[2] - flatsize = data[2] + data[3] - - full = text[0] - if ro[2] >= len(full): - full += b'\x00' * (ro[2] - len(full)) - else: - print('truncating .text?') - full = full[:ro[2]] - full += ro[0] - if data[2] > len(full): - full += b'\x00' * (data[2] - len(full)) - else: - print('truncating .rodata?') - full += data[0] - f = BinFile(BytesIO(full)) - + def __init__(self, f, segment_data=None): self.binfile = f # read MOD self.modoff = f.read_from('I', 4) f.seek(self.modoff) - if f.read('4s') != b'MOD0': + if f.read('4s') != 'MOD0': raise NxoException('invalid MOD0 magic') self.dynamicoff = self.modoff + f.read('i') @@ -307,23 +255,7 @@ class NxoFileBase(object): self.moduleoff = self.modoff + f.read('i') - self.datasize = self.bssoff - self.dataoff - self.bsssize = self.bssend - self.bssoff - - self.isLibnx = False - if f.read('4s') == 'LNY0': - self.isLibnx = True - self.libnx_got_start = self.modoff + f.read('i') - self.libnx_got_end = self.modoff + f.read('i') - - self.segment_builder = builder = SegmentBuilder() - for off,sz,name,kind in [ - (self.textoff, self.textsize, ".text", "CODE"), - (self.rodataoff, self.rodatasize, ".rodata", "CONST"), - (self.dataoff, self.datasize, ".data", "DATA"), - (self.bssoff, self.bsssize, ".bss", "BSS"), - ]: - builder.add_segment(off, sz, name, kind) + builder = SegmentBuilder() # read dynamic self.armv7 = (f.read_from('Q', self.dynamicoff) > 0xFFFFFFFF or f.read_from('Q', self.dynamicoff+0x10) > 0xFFFFFFFF) @@ -333,7 +265,7 @@ class NxoFileBase(object): self.dynamic = dynamic = {} for i in MULTIPLE_DTS: dynamic[i] = [] - for i in iter_range((flatsize - self.dynamicoff) // 0x10): + for i in xrange((f.size() - self.dynamicoff) / 0x10): tag, val = f.read('II' if self.armv7 else 'QQ') if tag == DT_NULL: break @@ -341,15 +273,17 @@ class NxoFileBase(object): dynamic[tag].append(val) else: dynamic[tag] = val - builder.add_section('.dynamic', self.dynamicoff, end=f.tell()) + self.dynamicsize = f.tell() - self.dynamicoff + builder.add_section('.dynamic', self.dynamicoff, end=self.dynamicoff + self.dynamicsize) + builder.add_section('.eh_frame_hdr', self.unwindoff, end=self.unwindend) # read .dynstr if DT_STRTAB in dynamic and DT_STRSZ in dynamic: f.seek(dynamic[DT_STRTAB]) self.dynstr = f.read(dynamic[DT_STRSZ]) else: - self.dynstr = b'\x00' - print('warning: no dynstr') + self.dynstr = '\0' + print 'warning: no dynstr' for startkey, szkey, name in [ (DT_STRTAB, DT_STRSZ, '.dynstr'), @@ -357,40 +291,117 @@ class NxoFileBase(object): (DT_FINI_ARRAY, DT_FINI_ARRAYSZ, '.fini_array'), (DT_RELA, DT_RELASZ, '.rela.dyn'), (DT_REL, DT_RELSZ, '.rel.dyn'), + (DT_RELR, DT_RELRSZ, '.relr.dyn'), (DT_JMPREL, DT_PLTRELSZ, ('.rel.plt' if self.armv7 else '.rela.plt')), ]: if startkey in dynamic and szkey in dynamic: builder.add_section(name, dynamic[startkey], size=dynamic[szkey]) + # TODO + #build_id = content.find('\x04\x00\x00\x00\x14\x00\x00\x00\x03\x00\x00\x00GNU\x00') + #if build_id >= 0: + # builder.add_section('.note.gnu.build-id', build_id, size=0x24) + #else: + # build_id = content.index('\x04\x00\x00\x00\x10\x00\x00\x00\x03\x00\x00\x00GNU\x00') + # if build_id >= 0: + # builder.add_section('.note.gnu.build-id', build_id, size=0x20) + + if DT_HASH in dynamic: + hash_start = dynamic[DT_HASH] + f.seek(hash_start) + nbucket, nchain = f.read('II') + f.skip(nbucket * 4) + f.skip(nchain * 4) + hash_end = f.tell() + builder.add_section('.hash', hash_start, end=hash_end) + + if DT_GNU_HASH in dynamic: + gnuhash_start = dynamic[DT_GNU_HASH] + f.seek(gnuhash_start) + nbuckets, symoffset, bloom_size, bloom_shift = f.read('IIII') + f.skip(bloom_size * self.offsize) + buckets = [f.read('I') for i in range(nbuckets)] + + max_symix = max(buckets) if buckets else 0 + if max_symix >= symoffset: + f.skip((max_symix - symoffset) * 4) + while (f.read('I') & 1) == 0: + pass + gnuhash_end = f.tell() + builder.add_section('.gnu.hash', gnuhash_start, end=gnuhash_end) + self.needed = [self.get_dynstr(i) for i in self.dynamic[DT_NEEDED]] # load .dynsym self.symbols = symbols = [] - if DT_SYMTAB in dynamic and DT_STRTAB in dynamic: - f.seek(dynamic[DT_SYMTAB]) - while True: - if dynamic[DT_SYMTAB] < dynamic[DT_STRTAB] and f.tell() >= dynamic[DT_STRTAB]: - break - if self.armv7: - st_name, st_value, st_size, st_info, st_other, st_shndx = f.read('IIIBBH') - else: - st_name, st_info, st_other, st_shndx, st_value, st_size = f.read('IBBHQQ') - if st_name > len(self.dynstr): - break - symbols.append(ElfSym(self.get_dynstr(st_name), st_info, st_other, st_shndx, st_value, st_size)) - builder.add_section('.dynsym', dynamic[DT_SYMTAB], end=f.tell()) + f.seek(dynamic[DT_SYMTAB]) + while True: + if dynamic[DT_SYMTAB] < dynamic[DT_STRTAB] and f.tell() >= dynamic[DT_STRTAB]: + break + if self.armv7: + st_name, st_value, st_size, st_info, st_other, st_shndx = f.read('IIIBBH') + else: + st_name, st_info, st_other, st_shndx, st_value, st_size = f.read('IBBHQQ') + if st_name > len(self.dynstr): + break + symbols.append(ElfSym(self.get_dynstr(st_name), st_info, st_other, st_shndx, st_value, st_size)) + builder.add_section('.dynsym', dynamic[DT_SYMTAB], end=f.tell()) self.plt_entries = [] self.relocations = [] locations = set() - plt_got_end = None - if DT_REL in dynamic and DT_RELSZ in dynamic: + if DT_REL in dynamic: locations |= self.process_relocations(f, symbols, dynamic[DT_REL], dynamic[DT_RELSZ]) - if DT_RELA in dynamic and DT_RELASZ in dynamic: + if DT_RELA in dynamic: locations |= self.process_relocations(f, symbols, dynamic[DT_RELA], dynamic[DT_RELASZ]) - if DT_JMPREL in dynamic and DT_PLTRELSZ in dynamic: + if DT_RELR in dynamic: + locations |= self.process_relocations_relr(f, dynamic[DT_RELR], dynamic[DT_RELRSZ]) + + if segment_data is None: + # infer segment info + rloc_guess = (dynamic[DT_REL if DT_REL in dynamic else DT_RELA] & ~0xFFF) + dloc_guess = (min(i for i in locations if i != 0) & ~0xFFF) + dloc_guess2 = None + modoff = f.read_from('I', 4) + if self.modoff != 8: + search_start = (self.modoff + 0xFFF) & ~0xFFF + for i in range(search_start, f.size(), 0x1000): + count = 0 + for j in range(4, 0x1000, 4): + if f.read_from('I', i - j) != 0: + break + count += 1 + if count > 6: + dloc_guess2 = i + break + if dloc_guess2 is not None and dloc_guess2 < dloc_guess: + dloc_guess = dloc_guess2 + + if segment_data: + tloc, tsize, rloc, rsize, dloc, dsize = segment_data + assert rloc_guess == rloc + assert dloc_guess == dloc + + self.textoff = 0 + self.textsize = rloc_guess + self.rodataoff = rloc_guess + self.rodatasize = dloc_guess - rloc_guess + self.dataoff = dloc_guess + else: + tloc, tsize, rloc, rsize, dloc, dsize = segment_data + self.textoff = tloc + self.textsize = tsize + self.rodataoff = rloc + self.rodatasize = rsize + self.dataoff = dloc + + self.datasize = self.bssoff - self.dataoff + self.bsssize = self.bssend - self.bssoff + + plt_got_end = None + if DT_JMPREL in dynamic: pltlocations = self.process_relocations(f, symbols, dynamic[DT_JMPREL], dynamic[DT_PLTRELSZ]) locations |= pltlocations @@ -419,32 +430,94 @@ class NxoFileBase(object): target = paddr + poff if plt_got_start <= target < plt_got_end: self.plt_entries.append((off, target)) - builder.add_section('.plt', min(self.plt_entries)[0], end=max(self.plt_entries)[0] + 0x10) + if len(self.plt_entries) > 0: + builder.add_section('.plt', min(self.plt_entries)[0], end=max(self.plt_entries)[0] + 0x10) - # try to find the ".got" which should follow the ".got.plt" - if not self.isLibnx: - if plt_got_end is not None: - good = False - got_end = plt_got_end + self.offsize - while got_end in locations and (DT_INIT_ARRAY not in dynamic or got_end < dynamic[DT_INIT_ARRAY]): - good = True - got_end += self.offsize + # try to find the ".got" which should follow the ".got.plt" + good = False + got_start = (plt_got_end if plt_got_end is not None else self.dynamicoff + self.dynamicsize) + got_end = self.offsize + got_start + while (got_end in locations or (plt_got_end is None and got_end < dynamic[DT_INIT_ARRAY])) and (DT_INIT_ARRAY not in dynamic or got_end < dynamic[DT_INIT_ARRAY] or dynamic[DT_INIT_ARRAY] < got_start): + good = True + got_end += self.offsize + #print 'got_start got_end %X %X %s %X' % (got_start, got_end, str(got_end in locations), dynamic[DT_INIT_ARRAY]) - if good: - builder.add_section('.got', plt_got_end, end=got_end) - if self.isLibnx: - builder.add_section('.got', self.libnx_got_start, end=self.libnx_got_end) + if good: + self.got_start = got_start + self.got_end = got_end + builder.add_section('.got', self.got_start, end=self.got_end) + + self.eh_table = [] + if not self.armv7: + f.seek(self.unwindoff) + version, eh_frame_ptr_enc, fde_count_enc, table_enc = f.read('BBBB') + if not any(i == 0xff for i in (eh_frame_ptr_enc, fde_count_enc, table_enc)): # DW_EH_PE_omit + #assert eh_frame_ptr_enc == 0x1B # DW_EH_PE_pcrel | DW_EH_PE_sdata4 + #assert fde_count_enc == 0x03 # DW_EH_PE_absptr | DW_EH_PE_udata4 + #assert table_enc == 0x3B # DW_EH_PE_datarel | DW_EH_PE_sdata4 + if eh_frame_ptr_enc == 0x1B and fde_count_enc == 0x03 and table_enc == 0x3B: + base_offset = f.tell() + eh_frame = base_offset + f.read('i') + + fde_count = f.read('I') + #assert 8 * fde_count == self.unwindend - f.tell() + if 8 * fde_count == self.unwindend - f.tell(): + for i in range(fde_count): + pc = self.unwindoff + f.read('i') + entry = self.unwindoff + f.read('i') + self.eh_table.append((pc, entry)) + + # TODO: we miss the last one, but better than nothing + last_entry = sorted(self.eh_table, key=lambda x: x[1])[-1][1] + builder.add_section('.eh_frame', eh_frame, end=last_entry) + + + for off,sz,name,kind in [ + (self.textoff, self.textsize, '.text', 'CODE'), + (self.rodataoff, self.rodatasize, '.rodata', 'CONST'), + (self.dataoff, self.datasize, '.data', 'DATA'), + (self.bssoff, self.bsssize, '.bss', 'BSS'), + ]: + builder.add_segment(off, sz, name, kind) self.sections = [] for start, end, name, kind in builder.flatten(): self.sections.append((start, end, name, kind)) + self._addr_to_name = None + self._plt_lookup = None + + @property + def addr_to_name(self): + if self._addr_to_name is None: + d = {} + for sym in self.symbols: + if sym.shndx: + d[sym.value] = sym.name + self._addr_to_name = d + return self._addr_to_name + + @property + def plt_lookup(self): + if self._plt_lookup is None: + # generate lookups for .plt call redirection + got_value_lookup = {} + for offset, r_type, sym, addend in self.relocations: + if r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64) and addend == 0 and sym.shndx: + got_value_lookup[offset] = sym.value + + self._plt_lookup = {} + for func, target in self.plt_entries: + if target in got_value_lookup: + self._plt_lookup[func] = got_value_lookup[target] + + return self._plt_lookup def process_relocations(self, f, symbols, offset, size): locations = set() f.seek(offset) relocsize = 8 if self.armv7 else 0x18 - for i in iter_range(size // relocsize): + for i in xrange(size / relocsize): # NOTE: currently assumes all armv7 relocs have no addends, # and all 64-bit ones do. if self.armv7: @@ -464,15 +537,64 @@ class NxoFileBase(object): self.relocations.append((offset, r_type, sym, addend)) return locations - def get_dynstr(self, o): - return ascii_string(self.dynstr[o:self.dynstr.index(b'\x00', o)]) + def process_relocations_relr(self, f, offset, size): + locations = set() + f.seek(offset) + relocsize = 8 + for i in xrange(size / relocsize): + entry = f.read('Q') + if entry & 1: + entry >>= 1 + i = 0 + while i < (relocsize * 8) - 1: + if entry & (1 << i): + locations.add(where + i * relocsize) + self.relocations.append((where + i * relocsize, R_FAKE_RELR, None, 0)) + i += 1 + where += relocsize * ((relocsize * 8) - 1) + else: + # Where + where = entry + locations.add(where) + self.relocations.append((where, R_FAKE_RELR, None, 0)) + where += relocsize + return locations + def get_dynstr(self, o): + return self.dynstr[o:self.dynstr.index('\0', o)] + + def get_path_or_name(self): + path = None + for off, end, name, class_ in self.sections: + if name == '.rodata' and end-off < 0x1000 and end-off > 8: + id_ = self.binfile.read_from(end-off, off) + length = struct.unpack_from('= len(full): + full += '\0' * (rloc - len(full)) + else: + print 'truncating?' + full = full[:rloc] + full += ro + if dloc >= len(full): + full += '\0' * (dloc - len(full)) + else: + print 'truncating?' + full = full[:dloc] + full += data + self.full = full + + super(NsoFile, self).__init__(BinFile(StringIO(full)), (tloc, tsize, rloc, rsize, dloc, dsize)) class NroFile(NxoFileBase): def __init__(self, fileobj): f = BinFile(fileobj) - if f.read_from('4s', 0x10) != b'NRO0': + if f.read_from('4s', 0x10) != 'NRO0': raise NxoException('Invalid NRO magic') f.seek(0x20) @@ -504,19 +640,61 @@ class NroFile(NxoFileBase): tloc, tsize = f.read('II') rloc, rsize = f.read('II') dloc, dsize = f.read('II') - bsssize = f.read_from('I', 0x28) - text = (f.read_from(tsize, tloc), tloc, tloc, tsize) - ro = (f.read_from(rsize, rloc), rloc, rloc, rsize) - data = (f.read_from(dsize, dloc), dloc, dloc, dsize) + # copy f, since all other formats allow the original file to be closed + f.seek(0) + full = f.read(f.size()) - super(NroFile, self).__init__(text, ro, data, bsssize) + filecopy = BinFile(StringIO(full)) + super(NroFile, self).__init__(filecopy, (tloc, tsize, rloc, rsize, dloc, dsize)) + +def kip1_blz_decompress(compressed): + compressed_size, init_index, uncompressed_addl_size = struct.unpack(' 0: + cmp_ofs -= 1 + control = decompressed[cmp_start + cmp_ofs] + for i in xrange(8): + if control & 0x80: + if cmp_ofs < 2 - cmp_start: + raise ValueError('Compression out of bounds!') + cmp_ofs -= 2 + segmentoffset = decompressed[cmp_start + cmp_ofs] | (decompressed[cmp_start + cmp_ofs + 1] << 8) + segmentsize = ((segmentoffset >> 12) & 0xF) + 3 + segmentoffset &= 0x0FFF + segmentoffset += 2 + if out_ofs < segmentsize - cmp_start: + raise ValueError('Compression out of bounds!') + for j in xrange(segmentsize): + if out_ofs + segmentoffset >= decompressed_size: + raise ValueError('Compression out of bounds!') + data = decompressed[cmp_start + out_ofs + segmentoffset] + out_ofs -= 1 + decompressed[cmp_start + out_ofs] = data + else: + if out_ofs < 1 - cmp_start: + raise ValueError('Compression out of bounds!') + out_ofs -= 1 + cmp_ofs -= 1 + decompressed[cmp_start + out_ofs] = decompressed[cmp_start + cmp_ofs] + control <<= 1 + control &= 0xFF + if not out_ofs: + break + return ''.join(map(chr, decompressed)) class KipFile(NxoFileBase): def __init__(self, fileobj): f = BinFile(fileobj) - if f.read_from('4s', 0) != b'KIP1': + if f.read_from('4s', 0) != 'KIP1': raise NxoException('Invalid KIP magic') flags = f.read_from('b', 0x1F) @@ -529,33 +707,72 @@ class KipFile(NxoFileBase): roff = toff + tfilesize doff = roff + rfilesize - bsssize = f.read_from('I', 0x54) - print('bss size 0x%x' % bsssize) + bsssize = f.read_from('I', 0x18) - print('load segments') - text = (kip1_blz_decompress(f.read_from(tfilesize, toff)), None, tloc, tsize) if flags & 1 else (f.read_from(tfilesize, toff), toff, tloc, tsize) - ro = (kip1_blz_decompress(f.read_from(rfilesize, roff)), None, rloc, rsize) if flags & 2 else (f.read_from(rfilesize, roff), roff, rloc, rsize) - data = (kip1_blz_decompress(f.read_from(dfilesize, doff)), None, dloc, dsize) if flags & 4 else (f.read_from(dfilesize, doff), doff, dloc, dsize) - super(KipFile, self).__init__(text, ro, data, bsssize) + text = kip1_blz_decompress(str(f.read_from(tfilesize, toff))) if flags & 1 else f.read_from(tfilesize, toff) + ro = kip1_blz_decompress(str(f.read_from(rfilesize, roff))) if flags & 2 else f.read_from(rfilesize, roff) + data = kip1_blz_decompress(str(f.read_from(dfilesize, doff))) if flags & 4 else f.read_from(dfilesize, doff) + full = text + if rloc >= len(full): + full += '\0' * (rloc - len(full)) + else: + print 'truncating?' + full = full[:rloc] + full += ro + if dloc >= len(full): + full += '\0' * (dloc - len(full)) + else: + print 'truncating?' + full = full[:dloc] + full += data + + super(KipFile, self).__init__(BinFile(StringIO(full)), (tloc, tsize, rloc, rsize, dloc, dsize)) + +class MemoryDumpFile(NxoFileBase): + def __init__(self, fileobj): + f = BinFile(fileobj) + + if f.read_from('4s', f.read_from('I', 4)) != 'MOD0': + raise NxoException('Invalid MOD0 magic') + + f.seek(0) + full = f.read(f.size()) + + filecopy = BinFile(StringIO(full)) + super(MemoryDumpFile, self).__init__(filecopy) class NxoException(Exception): pass +def looks_like_memory_dump(fileobj): + fileobj.seek(0) + header = fileobj.read(8) + if len(header) < 8: + return False + modoff = struct.unpack_from('= len(accept_formats_list): + accept_formats_list = None + accept_formats_index = 0 + return 0 + + ret = accept_formats_list[accept_formats_index] + if not isinstance(ret, dict): + ret = { 'format': ret } + if 'options' not in ret: + ret['options'] = 1 + if 'processor' not in ret: + ret['processor'] = 'arm' + ret['options'] |= 1 | idaapi.ACCEPT_CONTINUE + + accept_formats_index += 1 + + return ret def ida_make_offset(f, ea): if f.armv7: - idaapi.create_data(ea, idc.FF_DWORD, 4, idaapi.BADADDR) + idc.MakeDword(ea) else: - idaapi.create_data(ea, idc.FF_QWORD, 8, idaapi.BADADDR) - idc.op_plain_offset(ea, 0, 0) + idc.MakeQword(ea) + idc.OpOff(ea, 0, 0) def find_bl_targets(text_start, text_end): targets = set() - for pc in range(text_start, text_end, 4): - d = idc.get_wide_dword(pc) + for pco in xrange(0, text_end - text_start, 4): + pc = text_start + pco + d = Dword(pc) if (d & 0xfc000000) == 0x94000000: imm = d & 0x3ffffff if imm & 0x2000000: @@ -601,35 +892,73 @@ else: targets.add(target) return targets - def load_file(li, neflags, format): - idaapi.set_processor_type("arm", idaapi.SETPROC_LOADER_NON_FATAL|idaapi.SETPROC_LOADER) - f = load_nxo(li) - if f.armv7: - idc.set_inf_attr(idc.INF_LFLAGS, idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT) + def load_file(li, neflags, fmt): + idaapi.set_processor_type('arm', SETPROC_ALL|SETPROC_FATAL) + + options = FORMAT_OPTIONS[fmt] + + if OPT_EXEFS_LOAD in options: + ret = load_as_exefs(li, options) else: - idc.set_inf_attr(idc.INF_LFLAGS, idc.get_inf_attr(idc.INF_LFLAGS) | idc.LFLG_64BIT) + ret = load_one_file(li, options, 0) - idc.set_inf_attr(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3) - idaapi.set_compiler_id(idaapi.COMP_GNU) - idaapi.add_til('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1) + eh_parse = idaapi.find_plugin('eh_parse', True) + if eh_parse: + print 'eh_parse ->', idaapi.run_plugin(eh_parse, 0) + else: + print 'warning: eh_parse missing' - loadbase = 0x60000000 if f.armv7 else 0x7100000000 + return ret + + def load_as_exefs(li, options): + dirname = os.path.dirname(idc.get_input_file_path()) + binaries = LOAD_EXEFS_NAMES + binaries = [os.path.join(dirname, i) for i in binaries] + binaries = [i for i in binaries if os.path.exists(i)] + for idx, fname in enumerate(binaries): + with open(fname, 'rb') as f: + if not load_one_file(f, options, idx, os.path.basename(fname)): + return False + return True + + def load_one_file(li, options, idx, basename=None): + bypass_plt = OPT_BYPASS_PLT in options + + f = load_nxo(li) + + if idx == 0: + if f.armv7: + idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_PC_FLAT) + else: + idc.SetShortPrm(idc.INF_LFLAGS, idc.GetShortPrm(idc.INF_LFLAGS) | idc.LFLG_64BIT) + + idc.SetCharPrm(idc.INF_DEMNAMES, idaapi.DEMNAM_GCC3) + idaapi.set_compiler_id(idaapi.COMP_GNU) + idaapi.add_til2('gnulnx_arm' if f.armv7 else 'gnulnx_arm64', 1) + # don't create tails + idc.set_inf_attr(idc.INF_AF, idc.get_inf_attr(idc.INF_AF) & ~idc.AF_FTAIL) + + if OPT_LOAD_31_BIT in options: + loadbase = 0x8000000 + step = 0x1000000 + elif f.armv7: + loadbase = 0x60000000 + step = 0x10000000 + else: + loadbase = 0x7100000000 + step = 0x100000000 + loadbase += idx * step f.binfile.seek(0) as_string = f.binfile.read(f.bssoff) idaapi.mem2base(as_string, loadbase) - if f.text[1] != None: - li.file2base(f.text[1], loadbase + f.text[2], loadbase + f.text[2] + f.text[3], True) - if f.ro[1] != None: - li.file2base(f.ro[1], loadbase + f.ro[2], loadbase + f.ro[2] + f.ro[3], True) - if f.data[1] != None: - li.file2base(f.data[1], loadbase + f.data[2], loadbase + f.data[2] + f.data[3], True) + seg_prefix = basename if basename is not None else '' for start, end, name, kind in f.sections: if name.startswith('.got'): kind = 'CONST' - idaapi.add_segm(0, loadbase+start, loadbase+end, name, kind) - segm = idaapi.get_segm_by_name(name) + idaapi.add_segm(0, loadbase+start, loadbase+end, seg_prefix+name, kind) + segm = idaapi.get_segm_by_name(seg_prefix+name) if kind == 'CONST': segm.perm = idaapi.SEGPERM_READ elif kind == 'CODE': @@ -650,14 +979,16 @@ else: last_ea = max(loadbase + end for start, end, name, kind in f.sections) undef_entry_size = 8 undef_ea = ((last_ea + 0xFFF) & ~0xFFF) + undef_entry_size # plus 8 so we don't end up on the "end" symbol - idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, "UNDEF", "XTRN") - segm = idaapi.get_segm_by_name("UNDEF") + + undef_seg = basename + '.UNDEF' if basename is not None else 'UNDEF' + idaapi.add_segm(0, undef_ea, undef_ea+undef_count*undef_entry_size, undef_seg, 'XTRN') + segm = idaapi.get_segm_by_name(undef_seg) segm.type = idaapi.SEG_XTRN idaapi.update_segm(segm) for i,s in enumerate(f.symbols): if not s.shndx and s.name: - idaapi.create_data(undef_ea, idc.FF_QWORD, 8, idaapi.BADADDR) - idaapi.force_name(undef_ea, s.name) + idc.MakeQword(undef_ea) + idaapi.do_name_anyway(undef_ea, s.name) s.resolved = undef_ea undef_ea += undef_entry_size elif i != 0: @@ -665,10 +996,9 @@ else: s.resolved = loadbase + s.value if s.name: if s.type == STT_FUNC: - print(hex(s.resolved), s.name) idaapi.add_entry(s.resolved, s.resolved, s.name, 0) else: - idaapi.force_name(s.resolved, s.name) + idaapi.do_name_anyway(s.resolved, s.name) else: # NULL symbol @@ -679,17 +1009,20 @@ else: if s.name and s.shndx and s.value: if s.type == STT_FUNC: funcs.add(loadbase+s.value) + symend = loadbase+s.value+s.size + if Dword(symend) != 0: + funcs.add(symend) got_name_lookup = {} for offset, r_type, sym, addend in f.relocations: target = offset + loadbase if r_type in (R_ARM_GLOB_DAT, R_ARM_JUMP_SLOT, R_ARM_ABS32): if not sym: - print('error: relocation at %X failed' % target) + print 'error: relocation at %X failed' % target else: - idaapi.put_dword(target, sym.resolved) + idaapi.put_long(target, sym.resolved) elif r_type == R_ARM_RELATIVE: - idaapi.put_dword(target, idaapi.get_dword(target) + loadbase) + idaapi.put_long(target, idaapi.get_long(target) + loadbase) elif r_type in (R_AARCH64_GLOB_DAT, R_AARCH64_JUMP_SLOT, R_AARCH64_ABS64): idaapi.put_qword(target, sym.resolved + addend) if addend == 0: @@ -698,20 +1031,52 @@ else: idaapi.put_qword(target, loadbase + addend) if addend < f.textsize: funcs.add(loadbase + addend) + elif r_type == R_FAKE_RELR: + assert not f.armv7 # TODO + addend = idaapi.get_qword(target) + idaapi.put_qword(target, addend + loadbase) + if addend < f.textsize: + funcs.add(loadbase + addend) else: - print('TODO r_type %d' % (r_type,)) + print 'TODO r_type %d' % (r_type,) ida_make_offset(f, target) for func, target in f.plt_entries: if target in got_name_lookup: addr = loadbase + func funcs.add(addr) - idaapi.force_name(addr, got_name_lookup[target]) + idaapi.do_name_anyway(addr, got_name_lookup[target]) - funcs |= find_bl_targets(loadbase, loadbase+f.textsize) + if not f.armv7: + funcs |= find_bl_targets(loadbase, loadbase+f.textsize) + + if bypass_plt: + plt_lookup = f.plt_lookup + for pco in xrange(0, f.textsize, 4): + pc = loadbase + pco + d = Dword(pc) + if (d & 0x7c000000) == (0x94000000 & 0x7c000000): + imm = d & 0x3ffffff + if imm & 0x2000000: + imm |= ~0x1ffffff + if 0 <= imm <= 2: + continue + target = (pc + imm * 4) - loadbase + if target in plt_lookup: + new_target = plt_lookup[target] + loadbase + new_instr = (d & ~0x3ffffff) | (((new_target - pc) / 4) & 0x3ffffff) + idaapi.put_long(pc, new_instr) + + for pco in xrange(0, f.textsize, 4): + pc = loadbase + pco + d = Dword(pc) + if d == 0x14000001: + funcs.add(pc + 4) + + for pc, _ in f.eh_table: + funcs.add(loadbase + pc) for addr in sorted(funcs, reverse=True): - idc.AutoMark(addr, idc.AU_CODE) - idc.AutoMark(addr, idc.AU_PROC) + idaapi.auto_make_proc(addr) return 1 From 4ca3c44e5f4d002161faf649c98954344751b559 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 02:02:49 -0700 Subject: [PATCH 007/238] kern: pass ini1 size from loader to kernel, remove slab memset from init0 --- .../mesosphere/kern_initial_process.hpp | 8 ++++- .../source/init/kern_init_slab_setup.cpp | 3 ++ .../source/kern_initial_process.cpp | 27 +++++++++++----- .../source/kern_k_memory_manager.cpp | 9 +++--- .../source/arch/arm64/init/kern_init_core.cpp | 14 ++++---- .../kernel_ldr/source/kern_init_loader.cpp | 32 +++++++++++++------ 6 files changed, 62 insertions(+), 31 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp index 2ab3b6090..911298199 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp @@ -34,8 +34,14 @@ namespace ams::kern { uintptr_t _08; }; + struct InitialProcessBinaryLayoutWithSize { + InitialProcessBinaryLayout layout; + size_t size; + }; + KPhysicalAddress GetInitialProcessBinaryPhysicalAddress(); - void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr); + size_t GetInitialProcessBinarySize(); + void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr, size_t size); u64 GetInitialProcessIdMin(); u64 GetInitialProcessIdMax(); diff --git a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp index 1d76900ee..b82e78f84 100644 --- a/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp +++ b/libraries/libmesosphere/source/init/kern_init_slab_setup.cpp @@ -171,6 +171,9 @@ namespace ams::kern::init { const KMemoryRegion &slab_region = KMemoryLayout::GetSlabRegion(); KVirtualAddress address = slab_region.GetAddress(); + /* Clear the slab region. */ + std::memset(GetVoidPointer(address), 0, slab_region.GetSize()); + /* Initialize slab type array to be in sorted order. */ KSlabType slab_types[KSlabType_Count]; for (size_t i = 0; i < util::size(slab_types); i++) { slab_types[i] = static_cast(i); } diff --git a/libraries/libmesosphere/source/kern_initial_process.cpp b/libraries/libmesosphere/source/kern_initial_process.cpp index e435deee4..6b22a1784 100644 --- a/libraries/libmesosphere/source/kern_initial_process.cpp +++ b/libraries/libmesosphere/source/kern_initial_process.cpp @@ -27,6 +27,7 @@ namespace ams::kern { constinit KPhysicalAddress g_initial_process_binary_phys_addr = Null; constinit KVirtualAddress g_initial_process_binary_address = Null; + constinit size_t g_initial_process_binary_size = 0; constinit InitialProcessBinaryHeader g_initial_process_binary_header = {}; constinit size_t g_initial_process_secure_memory_size = 0; constinit u64 g_initial_process_id_min = std::numeric_limits::max(); @@ -275,10 +276,11 @@ namespace ams::kern { } - void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr) { + void SetInitialProcessBinaryPhysicalAddress(KPhysicalAddress phys_addr, size_t size) { MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr == Null); g_initial_process_binary_phys_addr = phys_addr; + g_initial_process_binary_size = size; } KPhysicalAddress GetInitialProcessBinaryPhysicalAddress() { @@ -287,6 +289,12 @@ namespace ams::kern { return g_initial_process_binary_phys_addr; } + size_t GetInitialProcessBinarySize() { + MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_phys_addr != Null); + + return g_initial_process_binary_size; + } + u64 GetInitialProcessIdMin() { return g_initial_process_id_min; } @@ -305,14 +313,17 @@ namespace ams::kern { LoadInitialProcessBinaryHeader(); if (g_initial_process_binary_header.num_processes > 0) { - /* Reserve pages for the initial process binary from the system resource limit. */ - const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize); - MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size)); + /* Ensure that we have a non-zero size. */ + const size_t expected_size = g_initial_process_binary_size; + MESOSPHERE_INIT_ABORT_UNLESS(expected_size != 0); - /* The initial process binary is potentially over-allocated, so free any extra pages. */ - if (total_size < InitialProcessBinarySizeMax) { - Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(g_initial_process_binary_address + total_size), (InitialProcessBinarySizeMax - total_size) / PageSize); - } + /* Ensure that the size we need to reserve is as we expect it to be. */ + const size_t total_size = util::AlignUp(g_initial_process_binary_header.size, PageSize); + MESOSPHERE_ABORT_UNLESS(total_size == expected_size); + MESOSPHERE_ABORT_UNLESS(total_size <= InitialProcessBinarySizeMax); + + /* Reserve pages for the initial process binary from the system resource limit. */ + MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_PhysicalMemoryMax, total_size)); return total_size; } else { diff --git a/libraries/libmesosphere/source/kern_k_memory_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_manager.cpp index b9999be81..01dcd565a 100644 --- a/libraries/libmesosphere/source/kern_k_memory_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_manager.cpp @@ -108,7 +108,8 @@ namespace ams::kern { /* Free each region to its corresponding heap. */ size_t reserved_sizes[MaxManagerCount] = {}; const KPhysicalAddress ini_start = GetInitialProcessBinaryPhysicalAddress(); - const KPhysicalAddress ini_end = ini_start + InitialProcessBinarySizeMax; + const size_t ini_size = GetInitialProcessBinarySize(); + const KPhysicalAddress ini_end = ini_start + ini_size; const KPhysicalAddress ini_last = ini_end - 1; for (const auto &it : KMemoryLayout::GetPhysicalMemoryRegionTree()) { if (it.IsDerivedFrom(KMemoryRegionType_DramUserPool)) { @@ -126,13 +127,13 @@ namespace ams::kern { } /* Open/reserve the ini memory. */ - manager.OpenFirst(ini_start, InitialProcessBinarySizeMax / PageSize); - reserved_sizes[it.GetAttributes()] += InitialProcessBinarySizeMax; + manager.OpenFirst(ini_start, ini_size / PageSize); + reserved_sizes[it.GetAttributes()] += ini_size; /* Free memory after the ini to the heap. */ if (ini_last != cur_last) { MESOSPHERE_ABORT_UNLESS(cur_end != Null); - manager.Free(ini_end, cur_end - ini_end); + manager.Free(ini_end, (cur_end - ini_end) / PageSize); } } else { /* Ensure there's no partial overlap with the ini image. */ diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index 240faf484..c8139fb49 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -45,7 +45,7 @@ namespace ams::kern::init { constinit KInitArguments g_init_arguments[cpu::NumCores]; /* Globals for passing data between InitializeCorePhase1 and InitializeCorePhase2. */ - constinit InitialProcessBinaryLayout g_phase2_initial_process_binary_layout{}; + constinit InitialProcessBinaryLayoutWithSize g_phase2_initial_process_binary_meta{}; constinit KPhysicalAddress g_phase2_resource_end_phys_addr = Null; constinit u64 g_phase2_linear_region_phys_to_virt_diff = 0; @@ -246,7 +246,7 @@ namespace ams::kern::init { /* Decode the initial state. */ const auto initial_page_allocator_state = *static_cast(initial_state[0]); - g_phase2_initial_process_binary_layout = *static_cast(initial_state[1]); + g_phase2_initial_process_binary_meta = *static_cast(initial_state[1]); /* Restore the page allocator state setup by kernel loader. */ g_initial_page_allocator.InitializeFromState(std::addressof(initial_page_allocator_state)); @@ -565,9 +565,6 @@ namespace ams::kern::init { } } - /* Clear the slab region. */ - std::memset(GetVoidPointer(slab_region_start), 0, slab_region_size); - /* NOTE: Unknown function is called here which is ifdef'd out on retail kernel. */ /* The unknown function is immediately before the function which gets an unknown debug region size, inside this translation unit. */ /* It's likely that this is some kind of initializer for this unknown debug region. */ @@ -624,9 +621,10 @@ namespace ams::kern::init { /* Set the initial process binary physical address. */ /* NOTE: Nintendo does this after pool partition setup, but it's a requirement that we do it before */ /* to retain compatibility with < 5.0.0. */ - const KPhysicalAddress ini_address = g_phase2_initial_process_binary_layout.address; + const KPhysicalAddress ini_address = g_phase2_initial_process_binary_meta.layout.address; + const size_t ini_size = g_phase2_initial_process_binary_meta.size; MESOSPHERE_INIT_ABORT_UNLESS(ini_address != Null); - SetInitialProcessBinaryPhysicalAddress(ini_address); + SetInitialProcessBinaryPhysicalAddress(ini_address, ini_size); /* Setup all other memory regions needed to arrange the pool partitions. */ SetupPoolPartitionMemoryRegions(); @@ -640,7 +638,7 @@ namespace ams::kern::init { /* Check that the region contains the ini. */ MESOSPHERE_INIT_ABORT_UNLESS(ini_region->GetAddress() <= GetInteger(ini_address)); - MESOSPHERE_INIT_ABORT_UNLESS(GetInteger(ini_address) + InitialProcessBinarySizeMax <= ini_region->GetEndAddress()); + MESOSPHERE_INIT_ABORT_UNLESS(GetInteger(ini_address) + ini_size <= ini_region->GetEndAddress()); MESOSPHERE_INIT_ABORT_UNLESS(ini_region->GetEndAddress() != 0); } diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index 70e26866c..0fceac933 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -45,7 +45,7 @@ namespace ams::kern::init::loader { constinit KInitialPageAllocator g_initial_page_allocator; constinit KInitialPageAllocator::State g_final_page_allocator_state; - constinit InitialProcessBinaryLayout g_initial_process_binary_layout; + constinit InitialProcessBinaryLayoutWithSize g_initial_process_binary_meta; constinit void *g_final_state[2]; @@ -165,19 +165,31 @@ namespace ams::kern::init::loader { const uintptr_t resource_end_address = base_address + resource_offset + resource_region_size; /* Setup the INI1 header in memory for the kernel. */ - KSystemControl::Init::GetInitialProcessBinaryLayout(std::addressof(g_initial_process_binary_layout)); - MESOSPHERE_INIT_ABORT_UNLESS(g_initial_process_binary_layout.address != 0); + { + /* Get the kernel layout. */ + KSystemControl::Init::GetInitialProcessBinaryLayout(std::addressof(g_initial_process_binary_meta.layout)); - if (ini_base_address != g_initial_process_binary_layout.address) { - /* The INI is not at the correct address, so we need to relocate it. */ + /* If there's no desired base address, use the ini in place. */ + if (g_initial_process_binary_meta.layout.address == 0) { + g_initial_process_binary_meta.layout.address = ini_base_address; + } + + + /* Validate and potentially relocate the INI. */ const InitialProcessBinaryHeader *ini_header = reinterpret_cast(ini_base_address); - if (ini_header->magic == InitialProcessBinaryMagic && ini_header->size <= InitialProcessBinarySizeMax) { - /* INI is valid, relocate it. */ - std::memmove(reinterpret_cast(g_initial_process_binary_layout.address), ini_header, ini_header->size); + size_t ini_size = 0; + if (ini_header->magic == InitialProcessBinaryMagic && (ini_size = ini_header->size) <= InitialProcessBinarySizeMax) { + /* INI is valid, relocate it if necessary. */ + if (ini_base_address != g_initial_process_binary_meta.layout.address) { + std::memmove(reinterpret_cast(g_initial_process_binary_meta.layout.address), ini_header, ini_size); + } } else { /* INI is invalid. Make the destination header invalid. */ - std::memset(reinterpret_cast(g_initial_process_binary_layout.address), 0, sizeof(InitialProcessBinaryHeader)); + std::memset(reinterpret_cast(g_initial_process_binary_meta.layout.address), 0, sizeof(InitialProcessBinaryHeader)); } + + /* Set the INI size in layout. */ + g_initial_process_binary_meta.size = util::AlignUp(ini_size, PageSize); } /* We want to start allocating page tables at the end of the resource region. */ @@ -238,7 +250,7 @@ namespace ams::kern::init::loader { /* Setup final kernel loader state. */ g_final_state[0] = std::addressof(g_final_page_allocator_state); - g_final_state[1] = std::addressof(g_initial_process_binary_layout); + g_final_state[1] = std::addressof(g_initial_process_binary_meta); return g_final_state; } From 0daef4a6e8bbf40c0aa31ca34d89d86614b2894d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 02:59:41 -0700 Subject: [PATCH 008/238] kern/ldr: move crt0 into .rodata --- fusee/program/source/fusee_stratosphere.cpp | 18 +- .../mesosphere/init/kern_init_layout.hpp | 16 +- mesosphere/build_mesosphere.py | 17 +- mesosphere/kernel/kernel.ld | 44 ++--- .../kernel/source/arch/arm64/init/start.s | 161 +++++++++++------- .../kernel_ldr/source/arch/arm64/start.s | 20 ++- .../kernel_ldr/source/kern_init_loader.cpp | 34 +++- 7 files changed, 220 insertions(+), 90 deletions(-) diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index 3146b4c8b..f18bc4646 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -24,6 +24,9 @@ namespace ams::nxboot { namespace { + constexpr u32 MesoshereMetadataLayout0Magic = util::FourCC<'M','S','S','0'>::Code; + constexpr u32 MesoshereMetadataLayout1Magic = util::FourCC<'M','S','S','1'>::Code; + struct InitialProcessBinaryHeader { static constexpr u32 Magic = util::FourCC<'I','N','I','1'>::Code; @@ -1011,7 +1014,20 @@ namespace ams::nxboot { } /* Set the embedded ini pointer. */ - std::memcpy(payload_data + 8, std::addressof(meso_size), sizeof(meso_size)); + const u32 magic = *reinterpret_cast(payload_data + 4); + if (magic == MesoshereMetadataLayout0Magic) { + std::memcpy(payload_data + 8, std::addressof(meso_size), sizeof(meso_size)); + } else if (magic == MesoshereMetadataLayout1Magic) { + if (const u32 meta_offset = *reinterpret_cast(payload_data + 8); meta_offset <= meso_size - sizeof(meso_size)) { + s64 relative_offset = meso_size - meta_offset; + std::memcpy(payload_data + meta_offset, std::addressof(relative_offset), sizeof(relative_offset)); + } else { + ShowFatalError("Invalid mesosphere metadata layout!\n"); + } + } else { + ShowFatalError("Unknown mesosphere metadata version!\n"); + } + /* Get the ini pointer. */ InitialProcessBinaryHeader * const ini = reinterpret_cast(payload_data + meso_size); diff --git a/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp b/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp index daf0e81a4..db952edf4 100644 --- a/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp +++ b/libraries/libmesosphere/include/mesosphere/init/kern_init_layout.hpp @@ -31,8 +31,22 @@ namespace ams::kern::init { u32 dynamic_offset; u32 init_array_offset; u32 init_array_end_offset; + u32 sysreg_offset; }; static_assert(util::is_pod::value); - static_assert(sizeof(KernelLayout) == 0x30); + static_assert(sizeof(KernelLayout) == 0x34); + + #if defined(ATMOSPHERE_ARCH_ARM64) + struct KernelSystemRegisters { + u64 ttbr0_el1; + u64 ttbr1_el1; + u64 tcr_el1; + u64 mair_el1; + u64 sctlr_el1; + }; + #else + struct KernelSystemRegisters { + }; + #endif } \ No newline at end of file diff --git a/mesosphere/build_mesosphere.py b/mesosphere/build_mesosphere.py index 5b9dd4f7b..db9599763 100644 --- a/mesosphere/build_mesosphere.py +++ b/mesosphere/build_mesosphere.py @@ -17,11 +17,16 @@ def main(argc, argv): kernel_ldr = f.read() with open(argv[2], 'rb') as f: kernel = f.read() - kernel_metadata_offset = 4 + kernel_metaptr_offset = 4 + assert (kernel_metaptr_offset <= len(kernel) - 0x40) + assert (kernel[kernel_metaptr_offset:kernel_metaptr_offset + 4] == b'MSS1') + kernel_metadata_offset = up('= bss_start) assert (bss_end == kernel_end) @@ -53,9 +58,9 @@ def main(argc, argv): mesosphere_end = align_up(kernel_ldr_end, 0x1000) with open(argv[3], 'wb') as f: - f.write(kernel[:kernel_metadata_offset + 4]) - f.write(pk('(layout) - base_address; + layout->rx_offset += layout_offset; + layout->rx_end_offset += layout_offset; + layout->ro_offset += layout_offset; + layout->ro_end_offset += layout_offset; + layout->rw_offset += layout_offset; + layout->rw_end_offset += layout_offset; + layout->bss_offset += layout_offset; + layout->bss_end_offset += layout_offset; + layout->resource_offset += layout_offset; + layout->dynamic_offset += layout_offset; + layout->init_array_offset += layout_offset; + layout->init_array_end_offset += layout_offset; + layout->sysreg_offset += layout_offset; + } + + /* Relocate the kernel if necessary. */ KPhysicalAddress correct_base = KSystemControl::Init::GetKernelPhysicalBaseAddress(base_address); if (correct_base != base_address) { const uintptr_t diff = GetInteger(correct_base) - base_address; @@ -62,7 +81,7 @@ namespace ams::kern::init::loader { } } - void SetupInitialIdentityMapping(KInitialPageTable &init_pt, uintptr_t base_address, uintptr_t kernel_size, uintptr_t page_table_region, size_t page_table_region_size, KInitialPageAllocator &allocator) { + void SetupInitialIdentityMapping(KInitialPageTable &init_pt, uintptr_t base_address, uintptr_t kernel_size, uintptr_t page_table_region, size_t page_table_region_size, KInitialPageAllocator &allocator, KernelSystemRegisters *sysregs) { /* Map in an RWX identity mapping for the kernel. */ constexpr PageTableEntry KernelRWXIdentityAttribute(PageTableEntry::Permission_KernelRWX, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); init_pt.Map(base_address, kernel_size, base_address, KernelRWXIdentityAttribute, allocator, 0); @@ -96,9 +115,17 @@ namespace ams::kern::init::loader { /* Setup SCTLR_EL1. */ /* TODO: Define these bits properly elsewhere, document exactly what each bit set is doing .*/ - constexpr u64 SctlrValue = 0x0000000034D5D925ul; + constexpr u64 SctlrValue = 0x0000000034D5D92Dul; cpu::SetSctlrEl1(SctlrValue); cpu::InstructionMemoryBarrier(); + + /* Setup the system registers for other cores. */ + /* NOTE: sctlr_el1 on other cores has the WXN bit set (0x80000); this will be set before KernelMain() on this core. */ + sysregs->ttbr0_el1 = init_pt.GetTtbr0L1TableAddress(); + sysregs->ttbr1_el1 = init_pt.GetTtbr1L1TableAddress(); + sysregs->tcr_el1 = TcrValue; + sysregs->mair_el1 = MairValue; + sysregs->sctlr_el1 = SctlrValue | 0x80000; } KVirtualAddress GetRandomKernelBaseAddress(KInitialPageTable &page_table, KPhysicalAddress phys_base_address, size_t kernel_size) { @@ -159,6 +186,7 @@ namespace ams::kern::init::loader { const uintptr_t dynamic_offset = layout->dynamic_offset; const uintptr_t init_array_offset = layout->init_array_offset; const uintptr_t init_array_end_offset = layout->init_array_end_offset; + const uintptr_t sysreg_offset = layout->sysreg_offset; /* Determine the size of the resource region. */ const size_t resource_region_size = KMemoryLayout::GetResourceRegionSizeForInit(KSystemControl::Init::ShouldIncreaseThreadResourceLimit()); @@ -199,7 +227,7 @@ namespace ams::kern::init::loader { KInitialPageTable init_pt(KernelBaseRangeStart, KernelBaseRangeLast, g_initial_page_allocator); /* Setup initial identity mapping. TTBR1 table passed by reference. */ - SetupInitialIdentityMapping(init_pt, base_address, bss_end_offset, resource_end_address, InitialPageTableRegionSizeMax, g_initial_page_allocator); + SetupInitialIdentityMapping(init_pt, base_address, bss_end_offset, resource_end_address, InitialPageTableRegionSizeMax, g_initial_page_allocator, reinterpret_cast(base_address + sysreg_offset)); /* Generate a random slide for the kernel's base address. */ const KVirtualAddress virtual_base_address = GetRandomKernelBaseAddress(init_pt, base_address, bss_end_offset); From 1491a7b1592b24c651848f245ddaf9b1fc8d9147 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 03:01:52 -0700 Subject: [PATCH 009/238] kern: on second thought, move vectors back to end of text --- mesosphere/kernel/kernel.ld | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mesosphere/kernel/kernel.ld b/mesosphere/kernel/kernel.ld index d54cb4a7a..356cea88c 100644 --- a/mesosphere/kernel/kernel.ld +++ b/mesosphere/kernel/kernel.ld @@ -29,15 +29,6 @@ SECTIONS . = ALIGN(8); } :code - /* .vectors. */ - . = ALIGN(2K); - __vectors_start__ = . ; - .vectors : - { - KEEP( *(.vectors) ) - . = ALIGN(8); - } :code - .init : { KEEP( *(.init) ) @@ -67,6 +58,15 @@ SECTIONS . = ALIGN(8); } :code + /* .vectors. */ + . = ALIGN(2K); + __vectors_start__ = . ; + .vectors : + { + KEEP( *(.vectors) ) + . = ALIGN(8); + } :code + /* =========== RODATA section =========== */ . = ALIGN(0x1000); __rodata_start = . ; From ec96203cb7f1b9ab44dbf9446f1352852e791a79 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 03:10:08 -0700 Subject: [PATCH 010/238] kern: remove unnecessary fields from InitArgs (0x80 -> 0x40) --- .../arch/arm64/init/kern_k_init_arguments.hpp | 10 ------ .../arch/arm64/kern_assembly_offsets.h | 17 ++++----- .../nintendo/nx/kern_k_sleep_manager.cpp | 36 +++++-------------- .../source/arch/arm64/init/kern_init_core.cpp | 20 +++++------ 4 files changed, 22 insertions(+), 61 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp index 94206bfae..b8e3a9565 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp @@ -19,13 +19,8 @@ namespace ams::kern::init { struct alignas(util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)) KInitArguments { - u64 ttbr0; - u64 ttbr1; - u64 tcr; - u64 mair; u64 cpuactlr; u64 cpuectlr; - u64 sctlr; u64 sp; u64 entrypoint; u64 argument; @@ -33,13 +28,8 @@ namespace ams::kern::init { static_assert(alignof(KInitArguments) == util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE)); static_assert(sizeof(KInitArguments) == std::max(INIT_ARGUMENTS_SIZE, util::CeilingPowerOfTwo(INIT_ARGUMENTS_SIZE))); - static_assert(AMS_OFFSETOF(KInitArguments, ttbr0) == INIT_ARGUMENTS_TTBR0); - static_assert(AMS_OFFSETOF(KInitArguments, ttbr1) == INIT_ARGUMENTS_TTBR1); - static_assert(AMS_OFFSETOF(KInitArguments, tcr) == INIT_ARGUMENTS_TCR); - static_assert(AMS_OFFSETOF(KInitArguments, mair) == INIT_ARGUMENTS_MAIR); static_assert(AMS_OFFSETOF(KInitArguments, cpuactlr) == INIT_ARGUMENTS_CPUACTLR); static_assert(AMS_OFFSETOF(KInitArguments, cpuectlr) == INIT_ARGUMENTS_CPUECTLR); - static_assert(AMS_OFFSETOF(KInitArguments, sctlr) == INIT_ARGUMENTS_SCTLR); static_assert(AMS_OFFSETOF(KInitArguments, sp) == INIT_ARGUMENTS_SP); static_assert(AMS_OFFSETOF(KInitArguments, entrypoint) == INIT_ARGUMENTS_ENTRYPOINT); static_assert(AMS_OFFSETOF(KInitArguments, argument) == INIT_ARGUMENTS_ARGUMENT); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h index b585f44eb..46d956e61 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_offsets.h @@ -246,17 +246,12 @@ #define THREAD_LOCAL_REGION_SIZE 0x200 /* ams::kern::init::KInitArguments, https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp */ -#define INIT_ARGUMENTS_SIZE 0x50 -#define INIT_ARGUMENTS_TTBR0 0x00 -#define INIT_ARGUMENTS_TTBR1 0x08 -#define INIT_ARGUMENTS_TCR 0x10 -#define INIT_ARGUMENTS_MAIR 0x18 -#define INIT_ARGUMENTS_CPUACTLR 0x20 -#define INIT_ARGUMENTS_CPUECTLR 0x28 -#define INIT_ARGUMENTS_SCTLR 0x30 -#define INIT_ARGUMENTS_SP 0x38 -#define INIT_ARGUMENTS_ENTRYPOINT 0x40 -#define INIT_ARGUMENTS_ARGUMENT 0x48 +#define INIT_ARGUMENTS_SIZE 0x28 +#define INIT_ARGUMENTS_CPUACTLR 0x00 +#define INIT_ARGUMENTS_CPUECTLR 0x08 +#define INIT_ARGUMENTS_SP 0x10 +#define INIT_ARGUMENTS_ENTRYPOINT 0x18 +#define INIT_ARGUMENTS_ARGUMENT 0x20 /* ams::kern::KScheduler (::SchedulingState), https://github.com/Atmosphere-NX/Atmosphere/blob/master/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp */ /* NOTE: Due to constraints on ldarb relative offsets, KSCHEDULER_NEEDS_SCHEDULING cannot trivially be changed, and will require assembly edits. */ diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp index 00b606ff5..bb782d390 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp @@ -32,7 +32,6 @@ namespace ams::kern::board::nintendo::nx { class SavedSystemRegisters { private: u64 ttbr0_el1; - u64 tcr_el1; u64 elr_el1; u64 sp_el0; u64 spsr_el1; @@ -92,7 +91,6 @@ namespace ams::kern::board::nintendo::nx { void SavedSystemRegisters::Save() { /* Save system registers. */ this->ttbr0_el1 = cpu::GetTtbr0El1(); - this->tcr_el1 = cpu::GetTcrEl1(); this->tpidr_el0 = cpu::GetTpidrEl0(); this->elr_el1 = cpu::GetElrEl1(); this->sp_el0 = cpu::GetSpEl0(); @@ -408,7 +406,6 @@ namespace ams::kern::board::nintendo::nx { /* Restore system registers. */ cpu::SetTtbr0El1 (this->ttbr0_el1); - cpu::SetTcrEl1 (this->tcr_el1); cpu::SetTpidrEl0 (this->tpidr_el0); cpu::SetElrEl1 (this->elr_el1); cpu::SetSpEl0 (this->sp_el0); @@ -515,24 +512,6 @@ namespace ams::kern::board::nintendo::nx { /* Save the system registers for the current core. */ g_sleep_system_registers[core_id].Save(); - /* Change the translation tables to use the kernel table. */ - { - /* Get the current value of the translation control register. */ - const u64 tcr = cpu::GetTcrEl1(); - - /* Disable translation table walks on tlb miss. */ - cpu::TranslationControlRegisterAccessor(tcr).SetEpd0(true).Store(); - cpu::EnsureInstructionConsistency(); - - /* Change the translation table base (ttbr0) to use the kernel table. */ - cpu::SetTtbr0El1(Kernel::GetKernelPageTable().GetIdentityMapTtbr0(core_id)); - cpu::EnsureInstructionConsistency(); - - /* Enable translation table walks on tlb miss. */ - cpu::TranslationControlRegisterAccessor(tcr).SetEpd0(false).Store(); - cpu::EnsureInstructionConsistency(); - } - /* Invalidate the entire tlb. */ cpu::InvalidateEntireTlb(); @@ -552,13 +531,14 @@ namespace ams::kern::board::nintendo::nx { /* Setup the initial arguments. */ { - init_args->ttbr0 = cpu::GetTtbr0El1(); - init_args->ttbr1 = cpu::GetTtbr1El1(); - init_args->tcr = cpu::GetTcrEl1(); - init_args->mair = cpu::GetMairEl1(); - init_args->cpuactlr = cpu::GetCpuActlrEl1(); - init_args->cpuectlr = cpu::GetCpuEctlrEl1(); - init_args->sctlr = cpu::GetSctlrEl1(); + /* Determine whether we're running on a cortex-a53 or a-57. */ + cpu::MainIdRegisterAccessor midr_el1; + const auto implementer = midr_el1.GetImplementer(); + const auto primary_part = midr_el1.GetPrimaryPartNumber(); + const bool needs_cpu_ctlr = (implementer == cpu::MainIdRegisterAccessor::Implementer::ArmLimited) && (primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA57 || primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA53); + + init_args->cpuactlr = needs_cpu_ctlr ? cpu::GetCpuActlrEl1() : 0; + init_args->cpuectlr = needs_cpu_ctlr ? cpu::GetCpuEctlrEl1() : 0; init_args->sp = 0; init_args->entrypoint = reinterpret_cast(::ams::kern::board::nintendo::nx::KSleepManager::ResumeEntry); init_args->argument = sleep_buffer; diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index c8139fb49..5058e0716 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -86,27 +86,23 @@ namespace ams::kern::init { } void SetupInitialArguments() { + /* Determine whether we're running on a cortex-a53 or a-57. */ + cpu::MainIdRegisterAccessor midr_el1; + const auto implementer = midr_el1.GetImplementer(); + const auto primary_part = midr_el1.GetPrimaryPartNumber(); + const bool needs_cpu_ctlr = (implementer == cpu::MainIdRegisterAccessor::Implementer::ArmLimited) && (primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA57 || primary_part == cpu::MainIdRegisterAccessor::PrimaryPartNumber::CortexA53); + /* Get parameters for initial arguments. */ - const u64 ttbr0 = cpu::GetTtbr0El1(); - const u64 ttbr1 = cpu::GetTtbr1El1(); - const u64 tcr = cpu::GetTcrEl1(); - const u64 mair = cpu::GetMairEl1(); - const u64 cpuactlr = cpu::GetCpuActlrEl1(); - const u64 cpuectlr = cpu::GetCpuEctlrEl1(); - const u64 sctlr = cpu::GetSctlrEl1(); + const u64 cpuactlr = needs_cpu_ctlr ? cpu::GetCpuActlrEl1() : 0; + const u64 cpuectlr = needs_cpu_ctlr ? cpu::GetCpuEctlrEl1() : 0; for (s32 i = 0; i < static_cast(cpu::NumCores); ++i) { /* Get the arguments. */ KInitArguments *init_args = g_init_arguments + i; /* Set the arguments. */ - init_args->ttbr0 = ttbr0; - init_args->ttbr1 = ttbr1; - init_args->tcr = tcr; - init_args->mair = mair; init_args->cpuactlr = cpuactlr; init_args->cpuectlr = cpuectlr; - init_args->sctlr = sctlr; init_args->sp = GetInteger(KMemoryLayout::GetMainStackTopAddress(i)) - sizeof(KThread::StackParameters); init_args->entrypoint = reinterpret_cast(::ams::kern::init::InvokeMain); init_args->argument = static_cast(i); From c72ba356843720d770bb4540d17d1814749dabd3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 03:21:06 -0700 Subject: [PATCH 011/238] kern: add speculation barriers after eret --- .../arch/arm64/kern_assembly_macros.h | 5 +++++ .../arch/arm64/svc/kern_svc_exception_asm.s | 2 +- .../arch/arm64/svc/kern_svc_handlers_asm.s | 8 ++++---- .../kernel/source/arch/arm64/init/start.s | 2 +- .../arch/arm64/kern_exception_handlers_asm.s | 18 +++++++++--------- .../arch/arm64/kern_k_thread_context_asm.s | 6 ++---- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h index 97b50afb6..8dfafdc7b 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_assembly_macros.h @@ -94,3 +94,8 @@ label_done: ENABLE_FPU(xtmp1) \ GET_THREAD_CONTEXT_AND_RESTORE_FPCR_FPSR(ctx, xtmp1, xtmp2, wtmp1, wtmp2) \ RESTORE_FPU32_ALL_REGISTERS(ctx, xtmp1) + +#define ERET_WITH_SPECULATION_BARRIER \ + eret; \ + dsb nsh; \ + isb diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s index 2194c594d..c3ee6a077 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_exception_asm.s @@ -130,4 +130,4 @@ _ZN3ams4kern3svc14RestoreContextEm: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - eret + ERET_WITH_SPECULATION_BARRIER diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s index d795c6aae..6e6f07a30 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s @@ -194,7 +194,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - eret + ERET_WITH_SPECULATION_BARRIER 5: /* Return from SVC. */ @@ -297,7 +297,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::SvcHandler32() */ .section .text._ZN3ams4kern4arch5arm6412SvcHandler32Ev, "ax", %progbits @@ -467,7 +467,7 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - eret + ERET_WITH_SPECULATION_BARRIER 5: /* Return from SVC. */ @@ -547,4 +547,4 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev: /* Return. */ add sp, sp, #(EXCEPTION_CONTEXT_SIZE) - eret + ERET_WITH_SPECULATION_BARRIER diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index 0a11c8200..5d9084b08 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -377,7 +377,7 @@ _ZN3ams4kern4init16JumpFromEL2ToEL1Ev: mov x0, #0xC5 msr spsr_el2, x0 - eret + ERET_WITH_SPECULATION_BARRIER #endif /* ams::kern::init::DisableMmuAndCaches() */ diff --git a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s index a23cebc0e..d81eb7e89 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s @@ -64,7 +64,7 @@ _ZN3ams4kern4arch5arm6422EL1IrqExceptionHandlerEv: add sp, sp, #(8 * 24) /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::EL0A64IrqExceptionHandler() */ .section .text._ZN3ams4kern4arch5arm6425EL0A64IrqExceptionHandlerEv, "ax", %progbits @@ -150,7 +150,7 @@ _ZN3ams4kern4arch5arm6425EL0A64IrqExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::EL0A32IrqExceptionHandler() */ .section .text._ZN3ams4kern4arch5arm6425EL0A32IrqExceptionHandlerEv, "ax", %progbits @@ -218,7 +218,7 @@ _ZN3ams4kern4arch5arm6425EL0A32IrqExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::EL0SynchronousExceptionHandler() */ .section .text._ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv, "ax", %progbits @@ -331,7 +331,7 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER 4: /* SVC from aarch32. */ ldp x16, x17, [sp], 16 @@ -377,7 +377,7 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: ldp x16, x17, [sp], 16 /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::EL1SynchronousExceptionHandler() */ @@ -441,7 +441,7 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: /* Return false. */ mov x0, #0x0 msr elr_el1, x30 - eret + ERET_WITH_SPECULATION_BARRIER 2: /* The exception wasn't an triggered by copying memory from userspace. */ ldr x0, [sp, #8] @@ -519,7 +519,7 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: mrs x0, tpidr_el1 /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::FpuAccessExceptionHandler() */ @@ -542,7 +542,7 @@ _ZN3ams4kern4arch5arm6425FpuAccessExceptionHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::EL1SystemErrorHandler() */ .section .text._ZN3ams4kern4arch5arm6421EL1SystemErrorHandlerEv, "ax", %progbits @@ -680,5 +680,5 @@ _ZN3ams4kern4arch5arm6421EL0SystemErrorHandlerEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return from the exception. */ - eret + ERET_WITH_SPECULATION_BARRIER diff --git a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s index 080048598..362adc712 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #include +#include /* ams::kern::arch::arm64::UserModeThreadStarter() */ .section .text._ZN3ams4kern4arch5arm6421UserModeThreadStarterEv, "ax", %progbits @@ -62,7 +63,7 @@ _ZN3ams4kern4arch5arm6421UserModeThreadStarterEv: add sp, sp, #(EXCEPTION_CONTEXT_SIZE) /* Return to EL0 */ - eret + ERET_WITH_SPECULATION_BARRIER /* ams::kern::arch::arm64::SupervisorModeThreadStarter() */ .section .text._ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv, "ax", %progbits @@ -84,6 +85,3 @@ _ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv: /* Mask I bit in DAIF */ msr daifclr, #2 br x1 - - /* This should never execute, but Nintendo includes an ERET here. */ - eret From cfd2d5b01264b6a99bd62593ff17b9bd8dadd0c2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 03:27:45 -0700 Subject: [PATCH 012/238] kern: clear new pages in init page allocator, not init page table --- .../arch/arm64/init/kern_k_init_page_table.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index f47407c89..8b9a6953c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -87,9 +87,8 @@ namespace ams::kern::arch::arm64::init { template static ALWAYS_INLINE KPhysicalAddress AllocateNewPageTable(PageAllocator &allocator, u64 phys_to_virt_offset) { - auto address = allocator.Allocate(PageSize); - ClearNewPageTable(address, phys_to_virt_offset); - return address; + MESOSPHERE_UNUSED(phys_to_virt_offset); + return allocator.Allocate(PageSize); } static ALWAYS_INLINE void ClearNewPageTable(KPhysicalAddress address, u64 phys_to_virt_offset) { @@ -883,6 +882,12 @@ namespace ams::kern::arch::arm64::init { const size_t ind_max = ((aligned_end - aligned_start) / align) - 1; while (true) { if (const uintptr_t random_address = aligned_start + (KSystemControl::Init::GenerateRandomRange(0, ind_max) * align); this->TryAllocate(random_address, size)) { + /* Clear the allocated pages. */ + volatile u64 *ptr = reinterpret_cast(random_address); + for (size_t i = 0; i < size / sizeof(u64); ++i) { + ptr[i] = 0; + } + return random_address; } } From 3b8f65d502a188ed8d2b788ad74bec495bc8d058 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 04:26:30 -0700 Subject: [PATCH 013/238] kern: update initial process load logic to do per-segment mapping/decompression --- .../kern_k_initial_process_reader.hpp | 2 +- .../source/kern_initial_process.cpp | 43 +--- .../source/kern_k_initial_process_reader.cpp | 196 +++++++++++++++--- 3 files changed, 169 insertions(+), 72 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp index 8ee175e96..8d22c3b73 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_initial_process_reader.hpp @@ -133,7 +133,7 @@ namespace ams::kern { } Result MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const; - Result Load(KProcessAddress address, const ams::svc::CreateProcessParameter ¶ms, KProcessAddress src) const; + void Load(const KPageGroup &pg, KVirtualAddress data) const; Result SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter ¶ms) const; }; diff --git a/libraries/libmesosphere/source/kern_initial_process.cpp b/libraries/libmesosphere/source/kern_initial_process.cpp index 6b22a1784..282bba103 100644 --- a/libraries/libmesosphere/source/kern_initial_process.cpp +++ b/libraries/libmesosphere/source/kern_initial_process.cpp @@ -156,40 +156,14 @@ namespace ams::kern { KPageGroup *process_pg = std::addressof(pg); ON_SCOPE_EXIT { process_pg->Close(); }; - /* Get the temporary region. */ - const auto &temp_region = KMemoryLayout::GetTempRegion(); - MESOSPHERE_ABORT_UNLESS(temp_region.GetEndAddress() != 0); - - /* Map the process's memory into the temporary region. */ - KProcessAddress temp_address = Null; - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().MapPageGroup(std::addressof(temp_address), pg, temp_region.GetAddress(), temp_region.GetSize() / PageSize, KMemoryState_Kernel, KMemoryPermission_KernelReadWrite)); - - /* Setup the new page group's memory, so that we can load the process. */ - { - /* Copy the unaligned ending of the compressed binary. */ - if (const size_t unaligned_size = binary_size - util::AlignDown(binary_size, PageSize); unaligned_size != 0) { - std::memcpy(GetVoidPointer(temp_address + process_size - unaligned_size), GetVoidPointer(data + binary_size - unaligned_size), unaligned_size); - } - - /* Copy the aligned part of the compressed binary. */ - if (const size_t aligned_size = util::AlignDown(binary_size, PageSize); aligned_size != 0 && src_pool == dst_pool) { - std::memmove(GetVoidPointer(temp_address + process_size - binary_size), GetVoidPointer(temp_address), aligned_size); - } else { - if (src_pool != dst_pool) { - std::memcpy(GetVoidPointer(temp_address + process_size - binary_size), GetVoidPointer(data), aligned_size); - Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(data), aligned_size / PageSize); - } - } - - /* Clear the first part of the memory. */ - std::memset(GetVoidPointer(temp_address), 0, process_size - binary_size); - } - /* Load the process. */ - MESOSPHERE_R_ABORT_UNLESS(reader.Load(temp_address, params, temp_address + process_size - binary_size)); + reader.Load(pg, data); - /* Unmap the temporary mapping. */ - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().UnmapPageGroup(temp_address, pg, KMemoryState_Kernel)); + /* If necessary, close/release the aligned part of the data we just loaded. */ + if (const size_t aligned_bin_size = util::AlignDown(binary_size, PageSize); aligned_bin_size != 0 && src_pool != dst_pool) { + Kernel::GetMemoryManager().Close(KMemoryLayout::GetLinearPhysicalAddress(data), aligned_bin_size / PageSize); + Kernel::GetSystemResourceLimit().Release(ams::svc::LimitableResource_PhysicalMemoryMax, aligned_bin_size); + } /* Create a KProcess object. */ new_process = KProcess::Create(); @@ -242,11 +216,6 @@ namespace ams::kern { MESOSPHERE_R_ABORT_UNLESS(new_process->Initialize(params, *process_pg, reader.GetCapabilities(), reader.GetNumCapabilities(), std::addressof(Kernel::GetSystemResourceLimit()), dst_pool, reader.IsImmortal())); } - /* Release the memory that was previously reserved. */ - if (const size_t aligned_bin_size = util::AlignDown(binary_size, PageSize); aligned_bin_size != 0 && src_pool != dst_pool) { - Kernel::GetSystemResourceLimit().Release(ams::svc::LimitableResource_PhysicalMemoryMax, aligned_bin_size); - } - /* Set the process's memory permissions. */ MESOSPHERE_R_ABORT_UNLESS(reader.SetMemoryPermissions(new_process->GetPageTable(), params)); diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index ff5f21a61..6a9e3718b 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -73,6 +73,119 @@ namespace ams::kern { } } + NOINLINE void LoadInitialProcessSegment(const KPageGroup &pg, size_t seg_offset, size_t seg_size, size_t binary_size, KVirtualAddress data, bool compressed) { + /* Save the original binary extents, for later use. */ + const KPhysicalAddress binary_phys = KMemoryLayout::GetLinearPhysicalAddress(data); + + /* Create a page group representing the segment. */ + KPageGroup segment_pg(Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer()); + if (size_t remaining_size = util::AlignUp(seg_size, PageSize); remaining_size != 0) { + /* Find the pages whose data corresponds to the segment. */ + size_t cur_offset = 0; + for (auto it = pg.begin(); it != pg.end() && remaining_size > 0; ++it) { + /* Get the current size. */ + const size_t cur_size = it->GetSize(); + + /* Determine if the offset is in range. */ + const size_t rel_diff = seg_offset - cur_offset; + const bool is_before = cur_offset <= seg_offset; + cur_offset += cur_size; + if (is_before && seg_offset < cur_offset) { + /* It is, so add the block. */ + const size_t block_size = std::min(cur_size - rel_diff, remaining_size); + MESOSPHERE_R_ABORT_UNLESS(segment_pg.AddBlock(it->GetAddress() + rel_diff, block_size / PageSize)); + + /* Advance. */ + cur_offset = seg_offset + block_size; + remaining_size -= block_size; + seg_offset += block_size; + } + } + } + + /* Setup the new page group's memory so that we can load the segment. */ + { + KVirtualAddress last_block = Null; + KVirtualAddress last_data = Null; + size_t last_copy_size = 0; + size_t last_clear_size = 0; + size_t remaining_copy_size = binary_size; + for (const auto &block : segment_pg) { + /* Get the current block extents. */ + const auto block_addr = block.GetAddress(); + const size_t block_size = block.GetSize(); + if (remaining_copy_size > 0) { + /* Determine if we need to copy anything. */ + const size_t cur_size = std::min(block_size, remaining_copy_size); + + /* NOTE: The first block may potentially overlap the binary we want to copy to. */ + /* Consider e.g. the case where the overall compressed image has size 0x40000, seg_offset is 0x30000, and binary_size is > 0x20000. */ + /* Suppose too that data points, say, 0x18000 into the compressed image. */ + /* Suppose finally that we simply naively copy in order. */ + /* The first iteration of this loop will perform an 0x10000 copy from image+0x18000 to image + 0x30000 (as there is no overlap). */ + /* The second iteration will perform a copy from image+0x28000 to . */ + /* However, the first copy will have trashed the data in the second copy. */ + /* Thus, we must copy the first block after-the-fact to avoid potentially trashing data in the overlap case. */ + /* It is guaranteed by pre-condition that only the very first block can overlap with the physical binary, so we can simply memmove it at the end. */ + if (last_block != Null) { + /* This is guaranteed by pre-condition, but for ease of debugging, check for no overlap. */ + AMS_ASSERT(!util::HasOverlap(GetInteger(binary_phys), binary_size, GetInteger(block_addr), cur_size)); + + /* We need to copy. */ + std::memcpy(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr)), GetVoidPointer(data), cur_size); + + /* If we need to, clear past where we're copying. */ + if (cur_size != block_size) { + std::memset(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr + cur_size)), 0, block_size - cur_size); + } + + /* Advance. */ + remaining_copy_size -= cur_size; + data += cur_size; + } else { + /* Save the first block, which may potentially overlap, so that we can copy it later. */ + last_block = KMemoryLayout::GetLinearVirtualAddress(block_addr); + last_data = data; + last_copy_size = cur_size; + last_clear_size = block_size - cur_size; + + /* Advance. */ + remaining_copy_size -= cur_size; + data += cur_size; + } + } else { + /* We don't have data to copy, so we should just clear the pages. */ + std::memset(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr)), 0, block_size); + } + } + + /* Handle a last block. */ + if (last_copy_size != 0) { + if (last_block != last_data) { + std::memmove(GetVoidPointer(last_block), GetVoidPointer(last_data), last_copy_size); + } + if (last_clear_size != 0) { + std::memset(GetVoidPointer(last_block + last_copy_size), 0, last_clear_size); + } + } + } + + /* If compressed, uncompress the data. */ + if (compressed) { + /* Get the temporary region. */ + const auto &temp_region = KMemoryLayout::GetTempRegion(); + MESOSPHERE_ABORT_UNLESS(temp_region.GetEndAddress() != 0); + + /* Map the process's memory into the temporary region. */ + KProcessAddress temp_address = Null; + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().MapPageGroup(std::addressof(temp_address), segment_pg, temp_region.GetAddress(), temp_region.GetSize() / PageSize, KMemoryState_Kernel, KMemoryPermission_KernelReadWrite)); + ON_SCOPE_EXIT { MESOSPHERE_R_ABORT_UNLESS(Kernel::GetKernelPageTable().UnmapPageGroup(temp_address, segment_pg, KMemoryState_Kernel)); }; + + /* Uncompress the data. */ + BlzUncompress(GetVoidPointer(temp_address + binary_size)); + } + } + } Result KInitialProcessReader::MakeCreateProcessParameter(ams::svc::CreateProcessParameter *out, bool enable_aslr) const { @@ -113,11 +226,13 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(start_address == 0); /* Set fields in parameter. */ - out->code_address = map_start + start_address; - out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize; - out->program_id = m_kip_header.GetProgramId(); - out->version = m_kip_header.GetVersion(); - out->flags = 0; + out->code_address = map_start + start_address; + out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize; + out->program_id = m_kip_header.GetProgramId(); + out->version = m_kip_header.GetVersion(); + out->flags = 0; + out->reslimit = ams::svc::InvalidHandle; + out->system_resource_num_pages = 0; MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize)); /* Copy name field. */ @@ -146,42 +261,55 @@ namespace ams::kern { R_SUCCEED(); } - Result KInitialProcessReader::Load(KProcessAddress address, const ams::svc::CreateProcessParameter ¶ms, KProcessAddress src) const { + void KInitialProcessReader::Load(const KPageGroup &pg, KVirtualAddress data) const { /* Prepare to layout the data. */ - const KProcessAddress rx_address = address + m_kip_header.GetRxAddress(); - const KProcessAddress ro_address = address + m_kip_header.GetRoAddress(); - const KProcessAddress rw_address = address + m_kip_header.GetRwAddress(); - const u8 *rx_binary = GetPointer(src); - const u8 *ro_binary = rx_binary + m_kip_header.GetRxCompressedSize(); - const u8 *rw_binary = ro_binary + m_kip_header.GetRoCompressedSize(); + const KVirtualAddress rx_data = data; + const KVirtualAddress ro_data = rx_data + m_kip_header.GetRxCompressedSize(); + const KVirtualAddress rw_data = ro_data + m_kip_header.GetRoCompressedSize(); + const size_t rx_size = m_kip_header.GetRxSize(); + const size_t ro_size = m_kip_header.GetRoSize(); + const size_t rw_size = m_kip_header.GetRwSize(); - /* Copy text. */ - if (util::AlignUp(m_kip_header.GetRxSize(), PageSize)) { - std::memmove(GetVoidPointer(rx_address), rx_binary, m_kip_header.GetRxCompressedSize()); - if (m_kip_header.IsRxCompressed()) { - BlzUncompress(GetVoidPointer(rx_address + m_kip_header.GetRxCompressedSize())); + /* If necessary, setup bss. */ + if (const size_t bss_size = m_kip_header.GetBssSize(); bss_size > 0) { + /* Determine how many additional pages are needed for bss. */ + const u64 rw_end = util::AlignUp(m_kip_header.GetRwAddress() + m_kip_header.GetRwSize(), PageSize); + const u64 bss_end = util::AlignUp(m_kip_header.GetBssAddress() + m_kip_header.GetBssSize(), PageSize); + if (rw_end != bss_end) { + /* Find the pages corresponding to bss. */ + size_t cur_offset = 0; + size_t remaining_size = bss_end - rw_end; + size_t bss_offset = rw_end - m_kip_header.GetRxAddress(); + for (auto it = pg.begin(); it != pg.end() && remaining_size > 0; ++it) { + /* Get the current size. */ + const size_t cur_size = it->GetSize(); + + /* Determine if the offset is in range. */ + const size_t rel_diff = bss_offset - cur_offset; + const bool is_before = cur_offset <= bss_offset; + cur_offset += cur_size; + if (is_before && bss_offset < cur_offset) { + /* It is, so clear the bss range. */ + const size_t block_size = std::min(cur_size - rel_diff, remaining_size); + std::memset(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(it->GetAddress() + rel_diff)), 0, block_size); + + /* Advance. */ + cur_offset = bss_offset + block_size; + remaining_size -= block_size; + bss_offset += block_size; + } + } } } - /* Copy rodata. */ - if (util::AlignUp(m_kip_header.GetRoSize(), PageSize)) { - std::memmove(GetVoidPointer(ro_address), ro_binary, m_kip_header.GetRoCompressedSize()); - if (m_kip_header.IsRoCompressed()) { - BlzUncompress(GetVoidPointer(ro_address + m_kip_header.GetRoCompressedSize())); - } - } + /* Load .rwdata. */ + LoadInitialProcessSegment(pg, m_kip_header.GetRwAddress() - m_kip_header.GetRxAddress(), rw_size, m_kip_header.GetRwCompressedSize(), rw_data, m_kip_header.IsRwCompressed()); - /* Copy rwdata. */ - if (util::AlignUp(m_kip_header.GetRwSize(), PageSize)) { - std::memmove(GetVoidPointer(rw_address), rw_binary, m_kip_header.GetRwCompressedSize()); - if (m_kip_header.IsRwCompressed()) { - BlzUncompress(GetVoidPointer(rw_address + m_kip_header.GetRwCompressedSize())); - } - } + /* Load .rodata. */ + LoadInitialProcessSegment(pg, m_kip_header.GetRoAddress() - m_kip_header.GetRxAddress(), ro_size, m_kip_header.GetRoCompressedSize(), ro_data, m_kip_header.IsRoCompressed()); - MESOSPHERE_UNUSED(params); - - R_SUCCEED(); + /* Load .text. */ + LoadInitialProcessSegment(pg, m_kip_header.GetRxAddress() - m_kip_header.GetRxAddress(), rx_size, m_kip_header.GetRxCompressedSize(), rx_data, m_kip_header.IsRxCompressed()); } Result KInitialProcessReader::SetMemoryPermissions(KProcessPageTable &page_table, const ams::svc::CreateProcessParameter ¶ms) const { From ae2c25e9c80daf51115e4599aca1290c0e1177ce Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 05:00:23 -0700 Subject: [PATCH 014/238] kern: update KMemoryState, remove bijection (separate IoRegister/IoMemory) --- .../arch/arm64/kern_k_process_page_table.hpp | 9 +- .../mesosphere/kern_k_memory_block.hpp | 61 +++--- .../mesosphere/kern_k_page_table_base.hpp | 28 +-- .../source/kern_k_debug_base.cpp | 8 +- .../source/kern_k_memory_block_manager.cpp | 3 +- .../source/kern_k_page_table_base.cpp | 185 +++++++++--------- .../source/svc/kern_svc_io_pool.cpp | 4 +- .../include/vapours/svc/svc_types_common.hpp | 9 +- 8 files changed, 163 insertions(+), 144 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 0d074a6b2..135c6696e 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -154,16 +154,16 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size)); } - Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size) { - R_RETURN(m_page_table.ReadDebugIoMemory(buffer, address, size)); + Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state) { + R_RETURN(m_page_table.ReadDebugIoMemory(buffer, address, size, state)); } Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size) { R_RETURN(m_page_table.WriteDebugMemory(address, buffer, size)); } - Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size) { - R_RETURN(m_page_table.WriteDebugIoMemory(address, buffer, size)); + Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size, KMemoryState state) { + R_RETURN(m_page_table.WriteDebugIoMemory(address, buffer, size, state)); } Result LockForMapDeviceAddressSpace(bool *out_is_io, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned, bool check_heap) { @@ -296,6 +296,7 @@ namespace ams::kern::arch::arm64 { bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const { return m_page_table.IsInUnsafeAliasRegion(addr, size); } bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { return m_page_table.CanContain(addr, size, state); } + bool CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const { return m_page_table.CanContain(addr, size, state); } KProcessAddress GetAddressSpaceStart() const { return m_page_table.GetAddressSpaceStart(); } KProcessAddress GetHeapRegionStart() const { return m_page_table.GetHeapRegionStart(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index faed32239..eacf909af 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -44,6 +44,7 @@ namespace ams::kern { KMemoryState_FlagCanChangeAttribute = (1 << 24), KMemoryState_FlagCanCodeMemory = (1 << 25), KMemoryState_FlagLinearMapped = (1 << 26), + KMemoryState_FlagCanPermissionLock = (1 << 27), KMemoryState_FlagsData = KMemoryState_FlagCanReprotect | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonDeviceIpc | KMemoryState_FlagCanUseNonSecureIpc | @@ -66,18 +67,22 @@ namespace ams::kern { KMemoryState_Free = ams::svc::MemoryState_Free, - KMemoryState_Io = ams::svc::MemoryState_Io | KMemoryState_FlagMapped | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap, - KMemoryState_Static = ams::svc::MemoryState_Static | KMemoryState_FlagMapped | KMemoryState_FlagCanQueryPhysical, + + KMemoryState_IoMemory = ams::svc::MemoryState_Io | KMemoryState_FlagMapped | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap, + KMemoryState_IoRegister = ams::svc::MemoryState_Io | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap, + + + KMemoryState_Static = ams::svc::MemoryState_Static | KMemoryState_FlagCanQueryPhysical, KMemoryState_Code = ams::svc::MemoryState_Code | KMemoryState_FlagsCode | KMemoryState_FlagCanMapProcess, - KMemoryState_CodeData = ams::svc::MemoryState_CodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeMemory, + KMemoryState_CodeData = ams::svc::MemoryState_CodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeMemory | KMemoryState_FlagCanPermissionLock, KMemoryState_Normal = ams::svc::MemoryState_Normal | KMemoryState_FlagsData | KMemoryState_FlagCanCodeMemory, KMemoryState_Shared = ams::svc::MemoryState_Shared | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped, /* KMemoryState_Alias was removed after 1.0.0. */ KMemoryState_AliasCode = ams::svc::MemoryState_AliasCode | KMemoryState_FlagsCode | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeAlias, - KMemoryState_AliasCodeData = ams::svc::MemoryState_AliasCodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeAlias | KMemoryState_FlagCanCodeMemory, - + KMemoryState_AliasCodeData = ams::svc::MemoryState_AliasCodeData | KMemoryState_FlagsData | KMemoryState_FlagCanMapProcess | KMemoryState_FlagCanCodeAlias | KMemoryState_FlagCanCodeMemory + | KMemoryState_FlagCanPermissionLock, KMemoryState_Ipc = ams::svc::MemoryState_Ipc | KMemoryState_FlagsMisc | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, @@ -85,7 +90,7 @@ namespace ams::kern { KMemoryState_Stack = ams::svc::MemoryState_Stack | KMemoryState_FlagsMisc | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, - KMemoryState_ThreadLocal = ams::svc::MemoryState_ThreadLocal | KMemoryState_FlagMapped | KMemoryState_FlagLinearMapped, + KMemoryState_ThreadLocal = ams::svc::MemoryState_ThreadLocal | KMemoryState_FlagLinearMapped, KMemoryState_Transfered = ams::svc::MemoryState_Transfered | KMemoryState_FlagsMisc | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanChangeAttribute | KMemoryState_FlagCanUseIpc | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, @@ -104,43 +109,44 @@ namespace ams::kern { KMemoryState_NonDeviceIpc = ams::svc::MemoryState_NonDeviceIpc | KMemoryState_FlagsMisc | KMemoryState_FlagCanUseNonDeviceIpc, - KMemoryState_Kernel = ams::svc::MemoryState_Kernel | KMemoryState_FlagMapped, + KMemoryState_Kernel = ams::svc::MemoryState_Kernel, KMemoryState_GeneratedCode = ams::svc::MemoryState_GeneratedCode | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagCanDebug | KMemoryState_FlagLinearMapped, KMemoryState_CodeOut = ams::svc::MemoryState_CodeOut | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped, KMemoryState_Coverage = ams::svc::MemoryState_Coverage | KMemoryState_FlagMapped, - KMemoryState_Insecure = ams::svc::MemoryState_Insecure | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped | KMemoryState_FlagCanChangeAttribute - | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap + KMemoryState_Insecure = ams::svc::MemoryState_Insecure | KMemoryState_FlagMapped | KMemoryState_FlagReferenceCounted | KMemoryState_FlagLinearMapped | KMemoryState_FlagCanChangeAttribute + | KMemoryState_FlagCanDeviceMap | KMemoryState_FlagCanAlignedDeviceMap | KMemoryState_FlagCanQueryPhysical | KMemoryState_FlagCanUseNonSecureIpc | KMemoryState_FlagCanUseNonDeviceIpc, }; #if 1 static_assert(KMemoryState_Free == 0x00000000); - static_assert(KMemoryState_Io == 0x00182001); - static_assert(KMemoryState_Static == 0x00042002); + static_assert(KMemoryState_IoMemory == 0x00182001); + static_assert(KMemoryState_IoRegister == 0x00180001); + static_assert(KMemoryState_Static == 0x00040002); static_assert(KMemoryState_Code == 0x04DC7E03); - static_assert(KMemoryState_CodeData == 0x07FEBD04); + static_assert(KMemoryState_CodeData == 0x0FFEBD04); static_assert(KMemoryState_Normal == 0x077EBD05); static_assert(KMemoryState_Shared == 0x04402006); static_assert(KMemoryState_AliasCode == 0x04DD7E08); - static_assert(KMemoryState_AliasCodeData == 0x07FFBD09); + static_assert(KMemoryState_AliasCodeData == 0x0FFFBD09); static_assert(KMemoryState_Ipc == 0x045C3C0A); static_assert(KMemoryState_Stack == 0x045C3C0B); - static_assert(KMemoryState_ThreadLocal == 0x0400200C); + static_assert(KMemoryState_ThreadLocal == 0x0400000C); static_assert(KMemoryState_Transfered == 0x055C3C0D); static_assert(KMemoryState_SharedTransfered == 0x045C380E); static_assert(KMemoryState_SharedCode == 0x0440380F); static_assert(KMemoryState_Inaccessible == 0x00000010); static_assert(KMemoryState_NonSecureIpc == 0x045C3811); static_assert(KMemoryState_NonDeviceIpc == 0x044C2812); - static_assert(KMemoryState_Kernel == 0x00002013); + static_assert(KMemoryState_Kernel == 0x00000013); static_assert(KMemoryState_GeneratedCode == 0x04402214); static_assert(KMemoryState_CodeOut == 0x04402015); - static_assert(KMemoryState_Coverage == 0x00002016); - static_assert(KMemoryState_Insecure == 0x05583817); + static_assert(KMemoryState_Coverage == 0x00002016); /* TODO: Is this correct? */ + static_assert(KMemoryState_Insecure == 0x055C3817); #endif enum KMemoryPermission : u8 { @@ -175,16 +181,17 @@ namespace ams::kern { } enum KMemoryAttribute : u8 { - KMemoryAttribute_None = 0x00, - KMemoryAttribute_All = 0xFF, - KMemoryAttribute_UserMask = KMemoryAttribute_All, + KMemoryAttribute_None = 0x00, + KMemoryAttribute_All = 0xFF, + KMemoryAttribute_UserMask = KMemoryAttribute_All, - KMemoryAttribute_Locked = ams::svc::MemoryAttribute_Locked, - KMemoryAttribute_IpcLocked = ams::svc::MemoryAttribute_IpcLocked, - KMemoryAttribute_DeviceShared = ams::svc::MemoryAttribute_DeviceShared, - KMemoryAttribute_Uncached = ams::svc::MemoryAttribute_Uncached, + KMemoryAttribute_Locked = ams::svc::MemoryAttribute_Locked, + KMemoryAttribute_IpcLocked = ams::svc::MemoryAttribute_IpcLocked, + KMemoryAttribute_DeviceShared = ams::svc::MemoryAttribute_DeviceShared, + KMemoryAttribute_Uncached = ams::svc::MemoryAttribute_Uncached, + KMemoryAttribute_PermissionLocked = ams::svc::MemoryAttribute_PermissionLocked, - KMemoryAttribute_SetMask = KMemoryAttribute_Uncached, + KMemoryAttribute_SetMask = KMemoryAttribute_Uncached, }; enum KMemoryBlockDisableMergeAttribute : u8 { @@ -258,6 +265,10 @@ namespace ams::kern { return m_state; } + constexpr ams::svc::MemoryState GetSvcState() const { + return static_cast(m_state & KMemoryState_Mask); + } + constexpr KMemoryPermission GetPermission() const { return m_permission; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 06d735504..765ec2db4 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -241,16 +241,20 @@ namespace ams::kern { bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const { /* Even though Unsafe physical memory is KMemoryState_Normal, it must be mapped inside the alias code region. */ - return this->CanContain(addr, size, KMemoryState_AliasCode); + return this->CanContain(addr, size, ams::svc::MemoryState_AliasCode); } ALWAYS_INLINE KScopedLightLock AcquireDeviceMapLock() { return KScopedLightLock(m_device_map_lock); } - KProcessAddress GetRegionAddress(KMemoryState state) const; - size_t GetRegionSize(KMemoryState state) const; - bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const; + KProcessAddress GetRegionAddress(ams::svc::MemoryState state) const; + size_t GetRegionSize(ams::svc::MemoryState state) const; + bool CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const; + + ALWAYS_INLINE KProcessAddress GetRegionAddress(KMemoryState state) const { return this->GetRegionAddress(static_cast(state & KMemoryState_Mask)); } + ALWAYS_INLINE size_t GetRegionSize(KMemoryState state) const { return this->GetRegionSize(static_cast(state & KMemoryState_Mask)); } + ALWAYS_INLINE bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { return this->CanContain(addr, size, static_cast(state & KMemoryState_Mask)); } protected: /* NOTE: These three functions (Operate, Operate, FinalizeUpdate) are virtual functions */ /* in Nintendo's kernel. We devirtualize them, since KPageTable is the only derived */ @@ -321,7 +325,7 @@ namespace ams::kern { Result QueryInfoImpl(KMemoryInfo *out_info, ams::svc::PageInfo *out_page, KProcessAddress address) const; - Result QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, KMemoryState state) const; + Result QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, ams::svc::MemoryState state) const; Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm); Result MapPageGroupImpl(PageLinkedList *page_list, KProcessAddress address, const KPageGroup &pg, const KPageProperties properties, bool reuse_ll); @@ -335,9 +339,9 @@ namespace ams::kern { NOINLINE Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, bool is_pa_valid, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm); - Result MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm); - Result ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size); - Result WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size); + Result MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryState state, KMemoryPermission perm); + Result ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size, KMemoryState state); + Result WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size, KMemoryState state); Result SetupForIpcClient(PageLinkedList *page_list, size_t *out_blocks_needed, KProcessAddress address, size_t size, KMemoryPermission test_perm, KMemoryState dst_state); Result SetupForIpcServer(KProcessAddress *out_addr, size_t size, KProcessAddress src_addr, KMemoryPermission test_perm, KMemoryState dst_state, KPageTableBase &src_page_table, bool send); @@ -371,8 +375,8 @@ namespace ams::kern { Result SetMaxHeapSize(size_t size); Result QueryInfo(KMemoryInfo *out_info, ams::svc::PageInfo *out_page_info, KProcessAddress addr) const; Result QueryPhysicalAddress(ams::svc::PhysicalMemoryInfo *out, KProcessAddress address) const; - Result QueryStaticMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, KMemoryState_Static)); } - Result QueryIoMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, KMemoryState_Io)); } + Result QueryStaticMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, ams::svc::MemoryState_Static)); } + Result QueryIoMapping(KProcessAddress *out, KPhysicalAddress address, size_t size) const { R_RETURN(this->QueryMappingImpl(out, address, size, ams::svc::MemoryState_Io)); } Result MapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); Result UnmapMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); Result MapCodeMemory(KProcessAddress dst_address, KProcessAddress src_address, size_t size); @@ -409,10 +413,10 @@ namespace ams::kern { Result InvalidateProcessDataCache(KProcessAddress address, size_t size); Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size); - Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size); + Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state); Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size); - Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size); + Result WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size, KMemoryState state); Result LockForMapDeviceAddressSpace(bool *out_is_io, KProcessAddress address, size_t size, KMemoryPermission perm, bool is_aligned, bool check_heap); Result LockForUnmapDeviceAddressSpace(KProcessAddress address, size_t size, bool check_heap); diff --git a/libraries/libmesosphere/source/kern_k_debug_base.cpp b/libraries/libmesosphere/source/kern_k_debug_base.cpp index 3388e1ce3..418d804f3 100644 --- a/libraries/libmesosphere/source/kern_k_debug_base.cpp +++ b/libraries/libmesosphere/source/kern_k_debug_base.cpp @@ -118,12 +118,12 @@ namespace ams::kern { const size_t cur_size = std::min(remaining, info.GetEndAddress() - GetInteger(cur_address)); /* Read the memory. */ - if (info.GetState() != KMemoryState_Io) { + if (info.GetSvcState() != ams::svc::MemoryState_Io) { /* The memory is normal memory. */ R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size)); } else { /* The memory is IO memory. */ - R_TRY(target_pt.ReadDebugIoMemory(GetVoidPointer(buffer), cur_address, cur_size)); + R_TRY(target_pt.ReadDebugIoMemory(GetVoidPointer(buffer), cur_address, cur_size, info.GetState())); } /* Advance. */ @@ -181,12 +181,12 @@ namespace ams::kern { const size_t cur_size = std::min(remaining, info.GetEndAddress() - GetInteger(cur_address)); /* Read the memory. */ - if (info.GetState() != KMemoryState_Io) { + if (info.GetSvcState() != ams::svc::MemoryState_Io) { /* The memory is normal memory. */ R_TRY(target_pt.WriteDebugMemory(cur_address, GetVoidPointer(buffer), cur_size)); } else { /* The memory is IO memory. */ - R_TRY(target_pt.WriteDebugIoMemory(cur_address, GetVoidPointer(buffer), cur_size)); + R_TRY(target_pt.WriteDebugIoMemory(cur_address, GetVoidPointer(buffer), cur_size, info.GetState())); } /* Advance. */ diff --git a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp index 0a5732032..4ccf06895 100644 --- a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp @@ -21,7 +21,8 @@ namespace ams::kern { constexpr const std::pair MemoryStateNames[] = { {KMemoryState_Free , "----- Free -----"}, - {KMemoryState_Io , "Io "}, + {KMemoryState_IoMemory , "IoMemory "}, + {KMemoryState_IoRegister , "IoRegister "}, {KMemoryState_Static , "Static "}, {KMemoryState_Code , "Code "}, {KMemoryState_CodeData , "CodeData "}, diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 06aa158c6..c60a6ccdb 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -368,77 +368,77 @@ namespace ams::kern { cpu::InvalidateEntireInstructionCache(); } - KProcessAddress KPageTableBase::GetRegionAddress(KMemoryState state) const { + KProcessAddress KPageTableBase::GetRegionAddress(ams::svc::MemoryState state) const { switch (state) { - case KMemoryState_Free: - case KMemoryState_Kernel: + case ams::svc::MemoryState_Free: + case ams::svc::MemoryState_Kernel: return m_address_space_start; - case KMemoryState_Normal: + case ams::svc::MemoryState_Normal: return m_heap_region_start; - case KMemoryState_Ipc: - case KMemoryState_NonSecureIpc: - case KMemoryState_NonDeviceIpc: + case ams::svc::MemoryState_Ipc: + case ams::svc::MemoryState_NonSecureIpc: + case ams::svc::MemoryState_NonDeviceIpc: return m_alias_region_start; - case KMemoryState_Stack: + case ams::svc::MemoryState_Stack: return m_stack_region_start; - case KMemoryState_Static: - case KMemoryState_ThreadLocal: + case ams::svc::MemoryState_Static: + case ams::svc::MemoryState_ThreadLocal: return m_kernel_map_region_start; - case KMemoryState_Io: - case KMemoryState_Shared: - case KMemoryState_AliasCode: - case KMemoryState_AliasCodeData: - case KMemoryState_Transfered: - case KMemoryState_SharedTransfered: - case KMemoryState_SharedCode: - case KMemoryState_GeneratedCode: - case KMemoryState_CodeOut: - case KMemoryState_Coverage: - case KMemoryState_Insecure: + case ams::svc::MemoryState_Io: + case ams::svc::MemoryState_Shared: + case ams::svc::MemoryState_AliasCode: + case ams::svc::MemoryState_AliasCodeData: + case ams::svc::MemoryState_Transfered: + case ams::svc::MemoryState_SharedTransfered: + case ams::svc::MemoryState_SharedCode: + case ams::svc::MemoryState_GeneratedCode: + case ams::svc::MemoryState_CodeOut: + case ams::svc::MemoryState_Coverage: + case ams::svc::MemoryState_Insecure: return m_alias_code_region_start; - case KMemoryState_Code: - case KMemoryState_CodeData: + case ams::svc::MemoryState_Code: + case ams::svc::MemoryState_CodeData: return m_code_region_start; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } - size_t KPageTableBase::GetRegionSize(KMemoryState state) const { + size_t KPageTableBase::GetRegionSize(ams::svc::MemoryState state) const { switch (state) { - case KMemoryState_Free: - case KMemoryState_Kernel: + case ams::svc::MemoryState_Free: + case ams::svc::MemoryState_Kernel: return m_address_space_end - m_address_space_start; - case KMemoryState_Normal: + case ams::svc::MemoryState_Normal: return m_heap_region_end - m_heap_region_start; - case KMemoryState_Ipc: - case KMemoryState_NonSecureIpc: - case KMemoryState_NonDeviceIpc: + case ams::svc::MemoryState_Ipc: + case ams::svc::MemoryState_NonSecureIpc: + case ams::svc::MemoryState_NonDeviceIpc: return m_alias_region_end - m_alias_region_start; - case KMemoryState_Stack: + case ams::svc::MemoryState_Stack: return m_stack_region_end - m_stack_region_start; - case KMemoryState_Static: - case KMemoryState_ThreadLocal: + case ams::svc::MemoryState_Static: + case ams::svc::MemoryState_ThreadLocal: return m_kernel_map_region_end - m_kernel_map_region_start; - case KMemoryState_Io: - case KMemoryState_Shared: - case KMemoryState_AliasCode: - case KMemoryState_AliasCodeData: - case KMemoryState_Transfered: - case KMemoryState_SharedTransfered: - case KMemoryState_SharedCode: - case KMemoryState_GeneratedCode: - case KMemoryState_CodeOut: - case KMemoryState_Coverage: - case KMemoryState_Insecure: + case ams::svc::MemoryState_Io: + case ams::svc::MemoryState_Shared: + case ams::svc::MemoryState_AliasCode: + case ams::svc::MemoryState_AliasCodeData: + case ams::svc::MemoryState_Transfered: + case ams::svc::MemoryState_SharedTransfered: + case ams::svc::MemoryState_SharedCode: + case ams::svc::MemoryState_GeneratedCode: + case ams::svc::MemoryState_CodeOut: + case ams::svc::MemoryState_Coverage: + case ams::svc::MemoryState_Insecure: return m_alias_code_region_end - m_alias_code_region_start; - case KMemoryState_Code: - case KMemoryState_CodeData: + case ams::svc::MemoryState_Code: + case ams::svc::MemoryState_CodeData: return m_code_region_end - m_code_region_start; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } - bool KPageTableBase::CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { + bool KPageTableBase::CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const { const KProcessAddress end = addr + size; const KProcessAddress last = end - 1; @@ -449,32 +449,32 @@ namespace ams::kern { const bool is_in_heap = !(end <= m_heap_region_start || m_heap_region_end <= addr || m_heap_region_start == m_heap_region_end); const bool is_in_alias = !(end <= m_alias_region_start || m_alias_region_end <= addr || m_alias_region_start == m_alias_region_end); switch (state) { - case KMemoryState_Free: - case KMemoryState_Kernel: + case ams::svc::MemoryState_Free: + case ams::svc::MemoryState_Kernel: return is_in_region; - case KMemoryState_Io: - case KMemoryState_Static: - case KMemoryState_Code: - case KMemoryState_CodeData: - case KMemoryState_Shared: - case KMemoryState_AliasCode: - case KMemoryState_AliasCodeData: - case KMemoryState_Stack: - case KMemoryState_ThreadLocal: - case KMemoryState_Transfered: - case KMemoryState_SharedTransfered: - case KMemoryState_SharedCode: - case KMemoryState_GeneratedCode: - case KMemoryState_CodeOut: - case KMemoryState_Coverage: - case KMemoryState_Insecure: + case ams::svc::MemoryState_Io: + case ams::svc::MemoryState_Static: + case ams::svc::MemoryState_Code: + case ams::svc::MemoryState_CodeData: + case ams::svc::MemoryState_Shared: + case ams::svc::MemoryState_AliasCode: + case ams::svc::MemoryState_AliasCodeData: + case ams::svc::MemoryState_Stack: + case ams::svc::MemoryState_ThreadLocal: + case ams::svc::MemoryState_Transfered: + case ams::svc::MemoryState_SharedTransfered: + case ams::svc::MemoryState_SharedCode: + case ams::svc::MemoryState_GeneratedCode: + case ams::svc::MemoryState_CodeOut: + case ams::svc::MemoryState_Coverage: + case ams::svc::MemoryState_Insecure: return is_in_region && !is_in_heap && !is_in_alias; - case KMemoryState_Normal: + case ams::svc::MemoryState_Normal: MESOSPHERE_ASSERT(is_in_heap); return is_in_region && !is_in_alias; - case KMemoryState_Ipc: - case KMemoryState_NonSecureIpc: - case KMemoryState_NonDeviceIpc: + case ams::svc::MemoryState_Ipc: + case ams::svc::MemoryState_NonSecureIpc: + case ams::svc::MemoryState_NonDeviceIpc: MESOSPHERE_ASSERT(is_in_alias); return is_in_region && !is_in_heap; default: @@ -705,7 +705,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, KMemoryState state) const { + Result KPageTableBase::QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, ams::svc::MemoryState state) const { MESOSPHERE_ASSERT(!this->IsLockedByCurrentThread()); MESOSPHERE_ASSERT(out != nullptr); @@ -739,7 +739,7 @@ namespace ams::kern { if (cur_valid && cur_entry.phys_addr <= address && address + size <= cur_entry.phys_addr + cur_entry.block_size) { /* Check if this region is valid. */ const KProcessAddress mapped_address = (region_start + tot_size) + (address - cur_entry.phys_addr); - if (R_SUCCEEDED(this->CheckMemoryState(mapped_address, size, KMemoryState_All, state, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) { + if (R_SUCCEEDED(this->CheckMemoryState(mapped_address, size, KMemoryState_Mask, static_cast(util::ToUnderlying(state)), KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) { /* It is! */ *out = mapped_address; R_SUCCEED(); @@ -1899,7 +1899,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm) { + Result KPageTableBase::MapIoImpl(KProcessAddress *out, PageLinkedList *page_list, KPhysicalAddress phys_addr, size_t size, KMemoryState state, KMemoryPermission perm) { /* Check pre-conditions. */ MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); @@ -1915,7 +1915,7 @@ namespace ams::kern { const size_t region_size = m_kernel_map_region_end - m_kernel_map_region_start; const size_t region_num_pages = region_size / PageSize; - MESOSPHERE_ASSERT(this->CanContain(region_start, region_size, KMemoryState_Io)); + MESOSPHERE_ASSERT(this->CanContain(region_start, region_size, state)); /* Locate the memory region. */ const KMemoryRegion *region = KMemoryLayout::Find(phys_addr); @@ -1960,11 +1960,11 @@ namespace ams::kern { R_UNLESS(addr != Null, svc::ResultOutOfMemory()); /* Check that we can map IO here. */ - MESOSPHERE_ASSERT(this->CanContain(addr, size, KMemoryState_Io)); + MESOSPHERE_ASSERT(this->CanContain(addr, size, state)); MESOSPHERE_R_ASSERT(this->CheckMemoryState(addr, size, KMemoryState_All, KMemoryState_Free, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_None, KMemoryAttribute_None)); /* Perform mapping operation. */ - const KPageProperties properties = { perm, true, false, DisableMergeAttribute_DisableHead }; + const KPageProperties properties = { perm, state == KMemoryState_IoRegister, false, DisableMergeAttribute_DisableHead }; R_TRY(this->Operate(page_list, addr, num_pages, phys_addr, true, properties, OperationType_Map, false)); /* Set the output address. */ @@ -1987,10 +1987,10 @@ namespace ams::kern { /* Map the io memory. */ KProcessAddress addr; - R_TRY(this->MapIoImpl(std::addressof(addr), updater.GetPageList(), phys_addr, size, perm)); + R_TRY(this->MapIoImpl(std::addressof(addr), updater.GetPageList(), phys_addr, size, KMemoryState_IoRegister, perm)); /* Update the blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), addr, size / PageSize, KMemoryState_Io, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), addr, size / PageSize, KMemoryState_IoRegister, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); /* We successfully mapped the pages. */ R_SUCCEED(); @@ -2020,7 +2020,8 @@ namespace ams::kern { R_TRY(this->Operate(updater.GetPageList(), dst_address, num_pages, phys_addr, true, properties, OperationType_Map, false)); /* Update the blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages, KMemoryState_Io, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); + const auto state = mapping == ams::svc::MemoryMapping_Memory ? KMemoryState_IoMemory : KMemoryState_IoRegister; + m_memory_block_manager.Update(std::addressof(allocator), dst_address, num_pages, state, perm, KMemoryAttribute_Locked, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); /* We successfully mapped the pages. */ R_SUCCEED(); @@ -2039,7 +2040,7 @@ namespace ams::kern { size_t num_allocator_blocks; R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr), std::addressof(num_allocator_blocks), dst_address, size, - KMemoryState_All, KMemoryState_Io, + KMemoryState_All, mapping == ams::svc::MemoryMapping_Memory ? KMemoryState_IoMemory : KMemoryState_IoRegister, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_Locked)); @@ -2308,7 +2309,7 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Perform mapping operation. */ - const KPageProperties properties = { perm, state == KMemoryState_Io, false, DisableMergeAttribute_DisableHead }; + const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); /* Update the blocks. */ @@ -2343,7 +2344,7 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Perform mapping operation. */ - const KPageProperties properties = { perm, state == KMemoryState_Io, false, DisableMergeAttribute_DisableHead }; + const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); /* Update the blocks. */ @@ -2653,7 +2654,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size) { + Result KPageTableBase::ReadIoMemoryImpl(void *buffer, KPhysicalAddress phys_addr, size_t size, KMemoryState state) { /* Check pre-conditions. */ MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); @@ -2667,7 +2668,7 @@ namespace ams::kern { /* Temporarily map the io memory. */ KProcessAddress io_addr; - R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, KMemoryPermission_UserRead)); + R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, state, KMemoryPermission_UserRead)); /* Ensure we unmap the io memory when we're done with it. */ ON_SCOPE_EXIT { @@ -2698,7 +2699,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size) { + Result KPageTableBase::WriteIoMemoryImpl(KPhysicalAddress phys_addr, const void *buffer, size_t size, KMemoryState state) { /* Check pre-conditions. */ MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); @@ -2712,7 +2713,7 @@ namespace ams::kern { /* Temporarily map the io memory. */ KProcessAddress io_addr; - R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, KMemoryPermission_UserReadWrite)); + R_TRY(this->MapIoImpl(std::addressof(io_addr), updater.GetPageList(), map_start, map_size, state, KMemoryPermission_UserReadWrite)); /* Ensure we unmap the io memory when we're done with it. */ ON_SCOPE_EXIT { @@ -2743,7 +2744,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size) { + Result KPageTableBase::ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state) { /* Lightly validate the range before doing anything else. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); @@ -2755,7 +2756,7 @@ namespace ams::kern { KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock); /* Check that the desired range is readable io memory. */ - R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, KMemoryState_Io, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, state, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); /* Read the memory. */ u8 *dst = static_cast(buffer); @@ -2769,7 +2770,7 @@ namespace ams::kern { const size_t cur_size = std::min(last_address - address + 1, util::AlignDown(GetInteger(address) + PageSize, PageSize) - GetInteger(address)); /* Read. */ - R_TRY(dst_page_table.ReadIoMemoryImpl(dst, phys_addr, cur_size)); + R_TRY(dst_page_table.ReadIoMemoryImpl(dst, phys_addr, cur_size, state)); /* Advance. */ address += cur_size; @@ -2779,7 +2780,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size) { + Result KPageTableBase::WriteDebugIoMemory(KProcessAddress address, const void *buffer, size_t size, KMemoryState state) { /* Lightly validate the range before doing anything else. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); @@ -2791,7 +2792,7 @@ namespace ams::kern { KScopedLightLockPair lk(src_page_table.m_general_lock, dst_page_table.m_general_lock); /* Check that the desired range is writable io memory. */ - R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, KMemoryState_Io, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_All, state, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); /* Read the memory. */ const u8 *src = static_cast(buffer); @@ -2805,7 +2806,7 @@ namespace ams::kern { const size_t cur_size = std::min(last_address - address + 1, util::AlignDown(GetInteger(address) + PageSize, PageSize) - GetInteger(address)); /* Read. */ - R_TRY(dst_page_table.WriteIoMemoryImpl(phys_addr, src, cur_size)); + R_TRY(dst_page_table.WriteIoMemoryImpl(phys_addr, src, cur_size, state)); /* Advance. */ address += cur_size; @@ -2838,7 +2839,7 @@ namespace ams::kern { m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, &KMemoryBlock::ShareToDevice, KMemoryPermission_None); /* Set whether the locked memory was io. */ - *out_is_io = old_state == KMemoryState_Io; + *out_is_io = static_cast(old_state & KMemoryState_Mask) == ams::svc::MemoryState_Io; R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp b/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp index ffa65f723..a5d132e61 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_io_pool.cpp @@ -127,7 +127,7 @@ namespace ams::kern::svc { R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); /* Verify that the mapping is in range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Io), svc::ResultInvalidMemoryRegion()); + R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, ams::svc::MemoryState_Io), svc::ResultInvalidMemoryRegion()); /* Validate the map permission. */ R_UNLESS(IsValidIoRegionPermission(map_perm), svc::ResultInvalidNewMemoryPermission()); @@ -156,7 +156,7 @@ namespace ams::kern::svc { R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); /* Verify that the mapping is in range. */ - R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Io), svc::ResultInvalidMemoryRegion()); + R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, ams::svc::MemoryState_Io), svc::ResultInvalidMemoryRegion()); /* Get the io region. */ KScopedAutoObject io_region = GetCurrentProcess().GetHandleTable().GetObject(io_region_handle); diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index c600519df..f71d2c486 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -112,10 +112,11 @@ namespace ams::svc { }; enum MemoryAttribute : u32 { - MemoryAttribute_Locked = (1 << 0), - MemoryAttribute_IpcLocked = (1 << 1), - MemoryAttribute_DeviceShared = (1 << 2), - MemoryAttribute_Uncached = (1 << 3), + MemoryAttribute_Locked = (1 << 0), + MemoryAttribute_IpcLocked = (1 << 1), + MemoryAttribute_DeviceShared = (1 << 2), + MemoryAttribute_Uncached = (1 << 3), + MemoryAttribute_PermissionLocked = (1 << 4), }; enum MemoryMapping : u32 { From 777b6d285cb54cccf2e10af7929710b7f3cc5c41 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 05:11:50 -0700 Subject: [PATCH 015/238] kern: KPageTableBase::CheckMemoryState now invokes a helper --- .../mesosphere/kern_k_page_table_base.hpp | 1 + .../source/kern_k_page_table_base.cpp | 32 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 765ec2db4..80a306a7b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -312,6 +312,7 @@ namespace ams::kern { } Result CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const; + Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const; Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const; Result CheckMemoryState(size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const { R_RETURN(this->CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index c60a6ccdb..1a69c860f 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -527,17 +527,12 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr) const { + Result KPageTableBase::CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr) const { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* Get information about the first block. */ - const KProcessAddress last_addr = addr + size - 1; - KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); KMemoryInfo info = it->GetMemoryInfo(); - /* If the start address isn't aligned, we need a block. */ - const size_t blocks_for_start_align = (util::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; - /* Validate all blocks in the range have correct state. */ const KMemoryState first_state = info.m_state; const KMemoryPermission first_perm = info.m_permission; @@ -562,9 +557,6 @@ namespace ams::kern { info = it->GetMemoryInfo(); } - /* If the end address isn't aligned, we need a block. */ - const size_t blocks_for_end_align = (util::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; - /* Write output state. */ if (out_state != nullptr) { *out_state = first_state; @@ -575,9 +567,29 @@ namespace ams::kern { if (out_attr != nullptr) { *out_attr = static_cast(first_attr & ~ignore_attr); } + + /* If the end address isn't aligned, we need a block. */ if (out_blocks_needed != nullptr) { - *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; + const size_t blocks_for_end_align = (util::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress()) ? 1 : 0; + *out_blocks_needed = blocks_for_end_align; } + + R_SUCCEED(); + } + + Result KPageTableBase::CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr) const { + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + + /* Check memory state. */ + const KProcessAddress last_addr = addr + size - 1; + KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); + R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)) + + /* If the start address isn't aligned, we need a block. */ + if (out_blocks_needed != nullptr && util::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) { + ++(*out_blocks_needed); + } + R_SUCCEED(); } From ad5bd81d3f187e0a77d5846f86c83267c7deb23c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 07:59:37 -0700 Subject: [PATCH 016/238] kern: implement PermissionLock, update KPageTableBase attribute/alignment checks --- .../mesosphere/kern_k_memory_block.hpp | 14 ++++- .../kern_k_memory_block_manager.hpp | 4 +- .../source/kern_k_memory_block_manager.cpp | 62 ++++++++++++++++++- .../source/kern_k_page_table_base.cpp | 49 ++++++++++----- .../source/svc/kern_svc_memory.cpp | 5 +- 5 files changed, 114 insertions(+), 20 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index eacf909af..9d0a97738 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -191,7 +191,7 @@ namespace ams::kern { KMemoryAttribute_Uncached = ams::svc::MemoryAttribute_Uncached, KMemoryAttribute_PermissionLocked = ams::svc::MemoryAttribute_PermissionLocked, - KMemoryAttribute_SetMask = KMemoryAttribute_Uncached, + KMemoryAttribute_SetMask = KMemoryAttribute_Uncached | KMemoryAttribute_PermissionLocked, }; enum KMemoryBlockDisableMergeAttribute : u8 { @@ -331,6 +331,10 @@ namespace ams::kern { return this->GetEndAddress() - 1; } + constexpr KMemoryState GetState() const { + return m_memory_state; + } + constexpr u16 GetIpcLockCount() const { return m_ipc_lock_count; } @@ -450,6 +454,14 @@ namespace ams::kern { } } + constexpr void UpdateAttribute(u32 mask, u32 attr) { + MESOSPHERE_ASSERT_THIS(); + MESOSPHERE_ASSERT((mask & KMemoryAttribute_IpcLocked) == 0); + MESOSPHERE_ASSERT((mask & KMemoryAttribute_DeviceShared) == 0); + + m_attribute = static_cast((m_attribute & ~mask) | attr); + } + constexpr void Split(KMemoryBlock *block, KProcessAddress addr) { MESOSPHERE_ASSERT_THIS(); MESOSPHERE_ASSERT(this->GetAddress() < addr); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp index 99caae0c2..4a67e86f5 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp @@ -104,7 +104,9 @@ namespace ams::kern { void Update(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr); void UpdateLock(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, MemoryBlockLockFunction lock_func, KMemoryPermission perm); - void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr); + void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr); + + void UpdateAttribute(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, u32 mask, u32 attr); iterator FindIterator(KProcessAddress address) const { return m_memory_block_tree.find(KMemoryBlock(util::ConstantInitialize, address, 1, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None)); diff --git a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp index 4ccf06895..4ba4a566a 100644 --- a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp @@ -223,7 +223,7 @@ namespace ams::kern { } /* Update block state. */ - it->Update(state, perm, attr, cur_address == address, set_disable_attr, clear_disable_attr); + it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr); cur_address += cur_info.GetSize(); remaining_pages -= cur_info.GetNumPages(); } @@ -233,7 +233,7 @@ namespace ams::kern { this->CoalesceForUpdate(allocator, address, num_pages); } - void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr) { + void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm, KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr) { /* Ensure for auditing that we never end up with an invalid tree. */ KScopedMemoryBlockManagerAuditor auditor(this); MESOSPHERE_ASSERT(util::IsAligned(GetInteger(address), PageSize)); @@ -270,7 +270,7 @@ namespace ams::kern { } /* Update block state. */ - it->Update(state, perm, attr, false, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr); cur_address += cur_info.GetSize(); remaining_pages -= cur_info.GetNumPages(); } else { @@ -336,6 +336,62 @@ namespace ams::kern { this->CoalesceForUpdate(allocator, address, num_pages); } + void KMemoryBlockManager::UpdateAttribute(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, u32 mask, u32 attr) { + /* Ensure for auditing that we never end up with an invalid tree. */ + KScopedMemoryBlockManagerAuditor auditor(this); + MESOSPHERE_ASSERT(util::IsAligned(GetInteger(address), PageSize)); + + KProcessAddress cur_address = address; + size_t remaining_pages = num_pages; + iterator it = this->FindIterator(address); + + while (remaining_pages > 0) { + const size_t remaining_size = remaining_pages * PageSize; + KMemoryInfo cur_info = it->GetMemoryInfo(); + + if ((it->GetAttribute() & mask) != attr) { + /* If we need to, create a new block before and insert it. */ + if (cur_info.GetAddress() != GetInteger(cur_address)) { + KMemoryBlock *new_block = allocator->Allocate(); + + it->Split(new_block, cur_address); + it = m_memory_block_tree.insert(*new_block); + it++; + + cur_info = it->GetMemoryInfo(); + cur_address = cur_info.GetAddress(); + } + + /* If we need to, create a new block after and insert it. */ + if (cur_info.GetSize() > remaining_size) { + KMemoryBlock *new_block = allocator->Allocate(); + + it->Split(new_block, cur_address + remaining_size); + it = m_memory_block_tree.insert(*new_block); + + cur_info = it->GetMemoryInfo(); + } + + /* Update block state. */ + it->UpdateAttribute(mask, attr); + cur_address += cur_info.GetSize(); + remaining_pages -= cur_info.GetNumPages(); + } else { + /* If we already have the right attributes, just advance. */ + if (cur_address + remaining_size < cur_info.GetEndAddress()) { + remaining_pages = 0; + cur_address += remaining_size; + } else { + remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; + cur_address = cur_info.GetEndAddress(); + } + } + it++; + } + + this->CoalesceForUpdate(allocator, address, num_pages); + } + /* Debug. */ bool KMemoryBlockManager::CheckState() const { /* If we fail, we should dump blocks. */ diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 1a69c860f..090521c4c 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -987,7 +987,7 @@ namespace ams::kern { /* Verify that the destination memory is aliasable code. */ size_t num_dst_allocator_blocks; - R_TRY(this->CheckMemoryStateContiguous(std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState_FlagCanCodeAlias, KMemoryState_FlagCanCodeAlias, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryStateContiguous(std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState_FlagCanCodeAlias, KMemoryState_FlagCanCodeAlias, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All & ~KMemoryAttribute_PermissionLocked, KMemoryAttribute_None)); /* Determine whether any pages being unmapped are code. */ bool any_code_pages = false; @@ -1649,9 +1649,10 @@ namespace ams::kern { KMemoryAttribute old_attr; size_t num_allocator_blocks; constexpr u32 AttributeTestMask = ~(KMemoryAttribute_SetMask | KMemoryAttribute_DeviceShared); + const u32 state_test_mask = ((mask & KMemoryAttribute_Uncached) ? static_cast(KMemoryState_FlagCanChangeAttribute) : 0) | ((mask & KMemoryAttribute_PermissionLocked) ? static_cast(KMemoryState_FlagCanPermissionLock) : 0); R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), std::addressof(old_attr), std::addressof(num_allocator_blocks), addr, size, - KMemoryState_FlagCanChangeAttribute, KMemoryState_FlagCanChangeAttribute, + state_test_mask, state_test_mask, KMemoryPermission_None, KMemoryPermission_None, AttributeTestMask, KMemoryAttribute_None, ~AttributeTestMask)); @@ -1663,15 +1664,18 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); - /* Determine the new attribute. */ - const KMemoryAttribute new_attr = static_cast(((old_attr & ~mask) | (attr & mask))); + /* If we need to, perform a change attribute operation. */ + if ((mask & KMemoryAttribute_Uncached) != 0) { + /* Determine the new attribute. */ + const KMemoryAttribute new_attr = static_cast(((old_attr & ~mask) | (attr & mask))); - /* Perform operation. */ - const KPageProperties properties = { old_perm, false, (new_attr & KMemoryAttribute_Uncached) != 0, DisableMergeAttribute_None }; - R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, OperationType_ChangePermissionsAndRefreshAndFlush, false)); + /* Perform operation. */ + const KPageProperties properties = { old_perm, false, (new_attr & KMemoryAttribute_Uncached) != 0, DisableMergeAttribute_None }; + R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, OperationType_ChangePermissionsAndRefreshAndFlush, false)); + } /* Update the blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, old_perm, new_attr, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.UpdateAttribute(std::addressof(allocator), addr, num_pages, mask, attr); R_SUCCEED(); } @@ -1957,10 +1961,16 @@ namespace ams::kern { /* Select an address to map at. */ KProcessAddress addr = Null; - const size_t phys_alignment = std::min(std::min(util::GetAlignment(GetInteger(phys_addr)), util::GetAlignment(size)), MaxPhysicalMapAlignment); for (s32 block_type = KPageTable::GetMaxBlockType(); block_type >= 0; block_type--) { const size_t alignment = KPageTable::GetBlockSize(static_cast(block_type)); - if (alignment > phys_alignment) { + + const KPhysicalAddress aligned_phys = util::AlignUp(GetInteger(phys_addr), alignment) + alignment - 1; + if (aligned_phys <= phys_addr) { + continue; + } + + const KPhysicalAddress last_aligned_paddr = util::AlignDown(GetInteger(last) + 1, alignment) - 1; + if (!(last_aligned_paddr <= last && aligned_phys <= last_aligned_paddr)) { continue; } @@ -2142,10 +2152,16 @@ namespace ams::kern { /* Select an address to map at. */ KProcessAddress addr = Null; - const size_t phys_alignment = std::min(std::min(util::GetAlignment(GetInteger(phys_addr)), util::GetAlignment(size)), MaxPhysicalMapAlignment); for (s32 block_type = KPageTable::GetMaxBlockType(); block_type >= 0; block_type--) { const size_t alignment = KPageTable::GetBlockSize(static_cast(block_type)); - if (alignment > phys_alignment) { + + const KPhysicalAddress aligned_phys = util::AlignUp(GetInteger(phys_addr), alignment) + alignment - 1; + if (aligned_phys <= phys_addr) { + continue; + } + + const KPhysicalAddress last_aligned_paddr = util::AlignDown(GetInteger(last) + 1, alignment) - 1; + if (!(last_aligned_paddr <= last && aligned_phys <= last_aligned_paddr)) { continue; } @@ -4467,7 +4483,9 @@ namespace ams::kern { /* Update the relevant memory blocks. */ m_memory_block_manager.UpdateIfMatch(std::addressof(allocator), address, size / PageSize, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, - KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None); + KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, + address == this->GetAliasRegionStart() ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None, + KMemoryBlockDisableMergeAttribute_None); R_SUCCEED(); } @@ -4562,6 +4580,9 @@ namespace ams::kern { /* Iterate over the memory, unmapping as we go. */ auto it = m_memory_block_manager.FindIterator(cur_address); + + const auto clear_merge_attr = (it->GetState() == KMemoryState_Normal && it->GetAddress() == this->GetAliasRegionStart() && it->GetAddress() == address) ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None; + while (true) { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); @@ -4594,7 +4615,7 @@ namespace ams::kern { m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, mapped_size); /* Update memory blocks. */ - m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, clear_merge_attr); /* We succeeded. */ R_SUCCEED(); diff --git a/libraries/libmesosphere/source/svc/kern_svc_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_memory.cpp index a6994fae4..95173a0db 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_memory.cpp @@ -58,10 +58,13 @@ namespace ams::kern::svc { R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); /* Validate the attribute and mask. */ - constexpr u32 SupportedMask = ams::svc::MemoryAttribute_Uncached; + constexpr u32 SupportedMask = ams::svc::MemoryAttribute_Uncached | ams::svc::MemoryAttribute_PermissionLocked; R_UNLESS((mask | attr) == mask, svc::ResultInvalidCombination()); R_UNLESS((mask | attr | SupportedMask) == SupportedMask, svc::ResultInvalidCombination()); + /* Check that permission locked is either being set or not masked. */ + R_UNLESS((mask & ams::svc::MemoryAttribute_PermissionLocked) == (attr & ams::svc::MemoryAttribute_PermissionLocked), svc::ResultInvalidCombination()); + /* Validate that the region is in range for the current process. */ auto &page_table = GetCurrentProcess().GetPageTable(); R_UNLESS(page_table.Contains(address, size), svc::ResultInvalidCurrentMemory()); From 85b5f203957532fba541cda46f71310c365bb4a7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 08:29:07 -0700 Subject: [PATCH 017/238] kern: KPageTable::Initialize no longer takes unused process id --- .../include/mesosphere/arch/arm64/kern_k_page_table.hpp | 2 +- .../mesosphere/arch/arm64/kern_k_process_page_table.hpp | 4 ++-- .../libmesosphere/source/arch/arm64/kern_k_page_table.cpp | 5 +---- libraries/libmesosphere/source/kern_k_process.cpp | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index f6f27c019..7da761ef6 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -178,7 +178,7 @@ namespace ams::kern::arch::arm64 { } NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); Result Finalize(); private: Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 135c6696e..c0a266e78 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -28,8 +28,8 @@ namespace ams::kern::arch::arm64 { m_page_table.Activate(id); } - Result Initialize(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - R_RETURN(m_page_table.InitializeForProcess(id, as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, system_resource, resource_limit)); + Result Initialize(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + R_RETURN(m_page_table.InitializeForProcess(as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, system_resource, resource_limit)); } void Finalize() { m_page_table.Finalize(); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index ae569f998..ed55750c9 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -207,10 +207,7 @@ namespace ams::kern::arch::arm64 { R_SUCCEED(); } - Result KPageTable::InitializeForProcess(u32 id, ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - /* The input ID isn't actually used. */ - MESOSPHERE_UNUSED(id); - + Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { /* Get an ASID */ m_asid = g_asid_manager.Reserve(); ON_RESULT_FAILURE { g_asid_manager.Release(m_asid); }; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 35c6959b3..d94ced156 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -282,7 +282,7 @@ namespace ams::kern { const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; - R_TRY(m_page_table.Initialize(m_process_id, as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); + R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); } ON_RESULT_FAILURE { m_page_table.Finalize(); }; @@ -362,7 +362,7 @@ namespace ams::kern { const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; - R_TRY(m_page_table.Initialize(m_process_id, as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, code_size, m_system_resource, res_limit)); + R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, code_size, m_system_resource, res_limit)); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; From b7384a8667927f0cefc3e8044432e02d747ba404 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 08:41:36 -0700 Subject: [PATCH 018/238] kern: KSupervisorPageTable now checks wxn instead of setting it --- .../mesosphere/arch/arm64/kern_cpu_system_registers.hpp | 4 ++++ .../arch/arm64/kern_k_supervisor_page_table.hpp | 5 +---- .../source/arch/arm64/kern_k_supervisor_page_table.cpp | 8 ++------ 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp index 3889b264f..61e066fee 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_cpu_system_registers.hpp @@ -372,6 +372,10 @@ namespace ams::kern::arch::arm64::cpu { this->SetBit(19, en); return *this; } + + constexpr ALWAYS_INLINE bool GetWxn() const { + return this->GetBits(19, 1) != 0; + } }; /* Accessors for timer registers. */ diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp index c8ccca33d..73d886d84 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp @@ -23,9 +23,8 @@ namespace ams::kern::arch::arm64 { class KSupervisorPageTable { private: KPageTable m_page_table; - u64 m_ttbr0_identity[cpu::NumCores]; public: - constexpr KSupervisorPageTable() : m_page_table(util::ConstantInitialize), m_ttbr0_identity() { /* ... */ } + constexpr KSupervisorPageTable() : m_page_table(util::ConstantInitialize) { /* ... */ } NOINLINE void Initialize(s32 core_id); @@ -61,8 +60,6 @@ namespace ams::kern::arch::arm64 { return m_page_table.GetPhysicalAddress(out, address); } - constexpr u64 GetIdentityMapTtbr0(s32 core_id) const { return m_ttbr0_identity[core_id]; } - void DumpMemoryBlocks() const { return m_page_table.DumpMemoryBlocks(); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp index 23e3541de..5f5112f8d 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_supervisor_page_table.cpp @@ -18,12 +18,8 @@ namespace ams::kern::arch::arm64 { void KSupervisorPageTable::Initialize(s32 core_id) { - /* Get the identity mapping ttbr0. */ - m_ttbr0_identity[core_id] = cpu::GetTtbr0El1(); - - /* Set sctlr_el1 */ - cpu::SystemControlRegisterAccessor().SetWxn(true).Store(); - cpu::EnsureInstructionConsistency(); + /* Verify that sctlr_el1 has the wxn bit set. */ + MESOSPHERE_ABORT_UNLESS(cpu::SystemControlRegisterAccessor().GetWxn()); /* Invalidate the entire TLB. */ cpu::InvalidateEntireTlb(); From 2c5002ce50999861838b912515c53377f7e39ec2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 08:52:46 -0700 Subject: [PATCH 019/238] kern: update KMemoryRegionType values for new ids + SecureUnknown region --- .../mesosphere/kern_k_memory_region_type.hpp | 78 ++++++++++--------- .../source/arch/arm64/init/kern_init_core.cpp | 16 +++- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp index 7023c34e6..f90908bf4 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_region_type.hpp @@ -212,7 +212,9 @@ namespace ams::kern { static_assert(KMemoryRegionType_DramKernelInitPt.GetValue() == (0x44E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_LinearMapped)); constexpr inline const auto KMemoryRegionType_DramKernelSecureAppletMemory = KMemoryRegionType_DramKernelBase.DeriveSparse(1, 3, 0).SetAttribute(KMemoryRegionAttr_LinearMapped); + constexpr inline const auto KMemoryRegionType_DramKernelSecureUnknown = KMemoryRegionType_DramKernelBase.DeriveSparse(1, 3, 1).SetAttribute(KMemoryRegionAttr_LinearMapped); static_assert(KMemoryRegionType_DramKernelSecureAppletMemory.GetValue() == (0x18E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_LinearMapped)); + static_assert(KMemoryRegionType_DramKernelSecureUnknown.GetValue() == (0x28E | KMemoryRegionAttr_CarveoutProtected | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_LinearMapped)); constexpr inline const auto KMemoryRegionType_DramReservedEarly = KMemoryRegionType_DramReservedBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap); static_assert(KMemoryRegionType_DramReservedEarly.GetValue() == (0x16 | KMemoryRegionAttr_NoUserMap)); @@ -228,53 +230,55 @@ namespace ams::kern { constexpr inline const auto KMemoryRegionType_DramPoolPartition = KMemoryRegionType_DramHeapBase.DeriveAttribute(KMemoryRegionAttr_NoUserMap); static_assert(KMemoryRegionType_DramPoolPartition.GetValue() == (0x26 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - constexpr inline const auto KMemoryRegionType_DramPoolManagement = KMemoryRegionType_DramPoolPartition.DeriveTransition(0, 2).DeriveTransition().SetAttribute(KMemoryRegionAttr_CarveoutProtected); - constexpr inline const auto KMemoryRegionType_DramUserPool = KMemoryRegionType_DramPoolPartition.DeriveTransition(1, 2).DeriveTransition(); - static_assert(KMemoryRegionType_DramPoolManagement.GetValue() == (0x166 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); - static_assert(KMemoryRegionType_DramUserPool.GetValue() == (0x1A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + constexpr inline const auto KMemoryRegionType_DramPoolManagement = KMemoryRegionType_DramPoolPartition.Derive(4, 0).SetAttribute(KMemoryRegionAttr_CarveoutProtected); + /* UNUSED: .Derive(4, 1); */ + /* UNUSED: .Derive(4, 2); */ + constexpr inline const auto KMemoryRegionType_DramUserPool = KMemoryRegionType_DramPoolPartition.Derive(4, 3); + static_assert(KMemoryRegionType_DramPoolManagement.GetValue() == (0xE6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); + static_assert(KMemoryRegionType_DramUserPool .GetValue() == (0x266 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); constexpr inline const auto KMemoryRegionType_DramApplicationPool = KMemoryRegionType_DramUserPool.Derive(4, 0); constexpr inline const auto KMemoryRegionType_DramAppletPool = KMemoryRegionType_DramUserPool.Derive(4, 1); constexpr inline const auto KMemoryRegionType_DramSystemNonSecurePool = KMemoryRegionType_DramUserPool.Derive(4, 2); constexpr inline const auto KMemoryRegionType_DramSystemPool = KMemoryRegionType_DramUserPool.Derive(4, 3).SetAttribute(KMemoryRegionAttr_CarveoutProtected); - static_assert(KMemoryRegionType_DramApplicationPool .GetValue() == (0x7A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - static_assert(KMemoryRegionType_DramAppletPool .GetValue() == (0xBA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - static_assert(KMemoryRegionType_DramSystemNonSecurePool.GetValue() == (0xDA6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); - static_assert(KMemoryRegionType_DramSystemPool .GetValue() == (0x13A6 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); + static_assert(KMemoryRegionType_DramApplicationPool .GetValue() == (0xE66 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + static_assert(KMemoryRegionType_DramAppletPool .GetValue() == (0x1666 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + static_assert(KMemoryRegionType_DramSystemNonSecurePool.GetValue() == (0x1A66 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap)); + static_assert(KMemoryRegionType_DramSystemPool .GetValue() == (0x2666 | KMemoryRegionAttr_LinearMapped | KMemoryRegionAttr_NoUserMap | KMemoryRegionAttr_CarveoutProtected)); - constexpr inline const auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 3, 0); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelPtHeap = KMemoryRegionType_Dram.DeriveSparse(1, 3, 1); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelTraceBuffer = KMemoryRegionType_Dram.DeriveSparse(1, 3, 2); + constexpr inline const auto KMemoryRegionType_VirtualDramHeapBase = KMemoryRegionType_Dram.DeriveSparse(1, 4, 0); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelPtHeap = KMemoryRegionType_Dram.DeriveSparse(1, 4, 1); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelTraceBuffer = KMemoryRegionType_Dram.DeriveSparse(1, 4, 2); static_assert(KMemoryRegionType_VirtualDramHeapBase .GetValue() == 0x1A); static_assert(KMemoryRegionType_VirtualDramKernelPtHeap .GetValue() == 0x2A); static_assert(KMemoryRegionType_VirtualDramKernelTraceBuffer.GetValue() == 0x4A); /* UNUSED: .DeriveSparse(2, 2, 0); */ - constexpr inline const auto KMemoryRegionType_VirtualDramUnknownDebug = KMemoryRegionType_Dram.DeriveSparse(2, 2, 1); - static_assert(KMemoryRegionType_VirtualDramUnknownDebug.GetValue() == (0x52)); + constexpr inline const auto KMemoryRegionType_VirtualDramUnknownDebug = KMemoryRegionType_Dram.Advance(2).Derive(4, 0); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelSecureAppletMemory = KMemoryRegionType_Dram.Advance(2).Derive(4, 1); + /* UNUSED: .Derive(4, 2); */ + constexpr inline const auto KMemoryRegionType_VirtualDramKernelSecureUnknown = KMemoryRegionType_Dram.Advance(2).Derive(4, 3); + static_assert(KMemoryRegionType_VirtualDramUnknownDebug .GetValue() == (0x32)); + static_assert(KMemoryRegionType_VirtualDramKernelSecureAppletMemory.GetValue() == (0x52)); + static_assert(KMemoryRegionType_VirtualDramKernelSecureUnknown .GetValue() == (0x92)); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelSecureAppletMemory = KMemoryRegionType_Dram.DeriveSparse(3, 1, 0); - static_assert(KMemoryRegionType_VirtualDramKernelSecureAppletMemory.GetValue() == (0x62)); - constexpr inline const auto KMemoryRegionType_VirtualDramKernelInitPt = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 0); - constexpr inline const auto KMemoryRegionType_VirtualDramPoolManagement = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 1); - constexpr inline const auto KMemoryRegionType_VirtualDramUserPool = KMemoryRegionType_VirtualDramHeapBase.Derive(3, 2); - static_assert(KMemoryRegionType_VirtualDramKernelInitPt .GetValue() == 0x19A); - static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x29A); - static_assert(KMemoryRegionType_VirtualDramUserPool .GetValue() == 0x31A); + constexpr inline const auto KMemoryRegionType_VirtualDramKernelInitPt = KMemoryRegionType_VirtualDramHeapBase.Derive(4, 0); + constexpr inline const auto KMemoryRegionType_VirtualDramPoolManagement = KMemoryRegionType_VirtualDramHeapBase.Derive(4, 1); + constexpr inline const auto KMemoryRegionType_VirtualDramUserPool = KMemoryRegionType_VirtualDramHeapBase.Derive(4, 2); + /* UNUSED: .Derive(4, 3); */ + static_assert(KMemoryRegionType_VirtualDramKernelInitPt .GetValue() == 0x31A); + static_assert(KMemoryRegionType_VirtualDramPoolManagement.GetValue() == 0x51A); + static_assert(KMemoryRegionType_VirtualDramUserPool .GetValue() == 0x61A); - /* NOTE: For unknown reason, the pools are derived out-of-order here. */ - /* It's worth eventually trying to understand why Nintendo made this choice. */ - /* UNUSED: .Derive(6, 0); */ - /* UNUSED: .Derive(6, 1); */ - constexpr inline const auto KMemoryRegionType_VirtualDramAppletPool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 2); - constexpr inline const auto KMemoryRegionType_VirtualDramApplicationPool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 3); - constexpr inline const auto KMemoryRegionType_VirtualDramSystemNonSecurePool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 4); - constexpr inline const auto KMemoryRegionType_VirtualDramSystemPool = KMemoryRegionType_VirtualDramUserPool.Derive(6, 5); - static_assert(KMemoryRegionType_VirtualDramAppletPool .GetValue() == 0x1B1A); - static_assert(KMemoryRegionType_VirtualDramApplicationPool .GetValue() == 0x271A); - static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x2B1A); - static_assert(KMemoryRegionType_VirtualDramSystemPool .GetValue() == 0x331A); + constexpr inline const auto KMemoryRegionType_VirtualDramApplicationPool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 0); + constexpr inline const auto KMemoryRegionType_VirtualDramAppletPool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 1); + constexpr inline const auto KMemoryRegionType_VirtualDramSystemNonSecurePool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 2); + constexpr inline const auto KMemoryRegionType_VirtualDramSystemPool = KMemoryRegionType_VirtualDramUserPool.Derive(4, 3); + static_assert(KMemoryRegionType_VirtualDramApplicationPool .GetValue() == 0x361A); + static_assert(KMemoryRegionType_VirtualDramAppletPool .GetValue() == 0x561A); + static_assert(KMemoryRegionType_VirtualDramSystemNonSecurePool.GetValue() == 0x661A); + static_assert(KMemoryRegionType_VirtualDramSystemPool .GetValue() == 0x961A); constexpr inline const auto KMemoryRegionType_ArchDeviceBase = KMemoryRegionType_Kernel.DeriveTransition(0, 1).SetSparseOnly(); constexpr inline const auto KMemoryRegionType_BoardDeviceBase = KMemoryRegionType_Kernel.DeriveTransition(0, 2).SetDenseOnly(); @@ -328,12 +332,14 @@ namespace ams::kern { static_assert(KMemoryRegionType_KernelTemp.GetValue() == 0x31); constexpr ALWAYS_INLINE KMemoryRegionType GetTypeForVirtualLinearMapping(u32 type_id) { - if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) { - return KMemoryRegionType_VirtualDramKernelTraceBuffer; - } else if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) { + if (KMemoryRegionType_DramKernelPtHeap.IsAncestorOf(type_id)) { return KMemoryRegionType_VirtualDramKernelPtHeap; } else if (KMemoryRegionType_DramKernelSecureAppletMemory.IsAncestorOf(type_id)) { return KMemoryRegionType_VirtualDramKernelSecureAppletMemory; + } else if (KMemoryRegionType_DramKernelSecureUnknown.IsAncestorOf(type_id)) { + return KMemoryRegionType_VirtualDramKernelSecureUnknown; + } else if (KMemoryRegionType_KernelTraceBuffer.IsAncestorOf(type_id)) { + return KMemoryRegionType_VirtualDramKernelTraceBuffer; } else if ((type_id | KMemoryRegionAttr_ShouldKernelMap) == type_id) { return KMemoryRegionType_VirtualDramUnknownDebug; } else { diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index 5058e0716..484a2426c 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -33,6 +33,7 @@ namespace ams::kern::init { void IdentityMappedFunctionAreaEnd(); size_t GetMiscUnknownDebugRegionSize(); + size_t GetSecureUnknownRegionSize(); void InitializeDebugRegisters(); void InitializeExceptionVectors(); @@ -488,14 +489,21 @@ namespace ams::kern::init { MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(slab_end_phys_addr), KSystemControl::SecureAppletMemorySize, KMemoryRegionType_DramKernelSecureAppletMemory)); } + /* Insert a physical region for the unknown debug2 region. */ + const size_t secure_unknown_size = GetSecureUnknownRegionSize(); + const auto secure_unknown_end_phys_addr = secure_applet_end_phys_addr + secure_unknown_size; + if (secure_unknown_size > 0) { + MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(secure_applet_end_phys_addr), secure_unknown_size, KMemoryRegionType_DramKernelSecureUnknown)); + } + /* Determine size available for kernel page table heaps. */ const KPhysicalAddress resource_end_phys_addr = slab_start_phys_addr + resource_region_size; g_phase2_resource_end_phys_addr = resource_end_phys_addr; - const size_t page_table_heap_size = GetInteger(resource_end_phys_addr) - GetInteger(secure_applet_end_phys_addr); + const size_t page_table_heap_size = GetInteger(resource_end_phys_addr) - GetInteger(secure_unknown_end_phys_addr); /* Insert a physical region for the kernel page table heap region */ - MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(secure_applet_end_phys_addr), page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); + MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(GetInteger(secure_unknown_end_phys_addr), page_table_heap_size, KMemoryRegionType_DramKernelPtHeap)); /* All DRAM regions that we haven't tagged by this point will be mapped under the linear mapping. Tag them. */ for (auto ®ion : KMemoryLayout::GetPhysicalMemoryRegionTree()) { @@ -726,4 +734,8 @@ namespace ams::kern::init { return 0; } + size_t GetSecureUnknownRegionSize() { + return 0; + } + } \ No newline at end of file From 39a95d402322cd57a3f4faf8c79195a63d2c2f1d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 09:13:59 -0700 Subject: [PATCH 020/238] kern: implement new default application system resource field in KProcess --- .../include/mesosphere/kern_k_process.hpp | 15 +++- .../libmesosphere/source/kern_k_process.cpp | 81 +++++++++++++------ 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 33adfe097..3258d41e2 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -76,6 +76,7 @@ namespace ams::kern { bool m_is_signaled; bool m_is_initialized; bool m_is_application; + bool m_is_default_application_system_resource; char m_name[13]; util::Atomic m_num_running_threads; u32 m_flags; @@ -178,6 +179,8 @@ namespace ams::kern { constexpr bool IsApplication() const { return m_is_application; } + constexpr bool IsDefaultApplicationSystemResource() const { return m_is_default_application_system_resource; } + constexpr bool IsSuspended() const { return m_is_suspended; } constexpr void SetSuspended(bool suspended) { m_is_suspended = suspended; } @@ -280,12 +283,20 @@ namespace ams::kern { void IncrementRunningThreadCount(); void DecrementRunningThreadCount(); + size_t GetRequiredSecureMemorySizeNonDefault() const { + return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; + } + + size_t GetRequiredSecureMemorySize() const { + return m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; + } + size_t GetTotalSystemResourceSize() const { - return m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->GetSize() : 0; + return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast(m_system_resource)->GetSize() : 0; } size_t GetUsedSystemResourceSize() const { - return m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->GetUsedSize() : 0; + return (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) ? static_cast(m_system_resource)->GetUsedSize() : 0; } void SetRunningThread(s32 core, KThread *thread, u64 idle_count, u64 switch_count) { diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index d94ced156..9dbd3a4f4 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -263,28 +263,47 @@ namespace ams::kern { MESOSPHERE_ASSERT(res_limit != nullptr); MESOSPHERE_ABORT_UNLESS((params.code_num_pages * PageSize) / PageSize == static_cast(params.code_num_pages)); - /* Determine is application. */ - const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication) != 0; - /* Set members. */ - m_memory_pool = pool; - m_resource_limit = res_limit; - m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); - m_is_immortal = immortal; + m_memory_pool = pool; + m_resource_limit = res_limit; + m_is_default_application_system_resource = false; + m_is_immortal = immortal; - /* Open reference to our system resource. */ - m_system_resource->Open(); + /* Setup our system resource. */ + if (const size_t system_resource_num_pages = params.system_resource_num_pages; system_resource_num_pages != 0) { + /* Create a secure system resource. */ + KSecureSystemResource *secure_resource = KSecureSystemResource::Create(); + R_UNLESS(secure_resource != nullptr, svc::ResultOutOfResource()); + + ON_RESULT_FAILURE { secure_resource->Close(); }; + + /* Initialize the secure resource. */ + R_TRY(secure_resource->Initialize(system_resource_num_pages * PageSize, m_resource_limit, m_memory_pool)); + + /* Set our system resource. */ + m_system_resource = secure_resource; + } else { + /* Use the system-wide system resource. */ + const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication); + m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); + + m_is_default_application_system_resource = is_app; + + /* Open reference to the system resource. */ + m_system_resource->Open(); + } + + /* Ensure we clean up our secure resource, if we fail. */ + ON_RESULT_FAILURE { m_system_resource->Close(); }; /* Setup page table. */ - /* NOTE: Nintendo passes process ID despite not having set it yet. */ - /* This goes completely unused, but even so... */ { const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); } - ON_RESULT_FAILURE { m_page_table.Finalize(); }; + ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; /* Ensure we can insert the code region. */ R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize, KMemoryState_Code), svc::ResultInvalidMemoryRegion()); @@ -315,9 +334,10 @@ namespace ams::kern { MESOSPHERE_ASSERT(res_limit != nullptr); /* Set pool and resource limit. */ - m_memory_pool = pool; - m_resource_limit = res_limit; - m_is_immortal = false; + m_memory_pool = pool; + m_resource_limit = res_limit; + m_is_default_application_system_resource = false; + m_is_immortal = false; /* Get the memory sizes. */ const size_t code_num_pages = params.code_num_pages; @@ -348,6 +368,8 @@ namespace ams::kern { const bool is_app = (params.flags & ams::svc::CreateProcessFlag_IsApplication); m_system_resource = std::addressof(is_app ? Kernel::GetApplicationSystemResource() : Kernel::GetSystemSystemResource()); + m_is_default_application_system_resource = is_app; + /* Open reference to the system resource. */ m_system_resource->Open(); } @@ -356,8 +378,6 @@ namespace ams::kern { ON_RESULT_FAILURE { m_system_resource->Close(); }; /* Setup page table. */ - /* NOTE: Nintendo passes process ID despite not having set it yet. */ - /* This goes completely unused, but even so... */ { const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; @@ -848,7 +868,7 @@ namespace ams::kern { size_t KProcess::GetUsedUserPhysicalMemorySize() const { const size_t norm_size = m_page_table.GetNormalMemorySize(); const size_t other_size = m_code_size + m_main_thread_stack_size; - const size_t sec_size = m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; + const size_t sec_size = this->GetRequiredSecureMemorySizeNonDefault(); return norm_size + other_size + sec_size; } @@ -856,13 +876,20 @@ namespace ams::kern { size_t KProcess::GetTotalUserPhysicalMemorySize() const { /* Get the amount of free and used size. */ const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax); - const size_t used_size = this->GetUsedUserPhysicalMemorySize(); const size_t max_size = m_max_process_memory; + /* Determine used size. */ + /* NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike GetUsedUserPhysicalMemorySize(). */ + const size_t norm_size = m_page_table.GetNormalMemorySize(); + const size_t other_size = m_code_size + m_main_thread_stack_size; + const size_t sec_size = this->GetRequiredSecureMemorySize(); + const size_t used_size = norm_size + other_size + sec_size; + + /* NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo does it this way. */ if (used_size + free_size > max_size) { return max_size; } else { - return free_size + used_size; + return free_size + this->GetUsedUserPhysicalMemorySize(); } } @@ -876,14 +903,20 @@ namespace ams::kern { size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const { /* Get the amount of free and used size. */ const size_t free_size = m_resource_limit->GetFreeValue(ams::svc::LimitableResource_PhysicalMemoryMax); - const size_t used_size = this->GetUsedUserPhysicalMemorySize(); - const size_t sec_size = m_system_resource->IsSecureResource() ? static_cast(m_system_resource)->CalculateRequiredSecureMemorySize() : 0; const size_t max_size = m_max_process_memory; + /* Determine used size. */ + /* NOTE: This does *not* check this->IsDefaultApplicationSystemResource(), unlike GetUsedUserPhysicalMemorySize(). */ + const size_t norm_size = m_page_table.GetNormalMemorySize(); + const size_t other_size = m_code_size + m_main_thread_stack_size; + const size_t sec_size = this->GetRequiredSecureMemorySize(); + const size_t used_size = norm_size + other_size + sec_size; + + /* NOTE: These function calls will recalculate, introducing a race...it is unclear why Nintendo does it this way. */ if (used_size + free_size > max_size) { - return max_size - sec_size; + return max_size - this->GetRequiredSecureMemorySizeNonDefault(); } else { - return free_size + used_size - sec_size; + return free_size + this->GetUsedNonSystemUserPhysicalMemorySize(); } } From 7b523cfc8dccaa7875dc4e19cea892280831798c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 09:16:52 -0700 Subject: [PATCH 021/238] kern: note OnFinalize calls in KPageTable::Finalize --- .../libmesosphere/source/arch/arm64/kern_k_page_table.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index ed55750c9..4d1269a07 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -236,9 +236,15 @@ namespace ams::kern::arch::arm64 { /* Only process tables should be finalized. */ MESOSPHERE_ASSERT(!this->IsKernel()); + /* NOTE: Here Nintendo calls an unknown OnFinalize function. */ + /* this->OnFinalize(); */ + /* Note that we've updated (to ensure we're synchronized). */ this->NoteUpdated(); + /* NOTE: Here Nintendo calls a second unknown OnFinalize function. */ + /* this->OnFinalize2(); */ + /* Free all pages in the table. */ { /* Get implementation objects. */ From 2a4d68f916acfaaed420a0a033684aba12ed3ff9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 09:32:23 -0700 Subject: [PATCH 022/238] kern: KPageTable: remove MapFirst operation, replace with MapFirstGroup --- .../arch/arm64/kern_k_page_table.hpp | 4 +- .../include/mesosphere/kern_k_page_group.hpp | 12 ++++- .../mesosphere/kern_k_page_table_base.hpp | 2 +- .../source/arch/arm64/kern_k_page_table.cpp | 20 +++---- .../source/kern_k_page_table_base.cpp | 52 ++++++++++++------- 5 files changed, 53 insertions(+), 37 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 7da761ef6..f8ab5e680 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -208,8 +208,8 @@ namespace ams::kern::arch::arm64 { } } - Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll); - Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); + Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); + Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll); bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp index 9beef7f1c..a0d150a08 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp @@ -158,8 +158,16 @@ namespace ams::kern { private: const KPageGroup *m_pg; public: - explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup *gp) : m_pg(gp) { if (m_pg) { m_pg->Open(); } } - explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup &gp) : KScopedPageGroup(std::addressof(gp)) { /* ... */ } + explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup *gp, bool not_first = true) : m_pg(gp) { + if (m_pg) { + if (not_first) { + m_pg->Open(); + } else { + m_pg->OpenFirst(); + } + } + } + explicit ALWAYS_INLINE KScopedPageGroup(const KPageGroup &gp, bool not_first = true) : KScopedPageGroup(std::addressof(gp), not_first) { /* ... */ } ALWAYS_INLINE ~KScopedPageGroup() { if (m_pg) { m_pg->Close(); } } ALWAYS_INLINE void CancelClose() { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 80a306a7b..f45f0eba0 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -88,8 +88,8 @@ namespace ams::kern { enum OperationType { OperationType_Map = 0, - OperationType_MapFirst = 1, OperationType_MapGroup = 2, + OperationType_MapFirstGroup = 1, OperationType_Unmap = 3, OperationType_ChangePermissions = 4, OperationType_ChangePermissionsAndRefresh = 5, diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 4d1269a07..8ad4a5dd4 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -351,7 +351,7 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); MESOSPHERE_ASSERT(this->ContainsPages(virt_addr, num_pages)); - if (operation == OperationType_Map || operation == OperationType_MapFirst) { + if (operation == OperationType_Map) { MESOSPHERE_ABORT_UNLESS(is_pa_valid); MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); } else { @@ -378,8 +378,7 @@ namespace ams::kern::arch::arm64 { switch (operation) { case OperationType_Map: - case OperationType_MapFirst: - R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirst, page_list, reuse_ll)); + R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, page_list, reuse_ll)); case OperationType_ChangePermissions: R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, false, false, page_list, reuse_ll)); case OperationType_ChangePermissionsAndRefresh: @@ -402,7 +401,8 @@ namespace ams::kern::arch::arm64 { auto entry_template = this->GetEntryTemplate(properties); switch (operation) { case OperationType_MapGroup: - R_RETURN(this->MapGroup(virt_addr, page_group, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, page_list, reuse_ll)); + case OperationType_MapFirstGroup: + R_RETURN(this->MapGroup(virt_addr, page_group, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirstGroup, page_list, reuse_ll)); MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } @@ -759,7 +759,7 @@ namespace ams::kern::arch::arm64 { R_SUCCEED(); } - Result KPageTable::MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll) { + Result KPageTable::MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* Cache initial addresses for use on cleanup. */ @@ -830,21 +830,17 @@ namespace ams::kern::arch::arm64 { /* Open references to the pages, if we should. */ if (IsHeapPhysicalAddress(orig_phys_addr)) { - if (not_first) { - Kernel::GetMemoryManager().Open(orig_phys_addr, num_pages); - } else { - Kernel::GetMemoryManager().OpenFirst(orig_phys_addr, num_pages); - } + Kernel::GetMemoryManager().Open(orig_phys_addr, num_pages); } R_SUCCEED(); } - Result KPageTable::MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { + Result KPageTable::MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* We want to maintain a new reference to every page in the group. */ - KScopedPageGroup spg(pg); + KScopedPageGroup spg(pg, not_first); /* Cache initial address for use on cleanup. */ const KProcessAddress orig_virt_addr = virt_addr; diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 090521c4c..3d6bc0c95 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -4435,32 +4435,44 @@ namespace ams::kern { /* If it's unmapped, we need to map it. */ if (info.GetState() == KMemoryState_Free) { /* Determine the range to map. */ - const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, DisableMergeAttribute_None }; + const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, cur_address == this->GetAliasRegionStart() ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; size_t map_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; /* While we have pages to map, map them. */ - while (map_pages > 0) { - /* Check if we're at the end of the physical block. */ - if (pg_pages == 0) { - /* Ensure there are more pages to map. */ - MESOSPHERE_ASSERT(pg_it != pg.end()); + { + /* Create a page group for the current mapping range. */ + KPageGroup cur_pg(m_block_info_manager); + { + ON_RESULT_FAILURE { + cur_pg.OpenFirst(); + cur_pg.Close(); + }; - /* Advance our physical block. */ - ++pg_it; - pg_phys_addr = pg_it->GetAddress(); - pg_pages = pg_it->GetNumPages(); + size_t remain_pages = map_pages; + while (remain_pages > 0) { + /* Check if we're at the end of the physical block. */ + if (pg_pages == 0) { + /* Ensure there are more pages to map. */ + MESOSPHERE_ASSERT(pg_it != pg.end()); + + /* Advance our physical block. */ + ++pg_it; + pg_phys_addr = pg_it->GetAddress(); + pg_pages = pg_it->GetNumPages(); + } + + /* Add whatever we can to the current block. */ + const size_t cur_pages = std::min(pg_pages, remain_pages); + R_TRY(cur_pg.AddBlock(pg_phys_addr + ((pg_pages - cur_pages) * PageSize), cur_pages)); + + /* Advance. */ + remain_pages -= cur_pages; + pg_pages -= cur_pages; + } } - /* Map whatever we can. */ - const size_t cur_pages = std::min(pg_pages, map_pages); - R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_pages, pg_phys_addr, true, map_properties, OperationType_MapFirst, false)); - - /* Advance. */ - cur_address += cur_pages * PageSize; - map_pages -= cur_pages; - - pg_phys_addr += cur_pages * PageSize; - pg_pages -= cur_pages; + /* Map the papges. */ + R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages, cur_pg, map_properties, OperationType_MapFirstGroup, false)); } } From 3737151a2f98a8d0eb1a8070950d776626b97b3a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 09:37:45 -0700 Subject: [PATCH 023/238] kern: Add special-case for InvalidateProcessDataCache on current process --- .../arch/arm64/kern_k_process_page_table.hpp | 4 ++++ .../mesosphere/kern_k_page_table_base.hpp | 1 + .../source/kern_k_page_table_base.cpp | 17 +++++++++++++++++ .../libmesosphere/source/svc/kern_svc_cache.cpp | 6 +++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index c0a266e78..297d30b52 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -150,6 +150,10 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.InvalidateProcessDataCache(address, size)); } + Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size) { + R_RETURN(m_page_table.InvalidateCurrentProcessDataCache(address, size)); + } + Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size)); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index f45f0eba0..fcc06d733 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -412,6 +412,7 @@ namespace ams::kern { Result MakeAndOpenPageGroup(KPageGroup *out, KProcessAddress address, size_t num_pages, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr); Result InvalidateProcessDataCache(KProcessAddress address, size_t size); + Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size); Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size); Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 3d6bc0c95..79034dcf2 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -2508,6 +2508,23 @@ namespace ams::kern { R_SUCCEED(); } + Result KPageTableBase::InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size) { + /* Check pre-condition: this is being called on the current process. */ + MESOSPHERE_ASSERT(this == std::addressof(GetCurrentProcess().GetPageTable().GetBasePageTable())); + + /* Check that the region is in range. */ + R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); + + /* Lock the table. */ + KScopedLightLock lk(m_general_lock); + + /* Check the memory state. */ + R_TRY(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagReferenceCounted, KMemoryState_FlagReferenceCounted, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_Uncached, KMemoryAttribute_None)); + + /* Invalidate the data cache. */ + R_RETURN(cpu::InvalidateDataCache(GetVoidPointer(address), size)); + } + Result KPageTableBase::ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { /* Lightly validate the region is in range. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_cache.cpp b/libraries/libmesosphere/source/svc/kern_svc_cache.cpp index 62997b50b..c6ffb5e4c 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_cache.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_cache.cpp @@ -102,7 +102,11 @@ namespace ams::kern::svc { R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); /* Invalidate the cache. */ - R_TRY(process->GetPageTable().InvalidateProcessDataCache(address, size)); + if (process.GetPointerUnsafe() == GetCurrentProcessPointer()) { + R_TRY(process->GetPageTable().InvalidateCurrentProcessDataCache(address, size)); + } else { + R_TRY(process->GetPageTable().InvalidateProcessDataCache(address, size)); + } R_SUCCEED(); } From 4ddfb6183c042726c80c628cdd0b70ceb55a7506 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 09:51:40 -0700 Subject: [PATCH 024/238] kern: split out GetInstructionDataUserMode in exception handler --- .../arch/arm64/kern_exception_handlers.cpp | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index ba44e7f2c..c5d319811 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -59,7 +59,9 @@ namespace ams::kern::arch::arm64 { EsrEc_BrkInstruction = 0b111100, }; - constexpr u32 GetInstructionData(const KExceptionContext *context, u64 esr) { + + + u32 GetInstructionDataSupervisorMode(const KExceptionContext *context, u64 esr) { /* Check for THUMB usermode */ if ((context->psr & 0x3F) == 0x30) { u32 insn = *reinterpret_cast(context->pc & ~0x1); @@ -74,6 +76,37 @@ namespace ams::kern::arch::arm64 { } } + u32 GetInstructionDataUserMode(const KExceptionContext *context) { + /* Check for THUMB usermode */ + u32 insn = 0; + if ((context->psr & 0x3F) == 0x30) { + u16 insn_high = 0; + if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_high), reinterpret_cast(context->pc & ~0x1), sizeof(insn_high))) { + insn = insn_high; + + /* Check if the instruction was a THUMB mode branch prefix. */ + if (((insn >> 11) & 0b11110) == 0b11110) { + u16 insn_low = 0; + if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_low), reinterpret_cast((context->pc & ~0x1) + sizeof(u16)), sizeof(insn_low))) { + insn = (static_cast(insn_high) << 16) | (static_cast(insn_low) << 0); + } else { + insn = 0; + } + } + } else { + insn = 0; + } + } else { + u32 insn_value = 0; + if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_value), reinterpret_cast(context->pc), sizeof(insn_value))) { + insn = insn_value; + } else { + insn = 0; + } + } + return insn; + } + void HandleUserException(KExceptionContext *context, u64 esr, u64 far, u64 afsr0, u64 afsr1, u32 data) { KProcess &cur_process = GetCurrentProcess(); bool should_process_user_exception = KTargetSystem::IsUserExceptionHandlersEnabled(); @@ -501,9 +534,10 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(!KInterruptManager::AreInterruptsEnabled()); /* Retrieve information about the exception. */ - const u64 esr = cpu::GetEsrEl1(); - const u64 afsr0 = cpu::GetAfsr0El1(); - const u64 afsr1 = cpu::GetAfsr1El1(); + const bool is_user_mode = (context->psr & 0xF) == 0; + const u64 esr = cpu::GetEsrEl1(); + const u64 afsr0 = cpu::GetAfsr0El1(); + const u64 afsr1 = cpu::GetAfsr1El1(); u64 far = 0; u32 data = 0; @@ -514,7 +548,12 @@ namespace ams::kern::arch::arm64 { case EsrEc_BkptInstruction: case EsrEc_BrkInstruction: far = context->pc; - data = GetInstructionData(context, esr); + /* NOTE: Nintendo always calls GetInstructionDataUserMode. */ + if (is_user_mode) { + data = GetInstructionDataUserMode(context); + } else { + data = GetInstructionDataSupervisorMode(context, esr); + } break; case EsrEc_Svc32: if (context->psr & 0x20) { @@ -543,7 +582,6 @@ namespace ams::kern::arch::arm64 { /* Verify that spsr's M is allowable (EL0t). */ { - const bool is_user_mode = (context->psr & 0xF) == 0; if (is_user_mode) { /* If the user disable count is set, we may need to pin the current thread. */ if (GetCurrentThread().GetUserDisableCount() != 0 && GetCurrentProcess().GetPinnedThread(GetCurrentCoreId()) == nullptr) { From f93aea4c06f0f79ffb8d701defd4630785b512df Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 09:57:58 -0700 Subject: [PATCH 025/238] kern: split Process/Thread exit to separate WorkerTaskManagers --- .../mesosphere/kern_k_worker_task_manager.hpp | 3 ++- libraries/libmesosphere/source/kern_k_process.cpp | 4 ++-- libraries/libmesosphere/source/kern_k_thread.cpp | 13 ++++++++----- libraries/libmesosphere/source/kern_main.cpp | 5 +++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp index df0d81ff3..cb87f22b6 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_worker_task_manager.hpp @@ -25,7 +25,8 @@ namespace ams::kern { static constexpr s32 ExitWorkerPriority = 11; enum WorkerType { - WorkerType_Exit, + WorkerType_ExitThread, + WorkerType_ExitProcess, WorkerType_Count, }; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 9dbd3a4f4..07d122280 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -491,7 +491,7 @@ namespace ams::kern { MESOSPHERE_LOG("KProcess::Exit() pid=%ld name=%-12s\n", m_process_id, m_name); /* Register the process as a work task. */ - KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this); + KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this); } /* Exit the current thread. */ @@ -536,7 +536,7 @@ namespace ams::kern { MESOSPHERE_LOG("KProcess::Terminate() FAIL pid=%ld name=%-12s\n", m_process_id, m_name); /* Register the process as a work task. */ - KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this); + KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitProcess, this); } } diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 942e85b10..4ec7aa1dd 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -476,10 +476,6 @@ namespace ams::kern { m_parent->ClearRunningThread(this); } - /* Signal. */ - m_signaled = true; - KSynchronizationObject::NotifyAvailable(); - /* Call the on thread termination handler. */ KThreadContext::OnThreadTerminating(this); @@ -507,6 +503,13 @@ namespace ams::kern { cpu::SynchronizeCores(m_parent->GetPhysicalCoreMask()); } + /* Acquire the scheduler lock. */ + KScopedSchedulerLock sl; + + /* Signal. */ + m_signaled = true; + KSynchronizationObject::NotifyAvailable(); + /* Close the thread. */ this->Close(); } @@ -1328,7 +1331,7 @@ namespace ams::kern { this->StartTermination(); /* Register the thread as a work task. */ - KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_Exit, this); + KWorkerTaskManager::AddTask(KWorkerTaskManager::WorkerType_ExitThread, this); } MESOSPHERE_PANIC("KThread::Exit() would return"); diff --git a/libraries/libmesosphere/source/kern_main.cpp b/libraries/libmesosphere/source/kern_main.cpp index 14209eb1f..0f1782c2a 100644 --- a/libraries/libmesosphere/source/kern_main.cpp +++ b/libraries/libmesosphere/source/kern_main.cpp @@ -115,8 +115,9 @@ namespace ams::kern { /* Perform more core-0 specific initialization. */ if (core_id == 0) { - /* Initialize the exit worker manager, so that threads and processes may exit cleanly. */ - Kernel::GetWorkerTaskManager(KWorkerTaskManager::WorkerType_Exit).Initialize(KWorkerTaskManager::ExitWorkerPriority); + /* Initialize the exit worker managers, so that threads and processes may exit cleanly. */ + Kernel::GetWorkerTaskManager(KWorkerTaskManager::WorkerType_ExitThread).Initialize(KWorkerTaskManager::ExitWorkerPriority); + Kernel::GetWorkerTaskManager(KWorkerTaskManager::WorkerType_ExitProcess).Initialize(KWorkerTaskManager::ExitWorkerPriority); /* Setup so that we may sleep later, and reserve memory for secure applets. */ KSystemControl::InitializePhase2(); From 11c02e22e0514c6a082b6d22cc36e9959a273d17 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 10:12:20 -0700 Subject: [PATCH 026/238] kern: implement support for applying relr relocations --- .../mesosphere/init/kern_init_elf64.hpp | 21 +++++ .../source/init/kern_init_elf.cpp | 87 ++++++++++++++++--- 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp b/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp index 6b507f74c..76d858426 100644 --- a/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp +++ b/libraries/libmesosphere/include/mesosphere/init/kern_init_elf64.hpp @@ -114,6 +114,23 @@ namespace ams::kern::init::Elf::Elf64 { } }; + class Relr { + private: + Xword m_info; + public: + constexpr ALWAYS_INLINE bool IsLocation() const { + return (m_info & 1) == 0; + } + + constexpr ALWAYS_INLINE Xword GetLocation() const { + return m_info; + } + + constexpr ALWAYS_INLINE Xword GetBitmap() const { + return m_info >> 1; + } + }; + enum DynamicTag { DT_NULL = 0, DT_RELA = 7, @@ -121,6 +138,10 @@ namespace ams::kern::init::Elf::Elf64 { DT_REL = 17, DT_RELENT = 19, + DT_RELRSZ = 35, + DT_RELR = 36, + DT_RELRENT = 37, + DT_RELACOUNT = 0x6ffffff9, DT_RELCOUNT = 0x6ffffffa }; diff --git a/libraries/libmesosphere/source/init/kern_init_elf.cpp b/libraries/libmesosphere/source/init/kern_init_elf.cpp index 96ac6b5ee..a9ef3666d 100644 --- a/libraries/libmesosphere/source/init/kern_init_elf.cpp +++ b/libraries/libmesosphere/source/init/kern_init_elf.cpp @@ -21,10 +21,13 @@ namespace ams::kern::init::Elf { void ApplyRelocations(uintptr_t base_address, const Dyn *dynamic) { uintptr_t dyn_rel = 0; uintptr_t dyn_rela = 0; + uintptr_t dyn_relr = 0; uintptr_t rel_count = 0; uintptr_t rela_count = 0; + uintptr_t relr_sz = 0; uintptr_t rel_ent = 0; uintptr_t rela_ent = 0; + uintptr_t relr_ent = 0; /* Iterate over all tags, identifying important extents. */ for (const Dyn *cur_entry = dynamic; cur_entry->GetTag() != DT_NULL; cur_entry++) { @@ -35,43 +38,99 @@ namespace ams::kern::init::Elf { case DT_RELA: dyn_rela = base_address + cur_entry->GetPtr(); break; + case DT_RELR: + dyn_relr = base_address + cur_entry->GetPtr(); + break; case DT_RELENT: rel_ent = cur_entry->GetValue(); break; case DT_RELAENT: rela_ent = cur_entry->GetValue(); break; + case DT_RELRENT: + relr_ent = cur_entry->GetValue(); + break; case DT_RELCOUNT: rel_count = cur_entry->GetValue(); break; case DT_RELACOUNT: rela_count = cur_entry->GetValue(); break; + case DT_RELRSZ: + relr_sz = cur_entry->GetValue(); + break; } } /* Apply all Rel relocations */ - for (size_t i = 0; i < rel_count; i++) { - const auto &rel = *reinterpret_cast(dyn_rel + rel_ent * i); + if (rel_count > 0) { + /* Check that the rel relocations are applyable. */ + MESOSPHERE_INIT_ABORT_UNLESS(dyn_rel != 0); + MESOSPHERE_INIT_ABORT_UNLESS(rel_ent == sizeof(Elf::Rel)); - /* Only allow architecture-specific relocations. */ - while (rel.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } + for (size_t i = 0; i < rel_count; ++i) { + const auto &rel = reinterpret_cast(dyn_rel)[i]; - /* Apply the relocation. */ - Elf::Addr *target_address = reinterpret_cast(base_address + rel.GetOffset()); - *target_address += base_address; + /* Only allow architecture-specific relocations. */ + while (rel.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } + + /* Apply the relocation. */ + Elf::Addr *target_address = reinterpret_cast(base_address + rel.GetOffset()); + *target_address += base_address; + } } /* Apply all Rela relocations. */ - for (size_t i = 0; i < rela_count; i++) { - const auto &rela = *reinterpret_cast(dyn_rela + rela_ent * i); + if (rela_count > 0) { + /* Check that the rela relocations are applyable. */ + MESOSPHERE_INIT_ABORT_UNLESS(dyn_rela != 0); + MESOSPHERE_INIT_ABORT_UNLESS(rela_ent == sizeof(Elf::Rela)); - /* Only allow architecture-specific relocations. */ - while (rela.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } + for (size_t i = 0; i < rela_count; ++i) { + const auto &rela = reinterpret_cast(dyn_rela)[i]; - /* Apply the relocation. */ - Elf::Addr *target_address = reinterpret_cast(base_address + rela.GetOffset()); - *target_address = base_address + rela.GetAddend(); + /* Only allow architecture-specific relocations. */ + while (rela.GetType() != R_ARCHITECTURE_RELATIVE) { /* ... */ } + + /* Apply the relocation. */ + Elf::Addr *target_address = reinterpret_cast(base_address + rela.GetOffset()); + *target_address = base_address + rela.GetAddend(); + } + } + + /* Apply all Relr relocations. */ + if (relr_sz >= sizeof(Elf::Relr)) { + /* Check that the relr relocations are applyable. */ + MESOSPHERE_INIT_ABORT_UNLESS(dyn_relr != 0); + MESOSPHERE_INIT_ABORT_UNLESS(relr_ent == sizeof(Elf::Relr)); + + const size_t relr_count = relr_sz / sizeof(Elf::Relr); + + Elf::Addr *where = nullptr; + for (size_t i = 0; i < relr_count; ++i) { + const auto &relr = reinterpret_cast(dyn_relr)[i]; + + if (relr.IsLocation()) { + /* Update location. */ + where = reinterpret_cast(base_address + relr.GetLocation()); + + /* Apply the relocation. */ + *(where++) += base_address; + } else { + /* Get the bitmap. */ + u64 bitmap = relr.GetBitmap(); + + /* Apply all relocations. */ + while (bitmap != 0) { + const u64 next = util::CountTrailingZeros(bitmap); + bitmap &= ~(static_cast(1) << next); + where[next] += base_address; + } + + /* Advance. */ + where += BITSIZEOF(bitmap) - 1; + } + } } } From 06a840e5500c6fc31e4f12d6e05662c6ca816a09 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 10:12:54 -0700 Subject: [PATCH 027/238] kern: fix operation type enum-value whoops --- .../include/mesosphere/kern_k_page_table_base.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index fcc06d733..530b68dea 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -88,8 +88,8 @@ namespace ams::kern { enum OperationType { OperationType_Map = 0, - OperationType_MapGroup = 2, - OperationType_MapFirstGroup = 1, + OperationType_MapGroup = 1, + OperationType_MapFirstGroup = 2, OperationType_Unmap = 3, OperationType_ChangePermissions = 4, OperationType_ChangePermissionsAndRefresh = 5, From aba6ca732918695e837328b113cd060aec97208a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 10:13:45 -0700 Subject: [PATCH 028/238] kern: bump supported version to 17.x --- libraries/libvapours/include/vapours/svc/svc_version.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index 0268b505a..c7fb5341f 100644 --- a/libraries/libvapours/include/vapours/svc/svc_version.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_version.hpp @@ -57,8 +57,8 @@ namespace ams::svc { /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ - constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(16); - constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 2); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(17); + constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 5); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); From 6d0bf707831ed8e136396bb27683c28a7ab1c281 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 10:20:47 -0700 Subject: [PATCH 029/238] kern: fix assert usage in process load --- .../libmesosphere/source/kern_k_initial_process_reader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index 6a9e3718b..727ddd476 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -129,7 +129,8 @@ namespace ams::kern { /* It is guaranteed by pre-condition that only the very first block can overlap with the physical binary, so we can simply memmove it at the end. */ if (last_block != Null) { /* This is guaranteed by pre-condition, but for ease of debugging, check for no overlap. */ - AMS_ASSERT(!util::HasOverlap(GetInteger(binary_phys), binary_size, GetInteger(block_addr), cur_size)); + MESOSPHERE_ASSERT(!util::HasOverlap(GetInteger(binary_phys), binary_size, GetInteger(block_addr), cur_size)); + MESOSPHERE_UNUSED(binary_phys); /* We need to copy. */ std::memcpy(GetVoidPointer(KMemoryLayout::GetLinearVirtualAddress(block_addr)), GetVoidPointer(data), cur_size); From c5d7ca51595871b6ed67fd6140ed8a79140fd51b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 10:55:34 -0700 Subject: [PATCH 030/238] fusee/exo: implement the usual changes for new firmware support --- .../program/source/boot/secmon_boot_key_data.s | 9 +++++++-- exosphere/program/source/boot/secmon_package2.cpp | 2 +- fusee/program/source/fusee_key_derivation.cpp | 11 ++++++++--- fusee/program/source/fusee_package2.cpp | 2 +- fusee/program/source/fusee_setup_horizon.cpp | 2 ++ fusee/program/source/fusee_stratosphere.cpp | 14 ++++++++++++++ .../include/exosphere/pkg1/pkg1_key_generation.hpp | 1 + libraries/libexosphere/include/exosphere/pkg2.hpp | 4 ++-- libraries/libexosphere/source/fuse/fuse_api.cpp | 1 + .../include/stratosphere/hos/hos_types.hpp | 1 + .../include/vapours/ams/ams_api_version.h | 8 ++++---- .../include/vapours/ams/ams_target_firmware.h | 4 +++- 12 files changed, 45 insertions(+), 14 deletions(-) diff --git a/exosphere/program/source/boot/secmon_boot_key_data.s b/exosphere/program/source/boot/secmon_boot_key_data.s index 2be110d84..c8f390eb5 100644 --- a/exosphere/program/source/boot/secmon_boot_key_data.s +++ b/exosphere/program/source/boot/secmon_boot_key_data.s @@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* TODO: Update on next change of keys. */ /* Mariko Development Master Kek Source. */ -.byte 0x3A, 0x9C, 0xF0, 0x39, 0x70, 0x23, 0xF6, 0xAF, 0x71, 0x44, 0x60, 0xF4, 0x6D, 0xED, 0xA1, 0xD6 +.byte 0x43, 0xDB, 0x9D, 0x88, 0xDB, 0x38, 0xE9, 0xBF, 0x3D, 0xD7, 0x83, 0x39, 0xEF, 0xB1, 0x4F, 0xA7 /* Mariko Production Master Kek Source. */ -.byte 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 +.byte 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 /* Development Master Key Vectors. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ @@ -107,6 +107,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x08, 0xE0, 0xF4, 0xBE, 0xAA, 0x6E, 0x5A, 0xC3, 0xA6, 0xBC, 0xFE, 0xB9, 0xE2, 0xA3, 0x24, 0x12 /* Master key 0C encrypted with Master key 0D. */ .byte 0xD6, 0x80, 0x98, 0xC0, 0xFA, 0xC7, 0x13, 0xCB, 0x93, 0xD2, 0x0B, 0x82, 0x4C, 0xA1, 0x7B, 0x8D /* Master key 0D encrypted with Master key 0E. */ .byte 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 /* Master key 0E encrypted with Master key 0F. */ +.byte 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 /* Master key 0F encrypted with Master key 10. */ /* Production Master Key Vectors. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ @@ -125,6 +126,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x83, 0x67, 0xAF, 0x01, 0xCF, 0x93, 0xA1, 0xAB, 0x80, 0x45, 0xF7, 0x3F, 0x72, 0xFD, 0x3B, 0x38 /* Master key 0C encrypted with Master key 0D. */ .byte 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 /* Master key 0D encrypted with Master key 0E. */ .byte 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 /* Master key 0E encrypted with Master key 0F. */ +.byte 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD /* Master key 0F encrypted with Master key 10. */ /* Device Master Key Source Sources. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ @@ -140,6 +142,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x5B, 0x94, 0x63, 0xF7, 0xAD, 0x96, 0x1B, 0xA6, 0x23, 0x30, 0x06, 0x4D, 0x01, 0xE4, 0xCE, 0x1D /* 14.0.0 Device Master Key Source Source. */ .byte 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 /* 15.0.0 Device Master Key Source Source. */ .byte 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C /* 16.0.0 Device Master Key Source Source. */ +.byte 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 /* 17.0.0 Device Master Key Source Source. */ /* Development Device Master Kek Sources. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ @@ -155,6 +158,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xCE, 0x14, 0x74, 0x66, 0x98, 0xA8, 0x6D, 0x7D, 0xBD, 0x54, 0x91, 0x68, 0x5F, 0x1D, 0x0E, 0xEA /* 14.0.0 Device Master Kek Source. */ .byte 0xAE, 0x05, 0x48, 0x65, 0xAB, 0x17, 0x9D, 0x3D, 0x51, 0xB7, 0x56, 0xBD, 0x9B, 0x0B, 0x5B, 0x6E /* 15.0.0 Device Master Kek Source. */ .byte 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F /* 16.0.0 Device Master Kek Source. */ +.byte 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 /* 17.0.0 Device Master Kek Source. */ /* Production Device Master Kek Sources. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ @@ -170,3 +174,4 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x67, 0xD5, 0xD6, 0x0C, 0x08, 0xF5, 0xA3, 0x11, 0xBD, 0x6D, 0x5A, 0xEB, 0x96, 0x24, 0xB0, 0xD2 /* 14.0.0 Device Master Kek Source. */ .byte 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 /* 15.0.0 Device Master Kek Source. */ .byte 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F /* 16.0.0 Device Master Kek Source. */ +.byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */ diff --git a/exosphere/program/source/boot/secmon_package2.cpp b/exosphere/program/source/boot/secmon_package2.cpp index e2187ec6a..a4ad690a9 100644 --- a/exosphere/program/source/boot/secmon_package2.cpp +++ b/exosphere/program/source/boot/secmon_package2.cpp @@ -94,7 +94,7 @@ namespace ams::secmon::boot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 16); + static_assert(pkg1::KeyGeneration_Count == 17); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_key_derivation.cpp b/fusee/program/source/fusee_key_derivation.cpp index 1a7adb41f..a77f07911 100644 --- a/fusee/program/source/fusee_key_derivation.cpp +++ b/fusee/program/source/fusee_key_derivation.cpp @@ -23,17 +23,17 @@ namespace ams::nxboot { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 + 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x3A, 0x9C, 0xF0, 0x39, 0x70, 0x23, 0xF6, 0xAF, 0x71, 0x44, 0x60, 0xF4, 0x6D, 0xED, 0xA1, 0xD6 + 0x43, 0xDB, 0x9D, 0x88, 0xDB, 0x38, 0xE9, 0xBF, 0x3D, 0xD7, 0x83, 0x39, 0xEF, 0xB1, 0x4F, 0xA7 }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x99, 0x22, 0x09, 0x57, 0xA7, 0xF9, 0x5E, 0x94, 0xFE, 0x78, 0x7F, 0x41, 0xD6, 0xE7, 0x56, 0xE6 + 0x71, 0xB9, 0xA6, 0xC0, 0xFF, 0x97, 0x6B, 0x0C, 0xB4, 0x40, 0xB9, 0xD5, 0x81, 0x5D, 0x81, 0x90 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -70,6 +70,7 @@ namespace ams::nxboot { { 0x5B, 0x94, 0x63, 0xF7, 0xAD, 0x96, 0x1B, 0xA6, 0x23, 0x30, 0x06, 0x4D, 0x01, 0xE4, 0xCE, 0x1D }, /* 14.0.0 Device Master Key Source Source. */ { 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 }, /* 15.0.0 Device Master Key Source Source. */ { 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, /* 16.0.0 Device Master Key Source Source. */ + { 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, /* 17.0.0 Device Master Key Source Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -86,6 +87,7 @@ namespace ams::nxboot { { 0x67, 0xD5, 0xD6, 0x0C, 0x08, 0xF5, 0xA3, 0x11, 0xBD, 0x6D, 0x5A, 0xEB, 0x96, 0x24, 0xB0, 0xD2 }, /* 14.0.0 Device Master Kek Source. */ { 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 }, /* 15.0.0 Device Master Kek Source. */ { 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, /* 16.0.0 Device Master Kek Source. */ + { 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, /* 17.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -102,6 +104,7 @@ namespace ams::nxboot { { 0xCE, 0x14, 0x74, 0x66, 0x98, 0xA8, 0x6D, 0x7D, 0xBD, 0x54, 0x91, 0x68, 0x5F, 0x1D, 0x0E, 0xEA }, /* 14.0.0 Device Master Kek Source. */ { 0xAE, 0x05, 0x48, 0x65, 0xAB, 0x17, 0x9D, 0x3D, 0x51, 0xB7, 0x56, 0xBD, 0x9B, 0x0B, 0x5B, 0x6E }, /* 15.0.0 Device Master Kek Source. */ { 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F }, /* 16.0.0 Device Master Kek Source. */ + { 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 }, /* 17.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -121,6 +124,7 @@ namespace ams::nxboot { { 0x83, 0x67, 0xAF, 0x01, 0xCF, 0x93, 0xA1, 0xAB, 0x80, 0x45, 0xF7, 0x3F, 0x72, 0xFD, 0x3B, 0x38 }, /* Master key 0C encrypted with Master key 0D. */ { 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 }, /* Master key 0D encrypted with Master key 0E. */ { 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, /* Master key 0E encrypted with Master key 0F. */ + { 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, /* Master key 0F encrypted with Master key 10. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -140,6 +144,7 @@ namespace ams::nxboot { { 0x08, 0xE0, 0xF4, 0xBE, 0xAA, 0x6E, 0x5A, 0xC3, 0xA6, 0xBC, 0xFE, 0xB9, 0xE2, 0xA3, 0x24, 0x12 }, /* Master key 0C encrypted with Master key 0D. */ { 0xD6, 0x80, 0x98, 0xC0, 0xFA, 0xC7, 0x13, 0xCB, 0x93, 0xD2, 0x0B, 0x82, 0x4C, 0xA1, 0x7B, 0x8D }, /* Master key 0D encrypted with Master key 0E. */ { 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 }, /* Master key 0E encrypted with Master key 0F. */ + { 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 }, /* Master key 0F encrypted with Master key 10. */ }; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; diff --git a/fusee/program/source/fusee_package2.cpp b/fusee/program/source/fusee_package2.cpp index f82dc44ef..63aa2a37d 100644 --- a/fusee/program/source/fusee_package2.cpp +++ b/fusee/program/source/fusee_package2.cpp @@ -80,7 +80,7 @@ namespace ams::nxboot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 16); + static_assert(pkg1::KeyGeneration_Count == 17); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 4476dd6c6..8de07bab4 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -257,6 +257,8 @@ namespace ams::nxboot { return ams::TargetFirmware_15_0_0; } else if (std::memcmp(package1 + 0x10, "20230111", 8) == 0) { return ams::TargetFirmware_16_0_0; + } else if (std::memcmp(package1 + 0x10, "20230906", 8) == 0) { + return ams::TargetFirmware_17_0_0; } break; default: diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index f18bc4646..4ccc0ed41 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -168,6 +168,9 @@ namespace ams::nxboot { FsVersion_16_0_3, FsVersion_16_0_3_Exfat, + FsVersion_17_0_0, + FsVersion_17_0_0_Exfat, + FsVersion_Count, }; @@ -248,6 +251,9 @@ namespace ams::nxboot { { 0x39, 0xEE, 0x1F, 0x1E, 0x0E, 0xA7, 0x32, 0x5D }, /* FsVersion_16_0_3 */ { 0x62, 0xC6, 0x5E, 0xFD, 0x9A, 0xBF, 0x7C, 0x43 }, /* FsVersion_16_0_3_Exfat */ + + { 0x27, 0x07, 0x3B, 0xF0, 0xA1, 0xB8, 0xCE, 0x61 }, /* FsVersion_17_0_0 */ + { 0xEE, 0x0F, 0x4B, 0xAC, 0x6D, 0x1F, 0xFC, 0x4B }, /* FsVersion_17_0_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -673,6 +679,14 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x191409, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x16B9A0, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_17_0_0: + AddPatch(fs_meta, 0x18B149, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x165200, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_17_0_0_Exfat: + AddPatch(fs_meta, 0x195FA9, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x170060, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } diff --git a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp index f5caa9d76..64330af7a 100644 --- a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp +++ b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp @@ -36,6 +36,7 @@ namespace ams::pkg1 { KeyGeneration_14_0_0 = 0x0D, KeyGeneration_15_0_0 = 0x0E, KeyGeneration_16_0_0 = 0x0F, + KeyGeneration_17_0_0 = 0x10, KeyGeneration_Count, diff --git a/libraries/libexosphere/include/exosphere/pkg2.hpp b/libraries/libexosphere/include/exosphere/pkg2.hpp index 824d3ed34..81a3f664d 100644 --- a/libraries/libexosphere/include/exosphere/pkg2.hpp +++ b/libraries/libexosphere/include/exosphere/pkg2.hpp @@ -23,8 +23,8 @@ namespace ams::pkg2 { constexpr inline int PayloadCount = 3; - constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x17 in Nintendo's code. */ - constexpr inline int CurrentBootloaderVersion = 0x13; + constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */ + constexpr inline int CurrentBootloaderVersion = 0x14; struct Package2Meta { using Magic = util::FourCC<'P','K','2','1'>; diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 453720406..95c316d68 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,6 +177,7 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { + TargetFirmware_17_0_0, TargetFirmware_16_0_0, TargetFirmware_15_0_0, TargetFirmware_13_2_1, diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 4b7dc1ed0..303ff796e 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -80,6 +80,7 @@ namespace ams::hos { Version_16_0_2 = ::ams::TargetFirmware_16_0_2, Version_16_0_3 = ::ams::TargetFirmware_16_0_3, Version_16_1_0 = ::ams::TargetFirmware_16_1_0, + Version_17_0_0 = ::ams::TargetFirmware_17_0_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 3d84418e0..8b963d6d3 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -16,11 +16,11 @@ #pragma once #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 -#define ATMOSPHERE_RELEASE_VERSION_MINOR 5 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 5 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 6 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 16 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 17 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 9e6357e22..6288ab832 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -78,8 +78,9 @@ #define ATMOSPHERE_TARGET_FIRMWARE_16_0_2 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 2) #define ATMOSPHERE_TARGET_FIRMWARE_16_0_3 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 3) #define ATMOSPHERE_TARGET_FIRMWARE_16_1_0 ATMOSPHERE_TARGET_FIRMWARE(16, 1, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_16_1_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_17_0_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -150,6 +151,7 @@ namespace ams { TargetFirmware_16_0_2 = ATMOSPHERE_TARGET_FIRMWARE_16_0_2, TargetFirmware_16_0_3 = ATMOSPHERE_TARGET_FIRMWARE_16_0_3, TargetFirmware_16_1_0 = ATMOSPHERE_TARGET_FIRMWARE_16_1_0, + TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From 114b82284dabd37197802487241636620d4419fc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 11:03:17 -0700 Subject: [PATCH 031/238] exo/spl: Add new EsCommonKeyType --- exosphere/program/source/smc/secmon_smc_aes.cpp | 1 + exosphere/program/source/smc/secmon_smc_aes.hpp | 1 + exosphere/program/source/smc/secmon_smc_rsa.cpp | 4 ++-- .../libstratosphere/include/stratosphere/spl/spl_types.hpp | 1 + .../source/spl/smc/spl_secure_monitor_api.os.generic.cpp | 2 ++ 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/exosphere/program/source/smc/secmon_smc_aes.cpp b/exosphere/program/source/smc/secmon_smc_aes.cpp index 1d5f51ded..84999fd72 100644 --- a/exosphere/program/source/smc/secmon_smc_aes.cpp +++ b/exosphere/program/source/smc/secmon_smc_aes.cpp @@ -161,6 +161,7 @@ namespace ams::secmon::smc { constexpr const u8 EsCommonKeySources[EsCommonKeyType_Count][AesKeySize] = { [EsCommonKeyType_TitleKey] = { 0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B }, [EsCommonKeyType_ArchiveKey] = { 0x3B, 0x78, 0xF2, 0x61, 0x0F, 0x9D, 0x5A, 0xE2, 0x7B, 0x4E, 0x45, 0xAF, 0xCB, 0x0B, 0x67, 0x4D }, + [EsCommonKeyType_Unknown2] = { 0x42, 0x64, 0x0B, 0xE3, 0x5F, 0xC6, 0xBE, 0x47, 0xC7, 0xB4, 0x84, 0xC5, 0xEB, 0x63, 0xAA, 0x02 }, }; constexpr const u8 EsSealKeySource[AesKeySize] = { diff --git a/exosphere/program/source/smc/secmon_smc_aes.hpp b/exosphere/program/source/smc/secmon_smc_aes.hpp index 3a570b09a..ce0d8390f 100644 --- a/exosphere/program/source/smc/secmon_smc_aes.hpp +++ b/exosphere/program/source/smc/secmon_smc_aes.hpp @@ -22,6 +22,7 @@ namespace ams::secmon::smc { enum EsCommonKeyType { EsCommonKeyType_TitleKey = 0, EsCommonKeyType_ArchiveKey = 1, + EsCommonKeyType_Unknown2 = 2, EsCommonKeyType_Count, }; diff --git a/exosphere/program/source/smc/secmon_smc_rsa.cpp b/exosphere/program/source/smc/secmon_smc_rsa.cpp index 34982bb8a..b321d27a1 100644 --- a/exosphere/program/source/smc/secmon_smc_rsa.cpp +++ b/exosphere/program/source/smc/secmon_smc_rsa.cpp @@ -32,8 +32,8 @@ namespace ams::secmon::smc { struct PrepareEsDeviceUniqueKeyOption { using KeyGeneration = util::BitPack32::Field<0, 6, int>; - using Type = util::BitPack32::Field<6, 1, EsCommonKeyType>; - using Reserved = util::BitPack32::Field<7, 25, u32>; + using Type = util::BitPack32::Field<6, 2, EsCommonKeyType>; + using Reserved = util::BitPack32::Field<8, 25, u32>; }; constexpr const u8 ModularExponentiateByStorageKeyTable[] = { diff --git a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp index 08444261d..11c80ad48 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/spl_types.hpp @@ -98,6 +98,7 @@ namespace ams::spl { enum class EsDeviceUniqueKeyType { TitleKey = 0, ArchiveKey = 1, + Unknown2 = 2, }; struct AsyncOperationKey { diff --git a/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp b/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp index fead3970e..966912ad9 100644 --- a/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp +++ b/libraries/libstratosphere/source/spl/smc/spl_secure_monitor_api.os.generic.cpp @@ -50,6 +50,7 @@ namespace ams::spl::smc { enum EsCommonKeyType { EsCommonKeyType_TitleKey = 0, EsCommonKeyType_ArchiveKey = 1, + EsCommonKeyType_Unknown2 = 2, EsCommonKeyType_Count, }; @@ -86,6 +87,7 @@ namespace ams::spl::smc { constexpr const u8 EsCommonKeySources[EsCommonKeyType_Count][AesKeySize] = { [EsCommonKeyType_TitleKey] = { 0x1E, 0xDC, 0x7B, 0x3B, 0x60, 0xE6, 0xB4, 0xD8, 0x78, 0xB8, 0x17, 0x15, 0x98, 0x5E, 0x62, 0x9B }, [EsCommonKeyType_ArchiveKey] = { 0x3B, 0x78, 0xF2, 0x61, 0x0F, 0x9D, 0x5A, 0xE2, 0x7B, 0x4E, 0x45, 0xAF, 0xCB, 0x0B, 0x67, 0x4D }, + [EsCommonKeyType_Unknown2] = { 0x42, 0x64, 0x0B, 0xE3, 0x5F, 0xC6, 0xBE, 0x47, 0xC7, 0xB4, 0x84, 0xC5, 0xEB, 0x63, 0xAA, 0x02 }, }; constexpr u64 InvalidAsyncKey = 0; From ef9b111bbf50a145938f86f372e333c39bcec7a0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 11:25:52 -0700 Subject: [PATCH 032/238] emummc: update for 17.0.0 --- emummc/README.md | 2 +- emummc/source/FS/FS_offsets.c | 8 ++++ emummc/source/FS/FS_versions.h | 3 ++ emummc/source/FS/offsets/1700.h | 59 +++++++++++++++++++++++++++ emummc/source/FS/offsets/1700_exfat.h | 59 +++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 emummc/source/FS/offsets/1700.h create mode 100644 emummc/source/FS/offsets/1700_exfat.h diff --git a/emummc/README.md b/emummc/README.md index 95a6a047a..3b36a5a57 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 16.0.3** +**1.0.0 - 17.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index cf4c5dde5..a1031a8bc 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -67,6 +67,8 @@ #include "offsets/1600_exfat.h" #include "offsets/1603.h" #include "offsets/1603_exfat.h" +#include "offsets/1700.h" +#include "offsets/1700_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -145,6 +147,8 @@ DEFINE_OFFSET_STRUCT(_1600); DEFINE_OFFSET_STRUCT(_1600_EXFAT); DEFINE_OFFSET_STRUCT(_1603); DEFINE_OFFSET_STRUCT(_1603_EXFAT); +DEFINE_OFFSET_STRUCT(_1700); +DEFINE_OFFSET_STRUCT(_1700_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -250,6 +254,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1603)); case FS_VER_16_0_3_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1603_EXFAT)); + case FS_VER_17_0_0: + return &(GET_OFFSET_STRUCT_NAME(_1700)); + case FS_VER_17_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_1700_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index a8459bf88..0459f9b9b 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -98,6 +98,9 @@ enum FS_VER FS_VER_16_0_3, FS_VER_16_0_3_EXFAT, + FS_VER_17_0_0, + FS_VER_17_0_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/1700.h b/emummc/source/FS/offsets/1700.h new file mode 100644 index 000000000..0c91f3d58 --- /dev/null +++ b/emummc/source/FS/offsets/1700.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1700_H__ +#define __FS_1700_H__ + +// Accessor vtable getters +#define FS_OFFSET_1700_SDMMC_ACCESSOR_GC 0x18ACF0 +#define FS_OFFSET_1700_SDMMC_ACCESSOR_SD 0x18C9C0 +#define FS_OFFSET_1700_SDMMC_ACCESSOR_NAND 0x18B1C0 + +// Hooks +#define FS_OFFSET_1700_SDMMC_WRAPPER_READ 0x186BC0 +#define FS_OFFSET_1700_SDMMC_WRAPPER_WRITE 0x186C20 +#define FS_OFFSET_1700_RTLD 0x29D10 +#define FS_OFFSET_1700_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C))) + +#define FS_OFFSET_1700_CLKRST_SET_MIN_V_CLK_RATE 0x1A7B60 + +// Misc funcs +#define FS_OFFSET_1700_LOCK_MUTEX 0x17FEA0 +#define FS_OFFSET_1700_UNLOCK_MUTEX 0x17FEF0 + +#define FS_OFFSET_1700_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186B80 +#define FS_OFFSET_1700_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186BA0 + +// Misc Data +#define FS_OFFSET_1700_SD_MUTEX 0xFCE3F0 +#define FS_OFFSET_1700_NAND_MUTEX 0xFC9B78 +#define FS_OFFSET_1700_ACTIVE_PARTITION 0xFC9BB8 +#define FS_OFFSET_1700_SDMMC_DAS_HANDLE 0xFAF840 + +// NOPs +#define FS_OFFSET_1700_SD_DAS_INIT 0x28C64 + +// Nintendo Paths +#define FS_OFFSET_1700_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068068, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007510C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007BEAC, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0008F674, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1700_H__ diff --git a/emummc/source/FS/offsets/1700_exfat.h b/emummc/source/FS/offsets/1700_exfat.h new file mode 100644 index 000000000..449e2ead7 --- /dev/null +++ b/emummc/source/FS/offsets/1700_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1700_EXFAT_H__ +#define __FS_1700_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_GC 0x195B50 +#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_SD 0x197820 +#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_NAND 0x196020 + +// Hooks +#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_READ 0x191A20 +#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_WRITE 0x191A80 +#define FS_OFFSET_1700_EXFAT_RTLD 0x29D10 +#define FS_OFFSET_1700_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x3C))) + +#define FS_OFFSET_1700_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B29C0 + +// Misc funcs +#define FS_OFFSET_1700_EXFAT_LOCK_MUTEX 0x18AD00 +#define FS_OFFSET_1700_EXFAT_UNLOCK_MUTEX 0x18AD50 + +#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1919E0 +#define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191A00 + +// Misc Data +#define FS_OFFSET_1700_EXFAT_SD_MUTEX 0xFE03F0 +#define FS_OFFSET_1700_EXFAT_NAND_MUTEX 0xFDBB78 +#define FS_OFFSET_1700_EXFAT_ACTIVE_PARTITION 0xFDBBB8 +#define FS_OFFSET_1700_EXFAT_SDMMC_DAS_HANDLE 0xFBC840 + +// NOPs +#define FS_OFFSET_1700_EXFAT_SD_DAS_INIT 0x28C64 + +// Nintendo Paths +#define FS_OFFSET_1700_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068068, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007510C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007BEAC, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0008F674, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1700_EXFAT_H__ From c95741142edff86cf1e3af8863d25adfe3249657 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 12:31:37 -0700 Subject: [PATCH 033/238] ncm: update for new 17.0.0 apis --- .../include/stratosphere/fs.hpp | 1 + .../include/stratosphere/fs/fs_program_id.hpp | 26 ++++++++++++++ .../fssrv/fssrv_file_system_proxy_impl.hpp | 1 + .../fssrv/sf/fssrv_sf_i_file_system_proxy.hpp | 1 + .../stratosphere/ncm/ncm_content_meta.hpp | 6 ++-- .../ncm/ncm_content_meta_database.hpp | 5 +++ .../ncm/ncm_content_meta_platform.hpp | 25 +++++++++++++ .../stratosphere/ncm/ncm_content_storage.hpp | 5 +++ .../ncm/ncm_i_content_meta_database.hpp | 3 +- .../ncm/ncm_i_content_storage.hpp | 3 +- ..._integrated_content_meta_database_impl.hpp | 1 + .../ncm_integrated_content_storage_impl.hpp | 1 + .../source/fs/fs_program_id.cpp | 36 +++++++++++++++++++ .../source/fs/fs_remote_file_system_proxy.hpp | 4 +++ .../fs/impl/fs_id_string_impl.os.generic.cpp | 5 +-- .../source/ncm/ncm_content_meta.cpp | 2 ++ .../ncm/ncm_content_meta_database_impl.cpp | 16 +++++++++ .../ncm/ncm_content_meta_database_impl.hpp | 1 + .../ncm_content_meta_database_impl_base.hpp | 1 + .../source/ncm/ncm_content_storage_impl.cpp | 15 ++++++++ .../source/ncm/ncm_content_storage_impl.hpp | 1 + .../ncm/ncm_content_storage_impl_base.hpp | 1 + .../ncm/ncm_host_content_storage_impl.cpp | 23 ++++++++++++ .../ncm/ncm_host_content_storage_impl.hpp | 1 + ..._integrated_content_meta_database_impl.cpp | 17 +++++++++ .../ncm_integrated_content_storage_impl.cpp | 27 ++++++++++++++ .../ncm_read_only_content_storage_impl.cpp | 15 ++++++++ .../ncm_read_only_content_storage_impl.hpp | 1 + .../ncm_remote_content_meta_database_impl.hpp | 5 +++ .../ncm/ncm_remote_content_storage_impl.hpp | 5 +++ .../include/vapours/results/ncm_results.hpp | 2 ++ 31 files changed, 249 insertions(+), 7 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_platform.hpp create mode 100644 libraries/libstratosphere/source/fs/fs_program_id.cpp diff --git a/libraries/libstratosphere/include/stratosphere/fs.hpp b/libraries/libstratosphere/include/stratosphere/fs.hpp index 7aafab832..13b7603d1 100644 --- a/libraries/libstratosphere/include/stratosphere/fs.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs.hpp @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp new file mode 100644 index 000000000..e2f000002 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_program_id.hpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include + +namespace ams::fs { + + /* ACCURATE_TO_VERSION: 17.5.0.0 */ + Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr); + +} \ No newline at end of file diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp index c05920cc8..0ddba8f7c 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -104,6 +104,7 @@ namespace ams::fssrv { Result GetRightsId(ams::sf::Out out, ncm::ProgramId program_id, ncm::StorageId storage_id); Result RegisterExternalKey(const fs::RightsId &rights_id, const spl::AccessKey &access_key); Result UnregisterAllExternalKey(); + Result GetProgramId(ams::sf::Out out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr); Result GetRightsIdByPath(ams::sf::Out out, const fssrv::sf::FspPath &path); Result GetRightsIdAndKeyGenerationByPathObsolete(ams::sf::Out out, ams::sf::Out out_key_generation, const fssrv::sf::FspPath &path); Result GetRightsIdAndKeyGenerationByPath(ams::sf::Out out, ams::sf::Out out_key_generation, const fssrv::sf::FspPath &path, fs::ContentAttributes attr); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp index 5e8fade2f..ba41abb80 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp @@ -115,6 +115,7 @@ AMS_SF_METHOD_INFO(C, H, 615, Result, QuerySaveDataInternalStorageTotalSize, (), (), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 616, Result, GetSaveDataCommitId, (), (), hos::Version_6_0_0) \ AMS_SF_METHOD_INFO(C, H, 617, Result, UnregisterExternalKey, (const fs::RightsId &rights_id), (rights_id), hos::Version_7_0_0) \ + AMS_SF_METHOD_INFO(C, H, 618, Result, GetProgramId, (ams::sf::Out out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr), (out, path, attr), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 620, Result, SetSdCardEncryptionSeed, (const fs::EncryptionSeed &seed), (seed), hos::Version_2_0_0) \ AMS_SF_METHOD_INFO(C, H, 630, Result, SetSdCardAccessibility, (bool accessible), (accessible), hos::Version_4_0_0) \ AMS_SF_METHOD_INFO(C, H, 631, Result, IsSdCardAccessible, (ams::sf::Out out), (out), hos::Version_4_0_0) \ diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp index b00fe8cb1..4b7ac2ba8 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta.hpp @@ -16,6 +16,7 @@ #pragma once #include #include +#include #include #include #include @@ -58,7 +59,7 @@ namespace ams::ncm { u16 content_count; u16 content_meta_count; u8 attributes; - StorageId storage_id; + ContentMetaPlatform platform; }; static_assert(sizeof(ContentMetaHeader) == 0x8); @@ -67,7 +68,7 @@ namespace ams::ncm { u64 id; u32 version; ContentMetaType type; - u8 reserved_0D; + ContentMetaPlatform platform; u16 extended_header_size; u16 content_count; u16 content_meta_count; @@ -79,7 +80,6 @@ namespace ams::ncm { u8 reserved_1C[4]; }; static_assert(sizeof(PackagedContentMetaHeader) == 0x20); - static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_0D) == 0x0D); static_assert(AMS_OFFSETOF(PackagedContentMetaHeader, reserved_1C) == 0x1C); using InstallContentMetaHeader = PackagedContentMetaHeader; diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp index 947fbfaad..fde547802 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp @@ -221,6 +221,11 @@ namespace ams::ncm { AMS_ASSERT(m_interface != nullptr); R_RETURN(m_interface->GetContentInfoByTypeAndIdOffset(out_content_info, key, type, id_offset)); } + + Result GetPlatform(ContentMetaPlatform *out, const ContentMetaKey &key) { + AMS_ASSERT(m_interface != nullptr); + R_RETURN(m_interface->GetPlatform(out, key)); + } }; } diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_platform.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_platform.hpp new file mode 100644 index 000000000..2a08d8419 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_platform.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::ncm { + + enum class ContentMetaPlatform : u8 { + Nx = 0x0, + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp index a7ad71aca..64512681b 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_storage.hpp @@ -207,6 +207,11 @@ namespace ams::ncm { R_RETURN(m_interface->GetRightsIdFromPlaceHolderIdWithCacheDeprecated(out_rights_id, cache_content_id, placeholder_id)); } } + + Result GetProgramId(ncm::ProgramId *out, ContentId content_id, fs::ContentAttributes attr) { + AMS_ASSERT(m_interface != nullptr); + R_RETURN(m_interface->GetProgramId(out, content_id, attr)); + } }; } diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp index 411701b79..099de50fb 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp @@ -43,7 +43,8 @@ AMS_SF_METHOD_INFO(C, H, 22, Result, GetOwnerApplicationId, (sf::Out out_id, const ncm::ContentMetaKey &key), (out_id, key), hos::Version_10_0_0) \ AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out out_accessibilities, const ncm::ContentMetaKey &key), (out_accessibilities, key), hos::Version_15_0_0) \ AMS_SF_METHOD_INFO(C, H, 24, Result, GetContentInfoByType, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_info, key, type), hos::Version_15_0_0) \ - AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) + AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) \ + AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp index 250e84dc9..3ea0b73fb 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_storage.hpp @@ -58,6 +58,7 @@ AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCacheDeprecated, (sf::Out out_rights_id, ncm::ContentId cache_content_id, ncm::PlaceHolderId placeholder_id), (out_rights_id, cache_content_id, placeholder_id), hos::Version_8_0_0, hos::Version_15_0_1) \ AMS_SF_METHOD_INFO(C, H, 27, Result, GetRightsIdFromPlaceHolderIdWithCache, (sf::Out out_rights_id, ncm::PlaceHolderId placeholder_id, ncm::ContentId cache_content_id, fs::ContentAttributes attr), (out_rights_id, placeholder_id, cache_content_id, attr), hos::Version_16_0_0) \ AMS_SF_METHOD_INFO(C, H, 28, Result, RegisterPath, (const ncm::ContentId &content_id, const ncm::Path &path), (content_id, path), hos::Version_13_0_0) \ - AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0) + AMS_SF_METHOD_INFO(C, H, 29, Result, ClearRegisteredPath, (), (), hos::Version_13_0_0) \ + AMS_SF_METHOD_INFO(C, H, 30, Result, GetProgramId, (sf::Out out, ncm::ContentId content_id, fs::ContentAttributes attr), (out, content_id, attr), hos::Version_17_0_0) AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentStorage, AMS_NCM_I_CONTENT_STORAGE_INTERFACE_INFO, 0xFEAE3DD1) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp index 05ebe160d..38bfc154f 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp @@ -71,6 +71,7 @@ namespace ams::ncm { Result GetContentAccessibilities(sf::Out out_accessibilities, const ContentMetaKey &key); Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type); Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset); + Result GetPlatform(sf::Out out, const ContentMetaKey &key); }; static_assert(ncm::IsIContentMetaDatabase); diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp index f29c3e0f4..40a3063d0 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_storage_impl.hpp @@ -79,6 +79,7 @@ namespace ams::ncm { Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr); Result RegisterPath(const ContentId &content_id, const Path &path); Result ClearRegisteredPath(); + Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr); /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } diff --git a/libraries/libstratosphere/source/fs/fs_program_id.cpp b/libraries/libstratosphere/source/fs/fs_program_id.cpp new file mode 100644 index 000000000..3ef64dae7 --- /dev/null +++ b/libraries/libstratosphere/source/fs/fs_program_id.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include +#include "impl/fs_file_system_proxy_service_object.hpp" + +namespace ams::fs { + + Result GetProgramId(ncm::ProgramId *out, const char *path, fs::ContentAttributes attr) { + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(path != nullptr, fs::ResultNullptrArgument()); + + /* Convert the path for fsp. */ + fssrv::sf::FspPath sf_path; + R_TRY(fs::ConvertToFspPath(std::addressof(sf_path), path)); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + AMS_FS_R_TRY(fsp->GetProgramId(out, sf_path, attr)); + + R_SUCCEED(); + } + +} \ No newline at end of file diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp index f7eda97ad..ae9b8b492 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp @@ -320,6 +320,10 @@ namespace ams::fs { AMS_ABORT("TODO"); } + Result GetProgramId(ams::sf::Out out, const fssrv::sf::FspPath &path, fs::ContentAttributes attr) { + static_assert(sizeof(ncm::ProgramId) == sizeof(u64)); + R_RETURN(fsGetProgramId(reinterpret_cast(out.GetPointer()), path.str, static_cast<::FsContentAttributes>(static_cast(attr)))); + } Result GetRightsIdByPath(ams::sf::Out out, const fssrv::sf::FspPath &path) { static_assert(sizeof(RightsId) == sizeof(::FsRightsId)); diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp index c1e99b108..2922a2c1c 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -21,7 +21,7 @@ namespace ams::fs::impl { #define ADD_ENUM_CASE(v) case v: return #v template<> const char *IdString::ToString(pkg1::KeyGeneration id) { - static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_16_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_17_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -39,7 +39,8 @@ namespace ams::fs::impl { case KeyGeneration_13_0_0: return "13.0.0-13.2.1"; case KeyGeneration_14_0_0: return "14.0.0-14.1.2"; case KeyGeneration_15_0_0: return "15.0.0-15.0.1"; - case KeyGeneration_16_0_0: return "16.0.0-"; + case KeyGeneration_16_0_0: return "16.0.0-16.0.3"; + case KeyGeneration_17_0_0: return "17.0.0-"; default: return "Unknown"; } } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp b/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp index c505ecbd8..02f648a50 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta.cpp @@ -26,6 +26,7 @@ namespace ams::ncm { .content_count = src.content_count, .content_meta_count = src.content_meta_count, .attributes = src.attributes, + .platform = src.platform, }; } @@ -42,6 +43,7 @@ namespace ams::ncm { .content_count = src.content_count, .content_meta_count = src.content_meta_count, .attributes = src.attributes, + .platform = src.platform, }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp index 8b84f9114..da23ce454 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp @@ -518,4 +518,20 @@ namespace ams::ncm { R_RETURN(this->GetContentInfoImpl(out_content_info.GetPointer(), key, type, util::make_optional(id_offset))); } + Result ContentMetaDatabaseImpl::GetPlatform(sf::Out out, const ContentMetaKey &key) { + R_TRY(this->EnsureEnabled()); + + /* Obtain the content meta for the key. */ + const void *meta; + size_t meta_size; + R_TRY(this->GetContentMetaPointer(&meta, &meta_size, key)); + + /* Create a reader. */ + ContentMetaReader reader(meta, meta_size); + + /* Set the ouput value. */ + out.SetValue(reader.GetHeader()->platform); + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp index 7b51783cc..9d6bcfb46 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp @@ -64,6 +64,7 @@ namespace ams::ncm { virtual Result GetContentAccessibilities(sf::Out out_accessibilities, const ContentMetaKey &key) override; virtual Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type) override; virtual Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) override; + virtual Result GetPlatform(sf::Out out, const ContentMetaKey &key) override; }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp index d89483d80..7c0d57c30 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp @@ -80,6 +80,7 @@ namespace ams::ncm { virtual Result GetContentAccessibilities(sf::Out out_accessibilities, const ContentMetaKey &key) = 0; virtual Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type) = 0; virtual Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0; + virtual Result GetPlatform(sf::Out out, const ContentMetaKey &key) = 0; }; static_assert(ncm::IsIContentMetaDatabase); diff --git a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp index 0a8359d93..db0387503 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.cpp @@ -918,4 +918,19 @@ namespace ams::ncm { R_THROW(ncm::ResultInvalidOperation()); } + Result ContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { + R_TRY(this->EnsureEnabled()); + + /* Get the path of the content. */ + Path path; + R_TRY(this->GetPath(std::addressof(path), content_id)); + + /* Obtain the program id for the content. */ + ncm::ProgramId program_id; + R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr)); + + out.SetValue(program_id); + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp index b9b9b7455..5f9ae6904 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl.hpp @@ -105,6 +105,7 @@ namespace ams::ncm { virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) override; virtual Result RegisterPath(const ContentId &content_id, const Path &path) override; virtual Result ClearRegisteredPath() override; + virtual Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) override; }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp index 52f21022b..945d41683 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_storage_impl_base.hpp @@ -79,6 +79,7 @@ namespace ams::ncm { virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) = 0; virtual Result RegisterPath(const ContentId &content_id, const Path &path) = 0; virtual Result ClearRegisteredPath() = 0; + virtual Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) = 0; /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } diff --git a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp index 3ae075e09..592a2df3f 100644 --- a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.cpp @@ -224,4 +224,27 @@ namespace ams::ncm { R_SUCCEED(); } + Result HostContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { + R_TRY(this->EnsureEnabled()); + + /* Get the content path. */ + Path path; + R_TRY(m_registered_content->GetPath(std::addressof(path), content_id)); + + /* Check for correct extension. */ + const auto path_len = std::strlen(path.str); + const char *extension = path.str + path_len - 1; + if (*extension == '/') { + --extension; + } + R_UNLESS(path_len >= 4 && std::memcmp(extension - 4, ".ncd", 4) == 0, ncm::ResultInvalidContentMetaDirectory()); + + /* Obtain the program id for the content. */ + ncm::ProgramId program_id; + R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr)); + + out.SetValue(program_id); + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp index 7b4472c74..4a54063b3 100644 --- a/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_host_content_storage_impl.hpp @@ -77,6 +77,7 @@ namespace ams::ncm { Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr); Result RegisterPath(const ContentId &content_id, const Path &path); Result ClearRegisteredPath(); + Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr); /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } diff --git a/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp index 2a0ca8f51..b498464cf 100644 --- a/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp @@ -446,4 +446,21 @@ namespace ams::ncm { })); } + Result IntegratedContentMetaDatabaseImpl::GetPlatform(sf::Out out, const ContentMetaKey &key) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + /* Check that we're enabled. */ + R_TRY(this->EnsureEnabled()); + + /* Check that our list has interfaces to check. */ + R_UNLESS(m_list.GetCount() > 0, ncm::ResultContentMetaNotFound()); + + /* Check each interface in turn. */ + R_RETURN(m_list.TryEach([&](const auto &data) { + /* Try the current interface. */ + R_RETURN(data.interface->GetPlatform(out, key)); + })); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp index 6c7436f44..1853e6b89 100644 --- a/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_integrated_content_storage_impl.cpp @@ -326,4 +326,31 @@ namespace ams::ncm { R_THROW(ncm::ResultInvalidOperation()); } + Result IntegratedContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + /* Check that we're enabled. */ + R_TRY(this->EnsureEnabled()); + + /* Check that our list has interfaces to check. */ + R_UNLESS(m_list.GetCount() > 0, ncm::ResultContentNotFound()); + + /* Check each interface in turn. */ + R_TRY(m_list.TryEach([&](const auto &data) { + /* Check if the current interface has it. */ + bool has; + R_TRY(data.interface->Has(std::addressof(has), content_id)); + + /* If it doesn't, continue on. */ + R_UNLESS(has, ncm::ResultContentNotFound()); + + + /* If it does, read the file. */ + R_RETURN(data.interface->GetProgramId(out, content_id, attr)); + })); + + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp index 635730585..a25f23b1d 100644 --- a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.cpp @@ -297,4 +297,19 @@ namespace ams::ncm { R_THROW(ncm::ResultInvalidOperation()); } + Result ReadOnlyContentStorageImpl::GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { + R_TRY(this->EnsureEnabled()); + + /* Get the path of the content. */ + Path path; + R_TRY(this->GetPath(std::addressof(path), content_id)); + + /* Obtain the program id for the content. */ + ncm::ProgramId program_id; + R_TRY(fs::GetProgramId(std::addressof(program_id), path.str, attr)); + + out.SetValue(program_id); + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp index f42c630da..c00a3ae11 100644 --- a/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_read_only_content_storage_impl.hpp @@ -58,6 +58,7 @@ namespace ams::ncm { virtual Result GetRightsIdFromPlaceHolderIdWithCache(sf::Out out_rights_id, PlaceHolderId placeholder_id, ContentId cache_content_id, fs::ContentAttributes attr) override; virtual Result RegisterPath(const ContentId &content_id, const Path &path) override; virtual Result ClearRegisteredPath() override; + virtual Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) override; }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp index 0919d6d45..a0d8a4286 100644 --- a/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp @@ -186,6 +186,11 @@ namespace ams::ncm { AMS_UNUSED(out_content_info, key, type, id_offset); AMS_ABORT(); } + + Result GetPlatform(sf::Out out, const ContentMetaKey &key) { + static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8)); + R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast(out.GetPointer()), Convert(key))); + } }; static_assert(ncm::IsIContentMetaDatabase); #endif diff --git a/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp index ac809a5e6..87c88bbdc 100644 --- a/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_remote_content_storage_impl.hpp @@ -219,6 +219,11 @@ namespace ams::ncm { R_RETURN(ncmContentStorageClearRegisteredPath(std::addressof(m_srv))); } + Result GetProgramId(sf::Out out, ContentId content_id, fs::ContentAttributes attr) { + static_assert(sizeof(ncm::ProgramId) == sizeof(u64)); + R_RETURN(ncmContentStorageGetProgramId(std::addressof(m_srv), reinterpret_cast(out.GetPointer()), Convert(content_id), Convert(attr))); + } + /* 16.0.0 Alignment change hacks. */ Result CreatePlaceHolder_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id, s64 size) { R_RETURN(this->CreatePlaceHolder(placeholder_id, content_id, size)); } Result Register_AtmosphereAlignmentFix(ContentId content_id, PlaceHolderId placeholder_id) { R_RETURN(this->Register(placeholder_id, content_id)); } diff --git a/libraries/libvapours/include/vapours/results/ncm_results.hpp b/libraries/libvapours/include/vapours/results/ncm_results.hpp index 45d7c3a0a..2092cf0ce 100644 --- a/libraries/libvapours/include/vapours/results/ncm_results.hpp +++ b/libraries/libvapours/include/vapours/results/ncm_results.hpp @@ -54,6 +54,8 @@ namespace ams::ncm { R_DEFINE_ERROR_RESULT(InvalidContentMetaFileSize, 390); R_DEFINE_ERROR_RESULT(InvalidAddOnContentMetaExtendedHeader, 400); + R_DEFINE_ERROR_RESULT(InvalidContentMetaDirectory, 430); + R_DEFINE_ERROR_RANGE(ContentStorageNotActive, 250, 258); R_DEFINE_ERROR_RESULT(GameCardContentStorageNotActive, 251); R_DEFINE_ERROR_RESULT(BuiltInSystemContentStorageNotActive, 252); From 9d4cb685a7844d5b3496712f33fe6a713e32b5e3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 12:45:11 -0700 Subject: [PATCH 034/238] fs: update OpenCodeFileSystem abi for 17.0.0 --- .../fssrv/fssrv_file_system_proxy_impl.hpp | 10 ++++++++-- .../sf/fssrv_sf_i_file_system_proxy_for_loader.hpp | 5 +++-- libraries/libstratosphere/source/fs/fs_code.cpp | 2 +- .../fs/fs_remote_file_system_proxy_for_loader.hpp | 10 +++++++++- .../source/fssrv/fssrv_file_system_proxy_impl.cpp | 7 ++++++- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp index 0ddba8f7c..64d43c1d2 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -147,7 +147,8 @@ namespace ams::fssrv { /* fsp-ldr */ Result OpenCodeFileSystemDeprecated(ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id); Result OpenCodeFileSystemDeprecated2(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id); - Result OpenCodeFileSystem(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); Result IsArchivedProgram(ams::sf::Out out, u64 process_id); }; static_assert(sf::IsIFileSystemProxy); @@ -166,7 +167,12 @@ namespace ams::fssrv { R_THROW(fs::ResultPortAcceptableCountLimited()); } - Result OpenCodeFileSystem(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + AMS_UNUSED(out_fs, out_verif, path, attr, program_id); + R_THROW(fs::ResultPortAcceptableCountLimited()); + } + + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { AMS_UNUSED(out_fs, out_verif, path, attr, program_id); R_THROW(fs::ResultPortAcceptableCountLimited()); } diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp index 4ba1f0a8f..fef147445 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp @@ -20,11 +20,12 @@ #include #include -/* ACCURATE_TO_VERSION: 13.4.0.0 */ +/* ACCURATE_TO_VERSION: 17.5.0.0 */ #define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_0_3) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) diff --git a/libraries/libstratosphere/source/fs/fs_code.cpp b/libraries/libstratosphere/source/fs/fs_code.cpp index 23fa37a13..a8015cd6a 100644 --- a/libraries/libstratosphere/source/fs/fs_code.cpp +++ b/libraries/libstratosphere/source/fs/fs_code.cpp @@ -79,7 +79,7 @@ namespace ams::fs { R_TRY(fsp->SetCurrentProcess({})); sf::SharedPointer fs; - R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), out_verification_data, sf_path, attr, program_id)); + R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id)); /* Allocate a new filesystem wrapper. */ auto fsa = std::make_unique(std::move(fs)); diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp index fff9ba88c..71edaeb4f 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp @@ -47,7 +47,15 @@ namespace ams::fs { R_SUCCEED(); } - Result OpenCodeFileSystem(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + ::FsFileSystem fs; + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + + out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); + R_SUCCEED(); + } + + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { ::FsFileSystem fs; R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp index 75b7b7276..c3336bfb7 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -465,7 +465,12 @@ namespace ams::fssrv { AMS_UNUSED(out_fs, out_verif, path, program_id); } - Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result FileSystemProxyImpl::OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + AMS_ABORT("TODO"); + AMS_UNUSED(out_fs, out_verif, path, attr, program_id); + } + + Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { AMS_ABORT("TODO"); AMS_UNUSED(out_fs, out_verif, path, attr, program_id); } From aa170a72a9f6c444ccd4f2d185f2d376740cc659 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 13:32:22 -0700 Subject: [PATCH 035/238] erpt: Add basic (TODO-impl post-prerelease) support for 17.0.0 changes --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 1294 ++++++++--------- .../erpt/erpt_ids_deprecated.autogen.hpp | 693 +++++++++ .../include/stratosphere/erpt/erpt_types.hpp | 20 + .../erpt/sf/erpt_sf_i_context.hpp | 38 +- .../stratosphere/erpt/srv/erpt_srv_types.hpp | 53 + ...ssrv_sf_i_file_system_proxy_for_loader.hpp | 2 +- .../source/erpt/srv/erpt_srv_cipher.hpp | 10 +- .../source/erpt/srv/erpt_srv_context_impl.cpp | 20 +- .../source/erpt/srv/erpt_srv_context_impl.hpp | 6 +- .../erpt/srv/erpt_srv_context_record.cpp | 8 +- .../erpt/srv/erpt_srv_forced_shutdown.cpp | 4 +- .../source/erpt/srv/erpt_srv_formatter.hpp | 6 +- .../source/erpt/srv/erpt_srv_main.cpp | 4 +- .../source/erpt/srv/erpt_srv_reporter.cpp | 70 +- .../source/erpt/srv/erpt_srv_reporter.hpp | 6 +- 15 files changed, 1487 insertions(+), 747 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index ef867f14c..f81272ccd 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -178,676 +178,630 @@ HANDLER(BuiltInWirelessOUIInfo, 137) \ HANDLER(WirelessAPOUIInfo, 138) \ HANDLER(EthernetAdapterOUIInfo, 139) \ + HANDLER(NANDTypeInfo, 140) \ + HANDLER(MicroSDTypeInfo, 141) \ #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ - HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ - HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ - HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ - HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ - HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ - HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ - HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ - HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ - HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ - HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ + HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ + HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(IPAddressAcquisitionMethod, 18, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SubnetMask, 19, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GatewayIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DNSType, 21, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PriorityDNSIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AlternateDNSIPAddress, 23, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseProxyFlag, 24, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProxyIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProxyPort, 26, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProxyAutoAuthenticateFlag, 27, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(MTU, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ConnectAutomaticallyFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(UseStealthNetworkFlag, 30, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LimitHighCapacityFlag, 31, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NATType, 32, NATTypeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EnableWirelessInterfaceFlag, 33, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableWifiFlag, 34, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableBluetoothFlag, 35, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableNFCFlag, 36, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NintendoZoneSSIDListVersion, 37, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationID, 38, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationTitle, 39, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationVersion, 40, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationStorageLocation, 41, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProductModel, 42, ProductModelInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentLanguage, 43, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseNetworkTimeProtocolFlag, 44, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TimeZone, 45, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(VideoOutputSetting, 46, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDFreeSpace, 47, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SDCardFreeSpace, 48, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SerialNumber, 49, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(OsVersion, 50, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ScreenBrightnessAutoAdjustFlag, 51, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HdmiAudioOutputMode, 52, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SpeakerAudioOutputMode, 53, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MuteOnHeadsetUnpluggedFlag, 54, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerVibrationVolume, 55, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LockScreenFlag, 56, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(InternalBatteryLotNumber, 57, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NotifyInGameDownloadCompletionFlag, 58, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotificationSoundFlag, 59, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVResolutionSetting, 60, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RGBRangeSetting, 61, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ReduceScreenBurnFlag, 62, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVAllowsCecFlag, 63, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HandheldModeTimeToScreenSleep, 64, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleModeTimeToScreenSleep, 65, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(StopAutoSleepDuringContentPlayFlag, 66, SleepInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed, 67, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed, 68, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardCID, 69, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDCID, 70, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCID, 71, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDSpeedMode, 72, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MicroSDSpeedMode, 73, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(USB3AvailableFlag, 74, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(RegionSetting, 75, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoZoneConnectedFlag, 76, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ScreenBrightnessLevel, 77, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProgramId, 78, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbortFlag, 79, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ReportVisibilityFlag, 80, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatalFlag, 81, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OccurrenceTimestampNet, 82, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ResultBacktrace, 83, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch64, 84, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(StackBacktrace64, 85, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(RegisterSetFlag64, 86, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr64, 87, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AbortType, 88, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PrivateOsVersion, 89, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentSystemPowerState, 90, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PreviousSystemPowerState, 91, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DestinationSystemPowerState, 92, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionCurrentState, 93, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionPreviousState, 94, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscInitializedList, 95, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PscCurrentPmStateList, 96, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PscNextPmStateList, 97, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PerformanceMode, 98, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PerformanceConfiguration, 99, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(Throttled, 100, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ThrottlingDuration, 101, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ThrottlingTimestamp, 102, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardCrcErrorCount, 103, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicCrcErrorCount, 104, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRefreshCount, 105, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadRetryCount, 106, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidBlock, 107, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock, 108, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(CreateProcessFailureFlag, 109, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TemperaturePcb, 110, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TemperatureSoc, 111, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CurrentFanDuty, 112, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 113, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CradlePdcHFwVersion, 114, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradlePdcAFwVersion, 115, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleMcuFwVersion, 116, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleDp2HdmiFwVersion, 117, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningApplicationId, 118, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationTitle, 119, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersion, 120, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationStorageLocation, 121, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningAppletList, 122, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(FocusedAppletHistory, 123, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(CompositorState, 124, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorLayerState, 125, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorDisplayState, 126, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorHWCState, 127, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InputCurrentLimit, 128, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimit, 129, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastChargeCurrentLimit, 130, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeVoltageLimit, 131, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeConfiguration, 132, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizMode, 133, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeEnabled, 134, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PowerSupplyPath, 135, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryTemperature, 136, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargePercent, 137, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargeVoltage, 138, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryAge, 139, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerRole, 140, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyType, 141, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyVoltage, 142, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyCurrent, 143, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastBatteryChargingEnabled, 144, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquired, 145, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequested, 146, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 147, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 148, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 149, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDPatrolCount, 150, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationFailures, 151, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationErrorCorrections, 152, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteFailures, 153, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteErrorCorrections, 154, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDErrorLog, 155, NANDDriverLog, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardUserAreaSize, 156, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardProtectedAreaSize, 157, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardNumActivationFailures, 158, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumActivationErrorCorrections, 159, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteFailures, 160, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteErrorCorrections, 161, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardErrorLog, 162, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptionKey, 163, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardTimeoutRetryErrorCount, 164, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptCount, 165, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptRetryOutCount, 166, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertionCount, 167, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRemovalCount, 168, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicInitializeCount, 169, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestU16, 170, Test, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(TestU8, 171, Test, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestI16, 172, Test, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(TestI8, 173, Test, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(SystemAppletScene, 174, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CodecType, 175, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DecodeBuffers, 176, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FrameWidth, 177, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FrameHeight, 178, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorPrimaries, 179, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TransferCharacteristics, 180, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(MatrixCoefficients, 181, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(DisplayWidth, 182, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DisplayHeight, 183, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARWidth, 184, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARHeight, 185, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorFormat, 186, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ColorSpace, 187, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SurfaceLayout, 188, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BitStream, 189, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(VideoDecState, 190, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GpuErrorChannelId, 191, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorAruId, 192, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorType, 193, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultInfo, 194, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorWriteAccess, 195, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(GpuErrorFaultAddress, 196, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorFaultUnit, 197, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultType, 198, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorHwContextPointer, 199, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorContextStatus, 200, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaIntr, 201, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaErrorType, 202, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeaderShadow, 203, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeader, 204, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow0, 205, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow1, 206, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AccessPointChannel, 207, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ThreadName, 208, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AdspExceptionRegisters, 209, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsr, 210, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionProgramCounter, 211, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionLinkRegister, 212, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackPointer, 213, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegisters, 214, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddress, 215, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDump, 216, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 217, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 218, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 219, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 220, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 221, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 222, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 223, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 224, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(ModuleClockFrequencies, 225, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 226, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 227, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleResetAssertFlags, 228, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleMinimumVoltageClockRates, 229, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 230, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 231, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(AccessPointRssi, 232, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FuseInfo, 233, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(VideoLog, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardDeviceId, 235, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeCount, 236, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureCount, 237, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureDetail, 238, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardRefreshSuccessCount, 239, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAwakenCount, 240, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAwakenFailureCount, 241, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromInsert, 242, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromAwaken, 243, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageAddress, 244, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageCount, 245, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AppletManagerContextTrace, 246, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispIsRegistered, 247, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispIsSuspend, 248, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDC0SurfaceNum, 249, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispDC1SurfaceNum, 250, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectX, 251, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectY, 252, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectWidth, 253, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectHeight, 254, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectX, 255, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectY, 256, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectWidth, 257, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectHeight, 258, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowIndex, 259, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowBlendOperation, 260, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlphaOperation, 261, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDepth, 262, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlpha, 263, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispWindowHFilter, 264, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowVFilter, 265, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowOptions, 266, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSyncPointId, 267, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPSorPower, 268, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPClkType, 269, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPEnable, 270, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPState, 271, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdid, 272, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDPEdidSize, 273, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdidExtSize, 274, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPFakeMode, 275, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPModeNumber, 276, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPPlugInOut, 277, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPAuxIntHandler, 278, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPForceMaxLinkBW, 279, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPIsConnected, 280, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkValid, 281, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxBW, 282, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxLaneCount, 283, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkDownSpread, 284, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportEnhancedFraming, 285, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBpp, 286, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScaramberCap, 287, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBW, 288, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLaneCount, 289, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkEnhancedFraming, 290, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScrambleEnable, 291, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActivePolarity, 292, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveCount, 293, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTUSize, 294, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveFrac, 295, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkWatermark, 296, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkHBlank, 297, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkVBlank, 298, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEnhancedFraming, 299, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEdpCap, 300, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportFastLT, 301, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLTDataValid, 302, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTsp3Support, 303, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkAuxInterval, 304, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpCreated, 305, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpUserRequest, 306, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpPlugged, 307, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpState, 308, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispHdcpFailCount, 309, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispHdcpHdcp22, 310, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(NvDispHdcpMaxRetry, 311, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpHpd, 312, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpRepeater, 313, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxBuf, 314, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecRxLength, 315, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxBuf, 316, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecTxLength, 317, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxRet, 318, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecState, 319, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispCecTxInfo, 320, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxInfo, 321, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDCIndex, 322, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCInitialize, 323, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCClock, 324, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCFrequency, 325, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCFailed, 326, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCModeWidth, 327, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeHeight, 328, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeBpp, 329, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCPanelFrequency, 330, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinDirty, 331, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinEnable, 332, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCVrr, 333, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCPanelInitialize, 334, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDsiDataFormat, 335, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiVideoMode, 336, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiRefreshRate, 337, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiLpCmdModeFrequency, 338, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiHsCmdModeFrequency, 339, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPanelResetTimeout, 340, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPhyFrequency, 341, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiFrequency, 342, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiInstance, 343, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHostCtrlEnable, 344, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiInit, 345, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnable, 346, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsMode, 347, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiVendorId, 348, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDcDsiLcdVendorNum, 349, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsClockControl, 350, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnableHsClockInLpMode, 351, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiTeFrameUpdate, 352, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiGangedType, 353, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHbpInPktSeq, 354, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispErrID, 355, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData0, 356, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData1, 357, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardMountStatus, 358, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardMountUnexpectedResult, 359, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSize, 360, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SdCardTotalSize, 361, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceInitialLaunch, 362, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSincePowerOn, 363, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceLastAwake, 364, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(OccurrenceTick, 365, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(RetailInteractiveDisplayFlag, 366, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatFsError, 367, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsExtraError, 368, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorDrive, 369, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorName, 370, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorManufactureCode, 371, MonitorCapability, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorProductCode, 372, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorSerialNumber, 373, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(MonitorManufactureYear, 374, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PhysicalAddress, 375, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(Is4k60Hz, 376, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is4k30Hz, 377, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is1080P60Hz, 378, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is720P60Hz, 379, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcmChannelMax, 380, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CrashReportHash, 381, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorReportSharePermission, 382, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(VideoCodecTypeEnum, 383, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoBitRate, 384, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoFrameRate, 385, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoWidth, 386, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoHeight, 387, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioCodecTypeEnum, 388, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioSampleRate, 389, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioChannelCount, 390, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioBitRate, 391, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaContainerType, 392, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaProfileType, 393, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaLevelType, 394, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaCacheSizeEnum, 395, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorStatusEnum, 396, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorLog, 397, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ServerFqdn, 398, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerIpAddress, 399, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestStringEncrypt, 400, Test, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(TestU8ArrayEncrypt, 401, Test, FieldType_U8Array, FieldFlag_Encrypt) \ + HANDLER(TestU32ArrayEncrypt, 402, Test, FieldType_U32Array, FieldFlag_Encrypt) \ + HANDLER(TestU64ArrayEncrypt, 403, Test, FieldType_U64Array, FieldFlag_Encrypt) \ + HANDLER(TestI32ArrayEncrypt, 404, Test, FieldType_I32Array, FieldFlag_Encrypt) \ + HANDLER(TestI64ArrayEncrypt, 405, Test, FieldType_I64Array, FieldFlag_Encrypt) \ + HANDLER(CipherKey, 406, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FileSystemPath, 407, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerOpenUrl, 408, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerLastSocketErrors, 409, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(UnknownControllerCount, 410, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AttachedControllerCount, 411, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothControllerCount, 412, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbControllerCount, 413, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ControllerTypeList, 414, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerInterfaceList, 415, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerStyleList, 416, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsPooledBufferPeakFreeSize, 417, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferRetriedCount, 418, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferReduceAllocationCount, 419, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakFreeSize, 420, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerRetriedCount, 421, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsExpHeapPeakFreeSize, 422, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferPoolPeakFreeSize, 423, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferSuccessCount, 424, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferFailureCount, 425, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SteadyClockInternalOffset, 426, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SteadyClockCurrentTimePointValue, 427, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextOffset, 428, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextTimeStampValue, 429, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextOffset, 430, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextTimeStampValue, 431, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemAbortFlag, 432, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationAbortFlag, 433, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NifmErrorCode, 434, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsApplicationId, 435, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyIdList, 436, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyVersionList, 437, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyTypeList, 438, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyInstallTypeList, 439, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsSenderFlag, 440, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsApplicationRequestFlag, 441, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsHasExFatDriverFlag, 442, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsIpAddress, 443, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccount, 444, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAocRegistrationType, 445, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAttributeFlag, 446, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpSupportedLanguageFlag, 447, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpParentalControlFlag, 448, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpScreenShot, 449, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpVideoCapture, 450, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpDataLossConfirmation, 451, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPlayLogPolicy, 452, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPresenceGroupId, 453, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpRatingAge, 454, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ + HANDLER(AcpAocBaseId, 455, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSize, 456, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSize, 457, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSize, 458, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSize, 459, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpBcatDeliveryCacheStorageSize, 460, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpApplicationErrorCodeCategory, 461, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpLocalCommunicationId, 462, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpLogoType, 463, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpLogoHandling, 464, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRuntimeAocInstall, 465, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpCrashReport, 466, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpHdcp, 467, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpSeedForPseudoDeviceId, 468, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSizeMax, 469, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSizeMax, 470, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSizeMax, 471, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSizeMax, 472, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpTemporaryStorageSize, 473, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageSize, 474, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageJournalSize, 475, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageDataAndJournalSizeMax, 476, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageIndexMax, 477, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryableApplicationId, 478, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryCapability, 479, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRepairFlag, 480, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningApplicationPatchStorageLocation, 481, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersionNumber, 482, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRecoveredByInvalidateCacheCount, 483, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSaveDataIndexCount, 484, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakTotalAllocatableSize, 485, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(MonitorCurrentWidth, 486, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentHeight, 487, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentRefreshRate, 488, MonitorSettings, FieldType_String, FieldFlag_None ) \ + HANDLER(RebootlessSystemUpdateVersion, 489, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptedDyingMessage, 490, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(DramId, 491, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NifmConnectionTestRedirectUrl, 492, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 493, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0Flags, 494, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Speed, 495, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0ResetTimeInUs, 496, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0IrqCount, 497, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Statistics, 498, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePort1Flags, 499, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Speed, 500, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort1ResetTimeInUs, 501, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1IrqCount, 502, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Statistics, 503, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PcieFunction0VendorId, 504, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0DeviceId, 505, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0PmState, 506, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction0IsAcquired, 507, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieFunction1VendorId, 508, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1DeviceId, 509, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1PmState, 510, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction1IsAcquired, 511, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieGlobalRootComplexStatistics, 512, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePllResistorCalibrationValue, 513, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CertificateRequestedHostName, 514, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateCommonName, 515, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateSANCount, 516, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CertificateSANs, 517, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsBufferPoolMaxAllocateSize, 518, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateIssuerName, 519, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationAliveTime, 520, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSwitchLock, 521, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(USB3HostAvailableFlag, 522, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(USB3DeviceAvailableFlag, 523, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccountOptionFlag, 524, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServerErrorCode, 525, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletManagerMetaLogTrace, 526, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ServerCertificateSerialNumber, 527, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificatePublicKeyAlgorithm, 528, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateSignatureAlgorithm, 529, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateNotBefore, 530, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ServerCertificateNotAfter, 531, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateAlgorithmInfoBits, 532, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TlsConnectionPeerIpAddress, 533, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TlsConnectionLastHandshakeState, 534, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TlsConnectionInfoBits, 535, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslStateBits, 536, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessInfoBits, 537, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessHeapSize, 538, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SslBaseErrorCode, 539, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDumpSize, 540, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuCrashDump, 541, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(RunningApplicationProgramIndex, 542, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbTopology, 543, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(AkamaiReferenceId, 544, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NvHostErrID, 545, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvHostErrDataArrayU32, 546, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(HasSyslogFlag, 547, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpRuntimeParameterDelivery, 548, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PlatformRegion, 549, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSizeOfSystem, 550, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(NANDFreeSpaceOfSystem, 551, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AccessPointSSIDAsHex, 552, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(PanelVendorId, 553, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelRevisionId, 554, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelModelId, 555, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ErrorContext, 556, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorContextSize, 557, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ErrorContextTotalSize, 558, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryLimit, 559, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountLimit, 560, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountLimit, 561, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountLimit, 562, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountLimit, 563, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryPeak, 564, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountPeak, 565, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountPeak, 566, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountPeak, 567, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountPeak, 568, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GpuCrashHash, 569, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TouchScreenPanelGpioValue, 570, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BrowserCertificateHostName, 571, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateCommonName, 572, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateOrganizationalUnitName, 573, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 574, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AudioOutputTarget, 575, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AudioOutputChannelCount, 576, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AppletTotalActiveTime, 577, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(WakeCount, 578, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PredominantWakeReason, 579, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock2, 580, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock3, 581, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LumenRequestId, 582, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LlnwLlid, 583, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SupportingLimitedApplicationLicenses, 584, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 585, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServiceProfileRevisionKey, 586, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(BluetoothAudioConnectionCount, 587, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCount, 588, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCount, 589, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCount, 590, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFilePeakOpenCount, 591, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 592, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserFilePeakOpenCount, 593, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserDirectoryPeakOpenCount, 594, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardFilePeakOpenCount, 595, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardDirectoryPeakOpenCount, 596, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(SslAlertInfo, 597, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(SslVersionInfo, 598, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 599, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 600, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 601, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 602, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 603, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 604, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ServerErrorIsRetryable, 605, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FsDeepRetryStartCount, 606, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 607, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(BuiltInWirelessOUI, 608, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPOUI, 609, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EthernetAdapterOUI, 610, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatSafeControlResult, 611, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatErrorNumber, 612, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatSafeErrorNumber, 613, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatSafeControlResult, 614, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatErrorNumber, 615, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatSafeErrorNumber, 616, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDump2, 617, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDType, 618, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDType, 619, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardLastDeactivateReasonResult, 620, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastDeactivateReason, 621, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp new file mode 100644 index 000000000..30821a41a --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp @@ -0,0 +1,693 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +/* NOTE: This file is auto-generated. */ +/* Do not make edits to this file by hand. */ + +#define AMS_ERPT_FOREACH_DEPRECATED_FIELD(HANDLER) \ + HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ + HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ + HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ + HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ + HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ + HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ + HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ + HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ + HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ + HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ + diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index 3582448e1..798d08fad 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace ams::erpt { @@ -48,6 +49,17 @@ namespace ams::erpt { #undef GENERATE_ENUM + #define GENERATE_ENUM(NAME, ID, ...) DeprecatedFieldId_##NAME = ID, + + enum DeprecatedFieldId { + AMS_ERPT_FOREACH_DEPRECATED_FIELD(GENERATE_ENUM) + DeprecatedFieldId_Count, + }; + + #undef GENERATE_ENUM + + #define ERPT_FIELD_ID(NAME) (::ams::hos::GetVersion() >= ::ams::hos::Version_17_0_0 ? ::ams::erpt::FieldId_##NAME : static_cast<::ams::erpt::FieldId>(::ams::util::ToUnderlying(::ams::erpt::DeprecatedFieldId_##NAME))) + constexpr inline u32 ArrayBufferSizeDefault = 0x100; constexpr inline u32 ArrayBufferSizeMax = 96_KB; constexpr inline u32 ArrayFieldSizeMax = 16_KB - 1; @@ -111,6 +123,14 @@ namespace ams::erpt { static_assert(util::is_pod::value); static_assert(sizeof(ReportFlagSet) == sizeof(u32)); + struct CreateReportOptionFlag { + using SubmitFsInfo = util::BitFlagSet::Flag<0>; + }; + + using CreateReportOptionFlagSet = util::BitFlagSet; + static_assert(util::is_pod::value); + static_assert(sizeof(CreateReportOptionFlagSet) == sizeof(u32)); + struct ReportInfo { ReportType type; ReportId id; diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp index f2917690f..94e876525 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp @@ -20,24 +20,26 @@ #include #include -#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0) \ - AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ - AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) +#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_11_0_0) \ + AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp index 2b1ec9830..a1d6eeea0 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp @@ -49,6 +49,10 @@ namespace ams::erpt::srv { AMS_ERPT_FOREACH_FIELD(STRINGIZE_HANDLER) }; + constexpr inline const char * const DeprecatedFieldString[] = { + AMS_ERPT_FOREACH_DEPRECATED_FIELD(STRINGIZE_HANDLER) + }; + constexpr inline const char * const CategoryString[] = { AMS_ERPT_FOREACH_CATEGORY(STRINGIZE_HANDLER) }; @@ -76,10 +80,59 @@ namespace ams::erpt::srv { }; #undef GET_FIELD_FLAG + #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [DeprecatedFieldId_##FIELD] = CategoryId_##CATEGORY, + constexpr inline const CategoryId DeprecatedFieldToCategoryMap[] = { + AMS_ERPT_FOREACH_DEPRECATED_FIELD(GET_FIELD_CATEGORY) + }; + #undef GET_FIELD_CATEGORY + + #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [DeprecatedFieldId_##FIELD] = TYPE, + constexpr inline const FieldType DeprecatedFieldToTypeMap[] = { + AMS_ERPT_FOREACH_DEPRECATED_FIELD(GET_FIELD_TYPE) + }; + #undef GET_FIELD_TYPE + + #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [DeprecatedFieldId_##FIELD] = FLAG, + constexpr inline const FieldFlag DeprecatedFieldToFlagMap[] = { + AMS_ERPT_FOREACH_DEPRECATED_FIELD(GET_FIELD_FLAG) + }; + #undef GET_FIELD_FLAG + + inline CategoryId ConvertFieldToCategory(FieldId id) { + if (hos::GetVersion() >= hos::Version_17_0_0) { + return FieldToCategoryMap[id]; + } else { + AMS_ABORT_UNLESS(util::ToUnderlying(id) < util::ToUnderlying(DeprecatedFieldId_Count)); + return DeprecatedFieldToCategoryMap[id]; + } + } + + inline FieldType ConvertFieldToType(FieldId id) { + if (hos::GetVersion() >= hos::Version_17_0_0) { + return FieldToTypeMap[id]; + } else { + AMS_ABORT_UNLESS(util::ToUnderlying(id) < util::ToUnderlying(DeprecatedFieldId_Count)); + return DeprecatedFieldToTypeMap[id]; + } + } + + inline FieldFlag ConvertFieldToFlag(FieldId id) { + if (hos::GetVersion() >= hos::Version_17_0_0) { + return FieldToFlagMap[id]; + } else { + AMS_ABORT_UNLESS(util::ToUnderlying(id) < util::ToUnderlying(DeprecatedFieldId_Count)); + return DeprecatedFieldToFlagMap[id]; + } + } + constexpr inline ReportFlagSet MakeNoReportFlags() { return util::MakeBitFlagSet<32, ReportFlag>(); } + constexpr inline CreateReportOptionFlagSet MakeNoCreateReportOptionFlags() { + return util::MakeBitFlagSet<32, CreateReportOptionFlag>(); + } + constexpr inline AttachmentFlagSet MakeNoAttachmentFlags() { return util::MakeBitFlagSet<32, AttachmentFlag>(); } diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp index fef147445..488b49639 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp @@ -24,7 +24,7 @@ #define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_0_3) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \ AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp index 45cae0b4a..807132bb0 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp @@ -48,7 +48,7 @@ namespace ams::erpt::srv { ON_SCOPE_EXIT { Deallocate(hdr); }; hdr->magic = HeaderMagic; - hdr->field_type = static_cast(FieldToTypeMap[field_id]); + hdr->field_type = static_cast(ConvertFieldToType(field_id)); hdr->element_count = arr_size; hdr->reserved = 0; @@ -81,7 +81,7 @@ namespace ams::erpt::srv { oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt)); } - Formatter::AddField(report, FieldId_CipherKey, cipher, sizeof(cipher)); + Formatter::AddField(report, ERPT_FIELD_ID(CipherKey), cipher, sizeof(cipher)); std::memset(s_key, 0, sizeof(s_key)); R_RETURN(Formatter::End(report)); @@ -97,7 +97,7 @@ namespace ams::erpt::srv { } static Result AddField(Report *report, FieldId field_id, char *str, u32 len) { - if (FieldToFlagMap[field_id] == FieldFlag_Encrypt) { + if (ConvertFieldToFlag(field_id) == FieldFlag_Encrypt) { R_RETURN(EncryptArray(report, field_id, str, len)); } else { R_RETURN(Formatter::AddField(report, field_id, str, len)); @@ -105,7 +105,7 @@ namespace ams::erpt::srv { } static Result AddField(Report *report, FieldId field_id, u8 *bin, u32 len) { - if (FieldToFlagMap[field_id] == FieldFlag_Encrypt) { + if (ConvertFieldToFlag(field_id) == FieldFlag_Encrypt) { R_RETURN(EncryptArray(report, field_id, bin, len)); } else { R_RETURN(Formatter::AddField(report, field_id, bin, len)); @@ -114,7 +114,7 @@ namespace ams::erpt::srv { template static Result AddField(Report *report, FieldId field_id, T *arr, u32 len) { - if (FieldToFlagMap[field_id] == FieldFlag_Encrypt) { + if (ConvertFieldToFlag(field_id) == FieldFlag_Encrypt) { R_RETURN(EncryptArray(report, field_id, arr, len)); } else { R_RETURN(Formatter::AddField(report, field_id, arr, len)); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp index 4bc533d22..695b12229 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp @@ -38,7 +38,7 @@ namespace ams::erpt::srv { R_RETURN(Context::SubmitContext(ctx, data, data_size)); } - Result ContextImpl::CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result) { + Result ContextImpl::CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); const ReportMetaData *meta = reinterpret_cast(meta_buffer.GetPointer()); @@ -50,15 +50,19 @@ namespace ams::erpt::srv { R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument()); - R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags)); ManagerImpl::NotifyAll(); R_SUCCEED(); } + Result ContextImpl::CreateReportV1(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result) { + R_RETURN(this->CreateReport(report_type, ctx_buffer, data_buffer, meta_buffer, result, erpt::srv::MakeNoCreateReportOptionFlags())); + } + Result ContextImpl::CreateReportV0(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer) { - R_RETURN(this->CreateReport(report_type, ctx_buffer, data_buffer, meta_buffer, ResultSuccess())); + R_RETURN(this->CreateReportV1(report_type, ctx_buffer, data_buffer, meta_buffer, ResultSuccess())); } Result ContextImpl::SetInitialLaunchSettingsCompletionTime(const time::SteadyClockTimePoint &time_point) { @@ -138,7 +142,7 @@ namespace ams::erpt::srv { R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size)); } - Result ContextImpl::CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result) { + Result ContextImpl::CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); const u32 ctx_size = static_cast(ctx_buffer.GetSize()); @@ -150,15 +154,19 @@ namespace ams::erpt::srv { R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument()); - R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags)); ManagerImpl::NotifyAll(); R_SUCCEED(); } + Result ContextImpl::CreateReportWithAttachmentsDeprecated2(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result) { + R_RETURN(this->CreateReportWithAttachments(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, result, erpt::srv::MakeNoCreateReportOptionFlags())); + } + Result ContextImpl::CreateReportWithAttachmentsDeprecated(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer) { - R_RETURN(this->CreateReportWithAttachments(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess())); + R_RETURN(this->CreateReportWithAttachmentsDeprecated2(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess())); } Result ContextImpl::RegisterRunningApplet(ncm::ProgramId program_id) { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp index 4fa816f3c..d6c98c94b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp @@ -31,8 +31,10 @@ namespace ams::erpt::srv { Result ClearApplicationLaunchTime(); Result SubmitAttachment(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); Result CreateReportWithAttachmentsDeprecated(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer); - Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result); - Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result); + Result CreateReportWithAttachmentsDeprecated2(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result); + Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags); + Result CreateReportV1(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result); + Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags); Result RegisterRunningApplet(ncm::ProgramId program_id); Result UnregisterRunningApplet(ncm::ProgramId program_id); Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp index 0acc1cabf..b366c1550 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp @@ -75,11 +75,11 @@ namespace ams::erpt::srv { for (u32 i = 0; i < m_ctx.field_count; i++) { m_ctx.fields[i] = ctx_ptr->fields[i]; - R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < FieldId_Count, erpt::ResultInvalidArgument()); - R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); + R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < ERPT_FIELD_ID(Count), erpt::ResultInvalidArgument()); + R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); - R_UNLESS(m_ctx.fields[i].type == FieldToTypeMap[m_ctx.fields[i].id], erpt::ResultFieldTypeMismatch()); - R_UNLESS(m_ctx.category == FieldToCategoryMap[m_ctx.fields[i].id], erpt::ResultFieldCategoryMismatch()); + R_UNLESS(m_ctx.fields[i].type == ConvertFieldToType(m_ctx.fields[i].id), erpt::ResultFieldTypeMismatch()); + R_UNLESS(m_ctx.category == ConvertFieldToCategory(m_ctx.fields[i].id), erpt::ResultFieldCategoryMismatch()); if (IsArrayFieldType(m_ctx.fields[i].type)) { const u32 start_idx = m_ctx.fields[i].value_array.start_idx; diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp index a6a622f71..89189d99b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp @@ -83,10 +83,10 @@ namespace ams::erpt::srv { err::GetErrorCodeString(error_code_str, sizeof(error_code_str), err::ConvertResultToErrorCode(err::ResultForcedShutdownDetected())); /* Add error code to the context. */ - R_TRY(record->Add(FieldId_ErrorCode, error_code_str, std::strlen(error_code_str))); + R_TRY(record->Add(ERPT_FIELD_ID(ErrorCode), error_code_str, std::strlen(error_code_str))); /* Create report. */ - R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0)); + R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags())); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp index b50712be3..013bb45a4 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp @@ -62,7 +62,11 @@ namespace ams::erpt::srv { static Result AddId(Report *report, FieldId field_id) { static_assert(MaxFieldStringSize < ElementSize_256); - R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); + if (hos::GetVersion() >= hos::Version_17_0_0) { + R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); + } else { + R_TRY(AddStringValue(report, DeprecatedFieldString[field_id], strnlen(DeprecatedFieldString[field_id], MaxFieldStringSize))); + } R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp index 6f23bde32..1f3ef25db 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp @@ -135,7 +135,7 @@ namespace ams::erpt::srv { auto record = std::make_unique(CategoryId_ProductModelInfo); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - R_TRY(record->Add(FieldId_ProductModel, model, model_len)); + R_TRY(record->Add(ERPT_FIELD_ID(ProductModel), model, model_len)); R_TRY(Context::SubmitContextRecord(std::move(record))); R_SUCCEED(); @@ -146,7 +146,7 @@ namespace ams::erpt::srv { auto record = std::make_unique(CategoryId_RegionSettingInfo); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - R_TRY(record->Add(FieldId_RegionSetting, region, region_len)); + R_TRY(record->Add(ERPT_FIELD_ID(RegionSetting), region, region_len)); R_TRY(Context::SubmitContextRecord(std::move(record))); R_SUCCEED(); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index 2efa84820..33752621e 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -123,14 +123,14 @@ namespace ams::erpt::srv { if (error_context_total_size == 0) { return; } - record->Add(FieldId_ErrorContextTotalSize, error_context_total_size); + record->Add(ERPT_FIELD_ID(ErrorContextTotalSize), error_context_total_size); /* Set the context. */ if (error_context_size == 0) { return; } - record->Add(FieldId_ErrorContextSize, error_context_size); - record->Add(FieldId_ErrorContext, error_context, error_context_size); + record->Add(ERPT_FIELD_ID(ErrorContextSize), error_context_size); + record->Add(ERPT_FIELD_ID(ErrorContext), error_context, error_context_size); } constinit os::SdkMutex g_limit_mutex; @@ -164,7 +164,7 @@ namespace ams::erpt::srv { if (R_FAILED(svc::GetResourceLimitLimitValue(std::addressof(limit_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ return; \ } \ - if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \ + if (R_FAILED(record->Add(ERPT_FIELD_ID(System##__RESOURCE__##Limit), limit_value))) { \ return; \ } \ } while (0) @@ -203,7 +203,7 @@ namespace ams::erpt::srv { if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ return; \ } \ - if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \ + if (R_FAILED(record->Add(ERPT_FIELD_ID(System##__RESOURCE__##Peak), peak_value))) { \ return; \ } \ } while (0) @@ -234,7 +234,7 @@ namespace ams::erpt::srv { R_UNLESS(ctx->field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); const bool found_error_code = util::range::any_of(MakeSpan(ctx->fields, ctx->field_count), [] (const FieldEntry &entry) { - return entry.id == FieldId_ErrorCode; + return entry.id == ERPT_FIELD_ID(ErrorCode); }); R_UNLESS(found_error_code, erpt::ResultRequiredFieldMissing()); @@ -249,10 +249,10 @@ namespace ams::erpt::srv { bool found_abort_flag = false, found_syslog_flag = false; for (u32 i = 0; i < ctx->field_count; i++) { - if (ctx->fields[i].id == FieldId_AbortFlag) { + if (ctx->fields[i].id == ERPT_FIELD_ID(AbortFlag)) { found_abort_flag = true; } - if (ctx->fields[i].id == FieldId_HasSyslogFlag) { + if (ctx->fields[i].id == ERPT_FIELD_ID(HasSyslogFlag)) { found_syslog_flag = true; } if (found_abort_flag && found_syslog_flag) { @@ -261,11 +261,11 @@ namespace ams::erpt::srv { } if (!found_abort_flag) { - record->Add(FieldId_AbortFlag, false); + record->Add(ERPT_FIELD_ID(AbortFlag), false); } if (!found_syslog_flag) { - record->Add(FieldId_HasSyslogFlag, true); + record->Add(ERPT_FIELD_ID(HasSyslogFlag), true); } R_TRY(Context::SubmitContextRecord(std::move(record))); @@ -277,7 +277,7 @@ namespace ams::erpt::srv { bool needs_save_syslog = true; for (u32 i = 0; i < ctx->field_count; i++) { static_assert(FieldToTypeMap[FieldId_HasSyslogFlag] == FieldType_Bool); - if (ctx->fields[i].id == FieldId_HasSyslogFlag && !ctx->fields[i].value_bool) { + if (ctx->fields[i].id == ERPT_FIELD_ID(HasSyslogFlag) && !ctx->fields[i].value_bool) { needs_save_syslog = false; break; } @@ -299,13 +299,13 @@ namespace ams::erpt::srv { /* Find the program id entry. */ const auto fields_span = MakeSpan(error_info_ctx->fields, error_info_ctx->field_count); - const auto program_id_entry = util::range::find_if(fields_span, [](const FieldEntry &entry) { return entry.id == FieldId_ProgramId; }); + const auto program_id_entry = util::range::find_if(fields_span, [](const FieldEntry &entry) { return entry.id == ERPT_FIELD_ID(ProgramId); }); if (program_id_entry == fields_span.end()) { return; } /* Check that the report has abort flag set. */ - AMS_ASSERT(util::range::any_of(fields_span, [](const FieldEntry &entry) { return entry.id == FieldId_AbortFlag && entry.value_bool; })); + AMS_ASSERT(util::range::any_of(fields_span, [](const FieldEntry &entry) { return entry.id == ERPT_FIELD_ID(AbortFlag) && entry.value_bool; })); /* Check that the program id's value is a string. */ AMS_ASSERT(program_id_entry->type == FieldType_String); @@ -334,7 +334,7 @@ namespace ams::erpt::srv { } /* Add the active applet time. */ - const auto result = error_info_auto_record->Add(FieldId_AppletTotalActiveTime, (*active_duration).GetSeconds()); + const auto result = error_info_auto_record->Add(ERPT_FIELD_ID(AppletTotalActiveTime), (*active_duration).GetSeconds()); R_ASSERT(result); } @@ -413,7 +413,7 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) { /* Create a context record for the report. */ auto record = std::make_unique(); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); @@ -422,10 +422,10 @@ namespace ams::erpt::srv { R_TRY(record->Initialize(ctx, data, data_size)); /* Create the report. */ - R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments)); + R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags)); } - Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) { /* Clear the automatic categories, when we're done with our report. */ ON_SCOPE_EXIT { Context::ClearContext(CategoryId_ErrorInfo); @@ -457,7 +457,7 @@ namespace ams::erpt::srv { SaveSyslogReportIfRequired(ctx, report_id); /* Submit report contexts. */ - R_TRY(SubmitReportContexts(report_id, type, ctx_result, std::move(record), timestamp_user, timestamp_network)); + R_TRY(SubmitReportContexts(report_id, type, ctx_result, std::move(record), timestamp_user, timestamp_network, flags)); /* Link attachments to the report. */ R_TRY(LinkAttachments(report_id, attachments, num_attachments)); @@ -468,7 +468,7 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result Reporter::SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime ×tamp_user, const time::PosixTime ×tamp_network) { + Result Reporter::SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime ×tamp_user, const time::PosixTime ×tamp_network, erpt::CreateReportOptionFlagSet flags) { /* Create automatic record. */ auto auto_record = std::make_unique(CategoryId_ErrorInfoAuto, 0x300); R_UNLESS(auto_record != nullptr, erpt::ResultOutOfMemory()); @@ -489,28 +489,28 @@ namespace ams::erpt::srv { R_ABORT_UNLESS(time::GetStandardSteadyClockCurrentTimePoint(std::addressof(steady_clock_current_timepoint))); /* Add automatic fields. */ - auto_record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))); - auto_record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))); - auto_record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))); - auto_record->Add(FieldId_ReportIdentifier, identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))); - auto_record->Add(FieldId_OccurrenceTimestamp, timestamp_user.value); - auto_record->Add(FieldId_OccurrenceTimestampNet, timestamp_network.value); - auto_record->Add(FieldId_ReportVisibilityFlag, type == ReportType_Visible); - auto_record->Add(FieldId_OccurrenceTick, occurrence_tick.GetInt64Value()); - auto_record->Add(FieldId_SteadyClockInternalOffset, steady_clock_internal_offset_seconds); - auto_record->Add(FieldId_SteadyClockCurrentTimePointValue, steady_clock_current_timepoint.value); - auto_record->Add(FieldId_ElapsedTimeSincePowerOn, (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()); - auto_record->Add(FieldId_ElapsedTimeSinceLastAwake, (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()); + auto_record->Add(ERPT_FIELD_ID(OsVersion), s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))); + auto_record->Add(ERPT_FIELD_ID(PrivateOsVersion), s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))); + auto_record->Add(ERPT_FIELD_ID(SerialNumber), s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))); + auto_record->Add(ERPT_FIELD_ID(ReportIdentifier), identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))); + auto_record->Add(ERPT_FIELD_ID(OccurrenceTimestamp), timestamp_user.value); + auto_record->Add(ERPT_FIELD_ID(OccurrenceTimestampNet), timestamp_network.value); + auto_record->Add(ERPT_FIELD_ID(ReportVisibilityFlag), type == ReportType_Visible); + auto_record->Add(ERPT_FIELD_ID(OccurrenceTick), occurrence_tick.GetInt64Value()); + auto_record->Add(ERPT_FIELD_ID(SteadyClockInternalOffset), steady_clock_internal_offset_seconds); + auto_record->Add(ERPT_FIELD_ID(SteadyClockCurrentTimePointValue), steady_clock_current_timepoint.value); + auto_record->Add(ERPT_FIELD_ID(ElapsedTimeSincePowerOn), (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()); + auto_record->Add(ERPT_FIELD_ID(ElapsedTimeSinceLastAwake), (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()); if (s_initial_launch_settings_completion_time) { s64 elapsed_seconds; if (R_SUCCEEDED(time::GetElapsedSecondsBetween(std::addressof(elapsed_seconds), *s_initial_launch_settings_completion_time, steady_clock_current_timepoint))) { - auto_record->Add(FieldId_ElapsedTimeSinceInitialLaunch, elapsed_seconds); + auto_record->Add(ERPT_FIELD_ID(ElapsedTimeSinceInitialLaunch), elapsed_seconds); } } if (s_application_launch_time) { - auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()); + auto_record->Add(ERPT_FIELD_ID(ApplicationAliveTime), (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()); } /* Submit applet active duration information. */ @@ -530,6 +530,10 @@ namespace ams::erpt::srv { SubmitResourceLimitContexts(); #endif + if (flags.Test()) { + /* TODO: 17.0.0 SubmitFsInfo() */ + } + R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp index ca6fd256e..11913dbd5 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp @@ -56,10 +56,10 @@ namespace ams::erpt::srv { static void SetRedirectNewReportsToSdCard(bool en) { s_redirect_new_reports = en; } private: - static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime &user_timestamp, const time::PosixTime &network_timestamp); + static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime &user_timestamp, const time::PosixTime &network_timestamp, erpt::CreateReportOptionFlagSet flags); public: - static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments); - static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments); + static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags); + static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags); }; } From e96e1063e24a60544542ac61109b10d9d05d0642 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 13:32:46 -0700 Subject: [PATCH 036/238] jpegdec: stop bundling (TODO post-prerelease) --- atmosphere.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atmosphere.mk b/atmosphere.mk index 706b5f320..cca6fc106 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -84,7 +84,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037 - mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c + #mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240 @@ -98,7 +98,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) cp stratosphere/fatal/$(ATMOSPHERE_OUT_DIR)/fatal.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp cp stratosphere/creport/$(ATMOSPHERE_OUT_DIR)/creport.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp cp stratosphere/ro/$(ATMOSPHERE_OUT_DIR)/ro.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp - cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp + #cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp cp stratosphere/pgl/$(ATMOSPHERE_OUT_DIR)/pgl.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp cp stratosphere/LogManager/$(ATMOSPHERE_OUT_DIR)/LogManager.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420/exefs.nsp cp stratosphere/htc/$(ATMOSPHERE_OUT_DIR)/htc.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240/exefs.nsp From f5b2eab4a81cc88f2562ce1689d382167211d6dc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 13:36:40 -0700 Subject: [PATCH 037/238] exo: fix up new titlekey option extents --- exosphere/program/source/smc/secmon_smc_rsa.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exosphere/program/source/smc/secmon_smc_rsa.cpp b/exosphere/program/source/smc/secmon_smc_rsa.cpp index b321d27a1..920a65bea 100644 --- a/exosphere/program/source/smc/secmon_smc_rsa.cpp +++ b/exosphere/program/source/smc/secmon_smc_rsa.cpp @@ -33,7 +33,7 @@ namespace ams::secmon::smc { struct PrepareEsDeviceUniqueKeyOption { using KeyGeneration = util::BitPack32::Field<0, 6, int>; using Type = util::BitPack32::Field<6, 2, EsCommonKeyType>; - using Reserved = util::BitPack32::Field<8, 25, u32>; + using Reserved = util::BitPack32::Field<8, 24, u32>; }; constexpr const u8 ModularExponentiateByStorageKeyTable[] = { From 59a24fa646864b78a16fb7673f6e09fda415a3c4 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 14:01:00 -0700 Subject: [PATCH 038/238] fusee: support parsing 17.0.0+ INI --- fusee/program/source/fusee_stratosphere.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index 4ccc0ed41..e9ad72e80 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -257,7 +257,18 @@ namespace ams::nxboot { }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { - if (target_firmware >= ams::TargetFirmware_8_0_0) { + if (target_firmware >= ams::TargetFirmware_17_0_0) { + const u32 *data_32 = reinterpret_cast(data); + const u32 branch_target = (data_32[0] & 0x00FFFFFF); + for (size_t i = branch_target; i < branch_target + 0x1000 / sizeof(u32); ++i) { + const u32 ini_offset = (i * sizeof(u32)) + data_32[i]; + if (data_32[i + 1] == 0 && ini_offset <= header->meta.payload_sizes[0] && std::memcmp(data + ini_offset, "INI1", 4) == 0) { + return reinterpret_cast(data + ini_offset); + } + } + + return nullptr; + } else if (target_firmware >= ams::TargetFirmware_8_0_0) { /* Try to find initial process binary. */ const u32 *data_32 = reinterpret_cast(data); for (size_t i = 0; i < 0x1000 / sizeof(u32); ++i) { From 05259b751952e3aff433d37ff26b0eeef2dd8cdc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 16:59:46 -0700 Subject: [PATCH 039/238] emummc: fix offsets for 17.0.0 --- emummc/source/FS/offsets/1700.h | 6 +++--- emummc/source/FS/offsets/1700_exfat.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/emummc/source/FS/offsets/1700.h b/emummc/source/FS/offsets/1700.h index 0c91f3d58..7a9cf825e 100644 --- a/emummc/source/FS/offsets/1700.h +++ b/emummc/source/FS/offsets/1700.h @@ -18,9 +18,9 @@ #define __FS_1700_H__ // Accessor vtable getters -#define FS_OFFSET_1700_SDMMC_ACCESSOR_GC 0x18ACF0 -#define FS_OFFSET_1700_SDMMC_ACCESSOR_SD 0x18C9C0 -#define FS_OFFSET_1700_SDMMC_ACCESSOR_NAND 0x18B1C0 +#define FS_OFFSET_1700_SDMMC_ACCESSOR_GC 0x18AD00 +#define FS_OFFSET_1700_SDMMC_ACCESSOR_SD 0x18C9D0 +#define FS_OFFSET_1700_SDMMC_ACCESSOR_NAND 0x18B1D0 // Hooks #define FS_OFFSET_1700_SDMMC_WRAPPER_READ 0x186BC0 diff --git a/emummc/source/FS/offsets/1700_exfat.h b/emummc/source/FS/offsets/1700_exfat.h index 449e2ead7..e479724e0 100644 --- a/emummc/source/FS/offsets/1700_exfat.h +++ b/emummc/source/FS/offsets/1700_exfat.h @@ -18,9 +18,9 @@ #define __FS_1700_EXFAT_H__ // Accessor vtable getters -#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_GC 0x195B50 -#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_SD 0x197820 -#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_NAND 0x196020 +#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_GC 0x195B60 +#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_SD 0x197830 +#define FS_OFFSET_1700_EXFAT_SDMMC_ACCESSOR_NAND 0x196030 // Hooks #define FS_OFFSET_1700_EXFAT_SDMMC_WRAPPER_READ 0x191A20 From 71d0274884d4ebdedc4c891fce5d28922a340198 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 17:48:40 -0700 Subject: [PATCH 040/238] erpt: remove deprecated fields, they didn't actually change IDs, just the mapping between id and name table index --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 1303 +++++++++-------- .../erpt/erpt_ids_deprecated.autogen.hpp | 693 --------- .../include/stratosphere/erpt/erpt_types.hpp | 12 - .../stratosphere/erpt/srv/erpt_srv_types.hpp | 43 +- .../source/erpt/srv/erpt_srv_cipher.hpp | 2 +- .../erpt/srv/erpt_srv_context_record.cpp | 4 +- .../erpt/srv/erpt_srv_forced_shutdown.cpp | 2 +- .../source/erpt/srv/erpt_srv_formatter.hpp | 6 +- .../source/erpt/srv/erpt_srv_main.cpp | 4 +- .../source/erpt/srv/erpt_srv_reporter.cpp | 56 +- 10 files changed, 719 insertions(+), 1406 deletions(-) delete mode 100644 libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index f81272ccd..57630304d 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -182,626 +182,685 @@ HANDLER(MicroSDTypeInfo, 141) \ #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ - HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ - HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ - HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(IPAddressAcquisitionMethod, 18, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SubnetMask, 19, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GatewayIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DNSType, 21, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PriorityDNSIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AlternateDNSIPAddress, 23, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseProxyFlag, 24, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProxyIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProxyPort, 26, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProxyAutoAuthenticateFlag, 27, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(MTU, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ConnectAutomaticallyFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(UseStealthNetworkFlag, 30, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LimitHighCapacityFlag, 31, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NATType, 32, NATTypeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EnableWirelessInterfaceFlag, 33, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableWifiFlag, 34, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableBluetoothFlag, 35, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableNFCFlag, 36, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NintendoZoneSSIDListVersion, 37, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationID, 38, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationTitle, 39, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationVersion, 40, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationStorageLocation, 41, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProductModel, 42, ProductModelInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentLanguage, 43, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseNetworkTimeProtocolFlag, 44, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TimeZone, 45, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(VideoOutputSetting, 46, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDFreeSpace, 47, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SDCardFreeSpace, 48, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SerialNumber, 49, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(OsVersion, 50, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ScreenBrightnessAutoAdjustFlag, 51, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HdmiAudioOutputMode, 52, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SpeakerAudioOutputMode, 53, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MuteOnHeadsetUnpluggedFlag, 54, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerVibrationVolume, 55, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LockScreenFlag, 56, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(InternalBatteryLotNumber, 57, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NotifyInGameDownloadCompletionFlag, 58, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NotificationSoundFlag, 59, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVResolutionSetting, 60, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RGBRangeSetting, 61, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ReduceScreenBurnFlag, 62, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVAllowsCecFlag, 63, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HandheldModeTimeToScreenSleep, 64, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleModeTimeToScreenSleep, 65, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(StopAutoSleepDuringContentPlayFlag, 66, SleepInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LastConnectionTestDownloadSpeed, 67, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(LastConnectionTestUploadSpeed, 68, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardCID, 69, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDCID, 70, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDCID, 71, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDSpeedMode, 72, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MicroSDSpeedMode, 73, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(USB3AvailableFlag, 74, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(RegionSetting, 75, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoZoneConnectedFlag, 76, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ScreenBrightnessLevel, 77, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProgramId, 78, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbortFlag, 79, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ReportVisibilityFlag, 80, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatalFlag, 81, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OccurrenceTimestampNet, 82, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ResultBacktrace, 83, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch64, 84, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(StackBacktrace64, 85, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(RegisterSetFlag64, 86, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr64, 87, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AbortType, 88, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PrivateOsVersion, 89, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentSystemPowerState, 90, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PreviousSystemPowerState, 91, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DestinationSystemPowerState, 92, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionCurrentState, 93, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionPreviousState, 94, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscInitializedList, 95, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PscCurrentPmStateList, 96, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PscNextPmStateList, 97, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PerformanceMode, 98, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PerformanceConfiguration, 99, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(Throttled, 100, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ThrottlingDuration, 101, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ThrottlingTimestamp, 102, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GameCardCrcErrorCount, 103, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicCrcErrorCount, 104, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRefreshCount, 105, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadRetryCount, 106, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidBlock, 107, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock, 108, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(CreateProcessFailureFlag, 109, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TemperaturePcb, 110, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TemperatureSoc, 111, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CurrentFanDuty, 112, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(LastDvfsThresholdTripped, 113, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CradlePdcHFwVersion, 114, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradlePdcAFwVersion, 115, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleMcuFwVersion, 116, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleDp2HdmiFwVersion, 117, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningApplicationId, 118, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationTitle, 119, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersion, 120, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationStorageLocation, 121, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningAppletList, 122, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(FocusedAppletHistory, 123, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(CompositorState, 124, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorLayerState, 125, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorDisplayState, 126, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorHWCState, 127, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InputCurrentLimit, 128, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimit, 129, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastChargeCurrentLimit, 130, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeVoltageLimit, 131, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfiguration, 132, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizMode, 133, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ChargeEnabled, 134, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 135, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryTemperature, 136, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargePercent, 137, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargeVoltage, 138, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryAge, 139, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerRole, 140, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyType, 141, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyVoltage, 142, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyCurrent, 143, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastBatteryChargingEnabled, 144, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 145, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 146, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NANDPreEolInfo, 147, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypA, 148, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypB, 149, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDPatrolCount, 150, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationFailures, 151, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationErrorCorrections, 152, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteFailures, 153, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteErrorCorrections, 154, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDErrorLog, 155, NANDDriverLog, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardUserAreaSize, 156, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardProtectedAreaSize, 157, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardNumActivationFailures, 158, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumActivationErrorCorrections, 159, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteFailures, 160, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteErrorCorrections, 161, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardErrorLog, 162, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptionKey, 163, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardTimeoutRetryErrorCount, 164, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptCount, 165, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptRetryOutCount, 166, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardInsertionCount, 167, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRemovalCount, 168, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicInitializeCount, 169, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestU16, 170, Test, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(TestU8, 171, Test, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TestI16, 172, Test, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(TestI8, 173, Test, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(SystemAppletScene, 174, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CodecType, 175, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DecodeBuffers, 176, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FrameWidth, 177, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FrameHeight, 178, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorPrimaries, 179, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TransferCharacteristics, 180, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(MatrixCoefficients, 181, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(DisplayWidth, 182, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DisplayHeight, 183, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARWidth, 184, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARHeight, 185, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorFormat, 186, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ColorSpace, 187, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SurfaceLayout, 188, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BitStream, 189, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(VideoDecState, 190, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GpuErrorChannelId, 191, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorAruId, 192, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorType, 193, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultInfo, 194, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorWriteAccess, 195, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(GpuErrorFaultAddress, 196, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorFaultUnit, 197, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultType, 198, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorHwContextPointer, 199, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorContextStatus, 200, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaIntr, 201, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaErrorType, 202, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeaderShadow, 203, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeader, 204, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow0, 205, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow1, 206, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AccessPointChannel, 207, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ThreadName, 208, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 209, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 210, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionProgramCounter, 211, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionLinkRegister, 212, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackPointer, 213, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegisters, 214, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionStackAddress, 215, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackDump, 216, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 217, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(OscillatorClock, 218, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CpuDvfsTableClocks, 219, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(CpuDvfsTableVoltages, 220, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableClocks, 221, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableVoltages, 222, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableClocks, 223, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableVoltages, 224, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(ModuleClockFrequencies, 225, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ModuleClockEnableFlags, 226, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModulePowerEnableFlags, 227, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleResetAssertFlags, 228, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleMinimumVoltageClockRates, 229, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PowerDomainEnableFlags, 230, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PowerDomainVoltages, 231, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(AccessPointRssi, 232, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FuseInfo, 233, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(VideoLog, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardDeviceId, 235, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeCount, 236, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureCount, 237, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureDetail, 238, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardRefreshSuccessCount, 239, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAwakenCount, 240, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAwakenFailureCount, 241, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromInsert, 242, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromAwaken, 243, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageAddress, 244, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageCount, 245, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AppletManagerContextTrace, 246, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispIsRegistered, 247, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispIsSuspend, 248, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDC0SurfaceNum, 249, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispDC1SurfaceNum, 250, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectX, 251, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectY, 252, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectWidth, 253, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectHeight, 254, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectX, 255, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectY, 256, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectWidth, 257, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectHeight, 258, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowIndex, 259, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowBlendOperation, 260, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlphaOperation, 261, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDepth, 262, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlpha, 263, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispWindowHFilter, 264, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowVFilter, 265, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowOptions, 266, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSyncPointId, 267, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPSorPower, 268, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPClkType, 269, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPEnable, 270, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPState, 271, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdid, 272, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDPEdidSize, 273, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdidExtSize, 274, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPFakeMode, 275, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPModeNumber, 276, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPPlugInOut, 277, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPAuxIntHandler, 278, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPForceMaxLinkBW, 279, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPIsConnected, 280, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkValid, 281, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxBW, 282, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxLaneCount, 283, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkDownSpread, 284, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportEnhancedFraming, 285, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBpp, 286, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScaramberCap, 287, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBW, 288, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLaneCount, 289, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkEnhancedFraming, 290, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScrambleEnable, 291, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActivePolarity, 292, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveCount, 293, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTUSize, 294, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveFrac, 295, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkWatermark, 296, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkHBlank, 297, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkVBlank, 298, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEnhancedFraming, 299, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEdpCap, 300, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportFastLT, 301, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLTDataValid, 302, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTsp3Support, 303, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkAuxInterval, 304, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpCreated, 305, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpUserRequest, 306, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpPlugged, 307, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpState, 308, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispHdcpFailCount, 309, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispHdcpHdcp22, 310, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(NvDispHdcpMaxRetry, 311, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpHpd, 312, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpRepeater, 313, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxBuf, 314, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecRxLength, 315, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxBuf, 316, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecTxLength, 317, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxRet, 318, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecState, 319, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispCecTxInfo, 320, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxInfo, 321, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDCIndex, 322, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCInitialize, 323, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCClock, 324, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCFrequency, 325, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCFailed, 326, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCModeWidth, 327, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeHeight, 328, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeBpp, 329, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCPanelFrequency, 330, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinDirty, 331, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinEnable, 332, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCVrr, 333, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCPanelInitialize, 334, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDsiDataFormat, 335, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiVideoMode, 336, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiRefreshRate, 337, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiLpCmdModeFrequency, 338, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiHsCmdModeFrequency, 339, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPanelResetTimeout, 340, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPhyFrequency, 341, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiFrequency, 342, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiInstance, 343, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHostCtrlEnable, 344, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiInit, 345, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnable, 346, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsMode, 347, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiVendorId, 348, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDcDsiLcdVendorNum, 349, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsClockControl, 350, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnableHsClockInLpMode, 351, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiTeFrameUpdate, 352, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiGangedType, 353, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHbpInPktSeq, 354, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispErrID, 355, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData0, 356, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData1, 357, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardMountStatus, 358, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardMountUnexpectedResult, 359, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSize, 360, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SdCardTotalSize, 361, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceInitialLaunch, 362, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSincePowerOn, 363, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceLastAwake, 364, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(OccurrenceTick, 365, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(RetailInteractiveDisplayFlag, 366, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatFsError, 367, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsExtraError, 368, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorDrive, 369, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorName, 370, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorManufactureCode, 371, MonitorCapability, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorProductCode, 372, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorSerialNumber, 373, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(MonitorManufactureYear, 374, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PhysicalAddress, 375, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(Is4k60Hz, 376, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is4k30Hz, 377, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is1080P60Hz, 378, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is720P60Hz, 379, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcmChannelMax, 380, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CrashReportHash, 381, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorReportSharePermission, 382, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(VideoCodecTypeEnum, 383, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoBitRate, 384, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoFrameRate, 385, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoWidth, 386, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoHeight, 387, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioCodecTypeEnum, 388, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioSampleRate, 389, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioChannelCount, 390, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioBitRate, 391, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaContainerType, 392, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaProfileType, 393, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaLevelType, 394, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaCacheSizeEnum, 395, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorStatusEnum, 396, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorLog, 397, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ServerFqdn, 398, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerIpAddress, 399, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TestStringEncrypt, 400, Test, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(TestU8ArrayEncrypt, 401, Test, FieldType_U8Array, FieldFlag_Encrypt) \ - HANDLER(TestU32ArrayEncrypt, 402, Test, FieldType_U32Array, FieldFlag_Encrypt) \ - HANDLER(TestU64ArrayEncrypt, 403, Test, FieldType_U64Array, FieldFlag_Encrypt) \ - HANDLER(TestI32ArrayEncrypt, 404, Test, FieldType_I32Array, FieldFlag_Encrypt) \ - HANDLER(TestI64ArrayEncrypt, 405, Test, FieldType_I64Array, FieldFlag_Encrypt) \ - HANDLER(CipherKey, 406, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FileSystemPath, 407, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerOpenUrl, 408, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerLastSocketErrors, 409, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(UnknownControllerCount, 410, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AttachedControllerCount, 411, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothControllerCount, 412, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbControllerCount, 413, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ControllerTypeList, 414, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerInterfaceList, 415, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerStyleList, 416, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FsPooledBufferPeakFreeSize, 417, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferRetriedCount, 418, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferReduceAllocationCount, 419, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakFreeSize, 420, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerRetriedCount, 421, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsExpHeapPeakFreeSize, 422, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferPoolPeakFreeSize, 423, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferSuccessCount, 424, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferFailureCount, 425, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SteadyClockInternalOffset, 426, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SteadyClockCurrentTimePointValue, 427, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextOffset, 428, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextTimeStampValue, 429, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextOffset, 430, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextTimeStampValue, 431, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemAbortFlag, 432, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationAbortFlag, 433, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NifmErrorCode, 434, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsApplicationId, 435, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyIdList, 436, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyVersionList, 437, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyTypeList, 438, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyInstallTypeList, 439, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsSenderFlag, 440, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsApplicationRequestFlag, 441, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsHasExFatDriverFlag, 442, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsIpAddress, 443, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccount, 444, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAocRegistrationType, 445, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAttributeFlag, 446, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpSupportedLanguageFlag, 447, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpParentalControlFlag, 448, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpScreenShot, 449, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpVideoCapture, 450, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpDataLossConfirmation, 451, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPlayLogPolicy, 452, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPresenceGroupId, 453, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpRatingAge, 454, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ - HANDLER(AcpAocBaseId, 455, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSize, 456, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSize, 457, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSize, 458, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSize, 459, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpBcatDeliveryCacheStorageSize, 460, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpApplicationErrorCodeCategory, 461, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpLocalCommunicationId, 462, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpLogoType, 463, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpLogoHandling, 464, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRuntimeAocInstall, 465, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpCrashReport, 466, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpHdcp, 467, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpSeedForPseudoDeviceId, 468, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSizeMax, 469, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSizeMax, 470, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSizeMax, 471, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSizeMax, 472, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpTemporaryStorageSize, 473, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageSize, 474, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageJournalSize, 475, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageDataAndJournalSizeMax, 476, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageIndexMax, 477, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryableApplicationId, 478, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryCapability, 479, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRepairFlag, 480, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningApplicationPatchStorageLocation, 481, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersionNumber, 482, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRecoveredByInvalidateCacheCount, 483, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsSaveDataIndexCount, 484, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakTotalAllocatableSize, 485, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(MonitorCurrentWidth, 486, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentHeight, 487, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentRefreshRate, 488, MonitorSettings, FieldType_String, FieldFlag_None ) \ - HANDLER(RebootlessSystemUpdateVersion, 489, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptedDyingMessage, 490, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(DramId, 491, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NifmConnectionTestRedirectUrl, 492, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 493, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0Flags, 494, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Speed, 495, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0ResetTimeInUs, 496, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0IrqCount, 497, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Statistics, 498, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePort1Flags, 499, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Speed, 500, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort1ResetTimeInUs, 501, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1IrqCount, 502, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Statistics, 503, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PcieFunction0VendorId, 504, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0DeviceId, 505, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0PmState, 506, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction0IsAcquired, 507, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieFunction1VendorId, 508, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1DeviceId, 509, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1PmState, 510, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction1IsAcquired, 511, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieGlobalRootComplexStatistics, 512, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePllResistorCalibrationValue, 513, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CertificateRequestedHostName, 514, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateCommonName, 515, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateSANCount, 516, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CertificateSANs, 517, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsBufferPoolMaxAllocateSize, 518, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateIssuerName, 519, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationAliveTime, 520, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSwitchLock, 521, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(USB3HostAvailableFlag, 522, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(USB3DeviceAvailableFlag, 523, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccountOptionFlag, 524, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServerErrorCode, 525, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AppletManagerMetaLogTrace, 526, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ServerCertificateSerialNumber, 527, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificatePublicKeyAlgorithm, 528, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateSignatureAlgorithm, 529, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateNotBefore, 530, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ServerCertificateNotAfter, 531, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateAlgorithmInfoBits, 532, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TlsConnectionPeerIpAddress, 533, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TlsConnectionLastHandshakeState, 534, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TlsConnectionInfoBits, 535, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslStateBits, 536, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessInfoBits, 537, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessHeapSize, 538, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SslBaseErrorCode, 539, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDumpSize, 540, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuCrashDump, 541, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(RunningApplicationProgramIndex, 542, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbTopology, 543, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(AkamaiReferenceId, 544, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NvHostErrID, 545, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvHostErrDataArrayU32, 546, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(HasSyslogFlag, 547, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpRuntimeParameterDelivery, 548, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PlatformRegion, 549, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSizeOfSystem, 550, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(NANDFreeSpaceOfSystem, 551, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AccessPointSSIDAsHex, 552, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(PanelVendorId, 553, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelRevisionId, 554, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelModelId, 555, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ErrorContext, 556, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorContextSize, 557, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ErrorContextTotalSize, 558, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryLimit, 559, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountLimit, 560, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountLimit, 561, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountLimit, 562, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountLimit, 563, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryPeak, 564, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountPeak, 565, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountPeak, 566, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountPeak, 567, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountPeak, 568, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GpuCrashHash, 569, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TouchScreenPanelGpioValue, 570, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BrowserCertificateHostName, 571, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateCommonName, 572, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateOrganizationalUnitName, 573, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 574, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AudioOutputTarget, 575, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AudioOutputChannelCount, 576, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AppletTotalActiveTime, 577, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(WakeCount, 578, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PredominantWakeReason, 579, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock2, 580, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock3, 581, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LumenRequestId, 582, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LlnwLlid, 583, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SupportingLimitedApplicationLicenses, 584, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 585, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServiceProfileRevisionKey, 586, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(BluetoothAudioConnectionCount, 587, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothHidPairingInfoCount, 588, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothAudioPairingInfoCount, 589, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothLePairingInfoCount, 590, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFilePeakOpenCount, 591, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 592, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserFilePeakOpenCount, 593, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserDirectoryPeakOpenCount, 594, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardFilePeakOpenCount, 595, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardDirectoryPeakOpenCount, 596, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(SslAlertInfo, 597, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(SslVersionInfo, 598, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 599, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 600, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 601, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 602, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 603, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 604, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ServerErrorIsRetryable, 605, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FsDeepRetryStartCount, 606, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 607, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(BuiltInWirelessOUI, 608, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPOUI, 609, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EthernetAdapterOUI, 610, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatSafeControlResult, 611, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatErrorNumber, 612, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatSafeErrorNumber, 613, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatSafeControlResult, 614, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatErrorNumber, 615, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatSafeErrorNumber, 616, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDump2, 617, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDType, 618, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDType, 619, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardLastDeactivateReasonResult, 620, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastDeactivateReason, 621, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ + HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ + HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ + HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ + HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ + HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ + HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ + HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ + HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ + HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatSafeControlResult, 670, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatErrorNumber, 671, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatSafeErrorNumber, 672, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatSafeControlResult, 673, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatErrorNumber, 674, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatSafeErrorNumber, 675, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDump2, 676, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDType, 677, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDType, 678, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardLastDeactivateReasonResult, 679, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastDeactivateReason, 680, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp deleted file mode 100644 index 30821a41a..000000000 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids_deprecated.autogen.hpp +++ /dev/null @@ -1,693 +0,0 @@ -/* - * Copyright (c) Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#pragma once -#include - -/* NOTE: This file is auto-generated. */ -/* Do not make edits to this file by hand. */ - -#define AMS_ERPT_FOREACH_DEPRECATED_FIELD(HANDLER) \ - HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ - HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ - HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ - HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ - HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ - HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ - HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ - HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ - HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ - HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ - diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index 798d08fad..858919f4b 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -18,7 +18,6 @@ #include #include #include -#include namespace ams::erpt { @@ -49,17 +48,6 @@ namespace ams::erpt { #undef GENERATE_ENUM - #define GENERATE_ENUM(NAME, ID, ...) DeprecatedFieldId_##NAME = ID, - - enum DeprecatedFieldId { - AMS_ERPT_FOREACH_DEPRECATED_FIELD(GENERATE_ENUM) - DeprecatedFieldId_Count, - }; - - #undef GENERATE_ENUM - - #define ERPT_FIELD_ID(NAME) (::ams::hos::GetVersion() >= ::ams::hos::Version_17_0_0 ? ::ams::erpt::FieldId_##NAME : static_cast<::ams::erpt::FieldId>(::ams::util::ToUnderlying(::ams::erpt::DeprecatedFieldId_##NAME))) - constexpr inline u32 ArrayBufferSizeDefault = 0x100; constexpr inline u32 ArrayBufferSizeMax = 96_KB; constexpr inline u32 ArrayFieldSizeMax = 16_KB - 1; diff --git a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp index a1d6eeea0..a4604743b 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp @@ -49,10 +49,6 @@ namespace ams::erpt::srv { AMS_ERPT_FOREACH_FIELD(STRINGIZE_HANDLER) }; - constexpr inline const char * const DeprecatedFieldString[] = { - AMS_ERPT_FOREACH_DEPRECATED_FIELD(STRINGIZE_HANDLER) - }; - constexpr inline const char * const CategoryString[] = { AMS_ERPT_FOREACH_CATEGORY(STRINGIZE_HANDLER) }; @@ -80,49 +76,16 @@ namespace ams::erpt::srv { }; #undef GET_FIELD_FLAG - #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [DeprecatedFieldId_##FIELD] = CategoryId_##CATEGORY, - constexpr inline const CategoryId DeprecatedFieldToCategoryMap[] = { - AMS_ERPT_FOREACH_DEPRECATED_FIELD(GET_FIELD_CATEGORY) - }; - #undef GET_FIELD_CATEGORY - - #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [DeprecatedFieldId_##FIELD] = TYPE, - constexpr inline const FieldType DeprecatedFieldToTypeMap[] = { - AMS_ERPT_FOREACH_DEPRECATED_FIELD(GET_FIELD_TYPE) - }; - #undef GET_FIELD_TYPE - - #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [DeprecatedFieldId_##FIELD] = FLAG, - constexpr inline const FieldFlag DeprecatedFieldToFlagMap[] = { - AMS_ERPT_FOREACH_DEPRECATED_FIELD(GET_FIELD_FLAG) - }; - #undef GET_FIELD_FLAG - inline CategoryId ConvertFieldToCategory(FieldId id) { - if (hos::GetVersion() >= hos::Version_17_0_0) { - return FieldToCategoryMap[id]; - } else { - AMS_ABORT_UNLESS(util::ToUnderlying(id) < util::ToUnderlying(DeprecatedFieldId_Count)); - return DeprecatedFieldToCategoryMap[id]; - } + return FieldToCategoryMap[id]; } inline FieldType ConvertFieldToType(FieldId id) { - if (hos::GetVersion() >= hos::Version_17_0_0) { - return FieldToTypeMap[id]; - } else { - AMS_ABORT_UNLESS(util::ToUnderlying(id) < util::ToUnderlying(DeprecatedFieldId_Count)); - return DeprecatedFieldToTypeMap[id]; - } + return FieldToTypeMap[id]; } inline FieldFlag ConvertFieldToFlag(FieldId id) { - if (hos::GetVersion() >= hos::Version_17_0_0) { - return FieldToFlagMap[id]; - } else { - AMS_ABORT_UNLESS(util::ToUnderlying(id) < util::ToUnderlying(DeprecatedFieldId_Count)); - return DeprecatedFieldToFlagMap[id]; - } + return FieldToFlagMap[id]; } constexpr inline ReportFlagSet MakeNoReportFlags() { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp index 807132bb0..a71c3c6f5 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_cipher.hpp @@ -81,7 +81,7 @@ namespace ams::erpt::srv { oaep.Encrypt(cipher, sizeof(cipher), s_key, sizeof(s_key), salt, sizeof(salt)); } - Formatter::AddField(report, ERPT_FIELD_ID(CipherKey), cipher, sizeof(cipher)); + Formatter::AddField(report, FieldId_CipherKey, cipher, sizeof(cipher)); std::memset(s_key, 0, sizeof(s_key)); R_RETURN(Formatter::End(report)); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp index b366c1550..1d2b4681b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp @@ -75,8 +75,8 @@ namespace ams::erpt::srv { for (u32 i = 0; i < m_ctx.field_count; i++) { m_ctx.fields[i] = ctx_ptr->fields[i]; - R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < ERPT_FIELD_ID(Count), erpt::ResultInvalidArgument()); - R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); + R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < FieldId_Count, erpt::ResultInvalidArgument()); + R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); R_UNLESS(m_ctx.fields[i].type == ConvertFieldToType(m_ctx.fields[i].id), erpt::ResultFieldTypeMismatch()); R_UNLESS(m_ctx.category == ConvertFieldToCategory(m_ctx.fields[i].id), erpt::ResultFieldCategoryMismatch()); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp index 89189d99b..0b116f7ba 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp @@ -83,7 +83,7 @@ namespace ams::erpt::srv { err::GetErrorCodeString(error_code_str, sizeof(error_code_str), err::ConvertResultToErrorCode(err::ResultForcedShutdownDetected())); /* Add error code to the context. */ - R_TRY(record->Add(ERPT_FIELD_ID(ErrorCode), error_code_str, std::strlen(error_code_str))); + R_TRY(record->Add(FieldId_ErrorCode, error_code_str, std::strlen(error_code_str))); /* Create report. */ R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags())); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp index 013bb45a4..b50712be3 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp @@ -62,11 +62,7 @@ namespace ams::erpt::srv { static Result AddId(Report *report, FieldId field_id) { static_assert(MaxFieldStringSize < ElementSize_256); - if (hos::GetVersion() >= hos::Version_17_0_0) { - R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); - } else { - R_TRY(AddStringValue(report, DeprecatedFieldString[field_id], strnlen(DeprecatedFieldString[field_id], MaxFieldStringSize))); - } + R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp index 1f3ef25db..6f23bde32 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp @@ -135,7 +135,7 @@ namespace ams::erpt::srv { auto record = std::make_unique(CategoryId_ProductModelInfo); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - R_TRY(record->Add(ERPT_FIELD_ID(ProductModel), model, model_len)); + R_TRY(record->Add(FieldId_ProductModel, model, model_len)); R_TRY(Context::SubmitContextRecord(std::move(record))); R_SUCCEED(); @@ -146,7 +146,7 @@ namespace ams::erpt::srv { auto record = std::make_unique(CategoryId_RegionSettingInfo); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); - R_TRY(record->Add(ERPT_FIELD_ID(RegionSetting), region, region_len)); + R_TRY(record->Add(FieldId_RegionSetting, region, region_len)); R_TRY(Context::SubmitContextRecord(std::move(record))); R_SUCCEED(); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index 33752621e..ae0429a6d 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -123,14 +123,14 @@ namespace ams::erpt::srv { if (error_context_total_size == 0) { return; } - record->Add(ERPT_FIELD_ID(ErrorContextTotalSize), error_context_total_size); + record->Add(FieldId_ErrorContextTotalSize, error_context_total_size); /* Set the context. */ if (error_context_size == 0) { return; } - record->Add(ERPT_FIELD_ID(ErrorContextSize), error_context_size); - record->Add(ERPT_FIELD_ID(ErrorContext), error_context, error_context_size); + record->Add(FieldId_ErrorContextSize, error_context_size); + record->Add(FieldId_ErrorContext, error_context, error_context_size); } constinit os::SdkMutex g_limit_mutex; @@ -164,7 +164,7 @@ namespace ams::erpt::srv { if (R_FAILED(svc::GetResourceLimitLimitValue(std::addressof(limit_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ return; \ } \ - if (R_FAILED(record->Add(ERPT_FIELD_ID(System##__RESOURCE__##Limit), limit_value))) { \ + if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Limit, limit_value))) { \ return; \ } \ } while (0) @@ -203,7 +203,7 @@ namespace ams::erpt::srv { if (R_FAILED(svc::GetResourceLimitPeakValue(std::addressof(peak_value), handle, svc::LimitableResource_##__RESOURCE__##Max))) { \ return; \ } \ - if (R_FAILED(record->Add(ERPT_FIELD_ID(System##__RESOURCE__##Peak), peak_value))) { \ + if (R_FAILED(record->Add(FieldId_System##__RESOURCE__##Peak, peak_value))) { \ return; \ } \ } while (0) @@ -234,7 +234,7 @@ namespace ams::erpt::srv { R_UNLESS(ctx->field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); const bool found_error_code = util::range::any_of(MakeSpan(ctx->fields, ctx->field_count), [] (const FieldEntry &entry) { - return entry.id == ERPT_FIELD_ID(ErrorCode); + return entry.id == FieldId_ErrorCode; }); R_UNLESS(found_error_code, erpt::ResultRequiredFieldMissing()); @@ -249,10 +249,10 @@ namespace ams::erpt::srv { bool found_abort_flag = false, found_syslog_flag = false; for (u32 i = 0; i < ctx->field_count; i++) { - if (ctx->fields[i].id == ERPT_FIELD_ID(AbortFlag)) { + if (ctx->fields[i].id == FieldId_AbortFlag) { found_abort_flag = true; } - if (ctx->fields[i].id == ERPT_FIELD_ID(HasSyslogFlag)) { + if (ctx->fields[i].id == FieldId_HasSyslogFlag) { found_syslog_flag = true; } if (found_abort_flag && found_syslog_flag) { @@ -261,11 +261,11 @@ namespace ams::erpt::srv { } if (!found_abort_flag) { - record->Add(ERPT_FIELD_ID(AbortFlag), false); + record->Add(FieldId_AbortFlag, false); } if (!found_syslog_flag) { - record->Add(ERPT_FIELD_ID(HasSyslogFlag), true); + record->Add(FieldId_HasSyslogFlag, true); } R_TRY(Context::SubmitContextRecord(std::move(record))); @@ -277,7 +277,7 @@ namespace ams::erpt::srv { bool needs_save_syslog = true; for (u32 i = 0; i < ctx->field_count; i++) { static_assert(FieldToTypeMap[FieldId_HasSyslogFlag] == FieldType_Bool); - if (ctx->fields[i].id == ERPT_FIELD_ID(HasSyslogFlag) && !ctx->fields[i].value_bool) { + if (ctx->fields[i].id == FieldId_HasSyslogFlag && !ctx->fields[i].value_bool) { needs_save_syslog = false; break; } @@ -299,13 +299,13 @@ namespace ams::erpt::srv { /* Find the program id entry. */ const auto fields_span = MakeSpan(error_info_ctx->fields, error_info_ctx->field_count); - const auto program_id_entry = util::range::find_if(fields_span, [](const FieldEntry &entry) { return entry.id == ERPT_FIELD_ID(ProgramId); }); + const auto program_id_entry = util::range::find_if(fields_span, [](const FieldEntry &entry) { return entry.id == FieldId_ProgramId; }); if (program_id_entry == fields_span.end()) { return; } /* Check that the report has abort flag set. */ - AMS_ASSERT(util::range::any_of(fields_span, [](const FieldEntry &entry) { return entry.id == ERPT_FIELD_ID(AbortFlag) && entry.value_bool; })); + AMS_ASSERT(util::range::any_of(fields_span, [](const FieldEntry &entry) { return entry.id == FieldId_AbortFlag && entry.value_bool; })); /* Check that the program id's value is a string. */ AMS_ASSERT(program_id_entry->type == FieldType_String); @@ -334,7 +334,7 @@ namespace ams::erpt::srv { } /* Add the active applet time. */ - const auto result = error_info_auto_record->Add(ERPT_FIELD_ID(AppletTotalActiveTime), (*active_duration).GetSeconds()); + const auto result = error_info_auto_record->Add(FieldId_AppletTotalActiveTime, (*active_duration).GetSeconds()); R_ASSERT(result); } @@ -489,28 +489,28 @@ namespace ams::erpt::srv { R_ABORT_UNLESS(time::GetStandardSteadyClockCurrentTimePoint(std::addressof(steady_clock_current_timepoint))); /* Add automatic fields. */ - auto_record->Add(ERPT_FIELD_ID(OsVersion), s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))); - auto_record->Add(ERPT_FIELD_ID(PrivateOsVersion), s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))); - auto_record->Add(ERPT_FIELD_ID(SerialNumber), s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))); - auto_record->Add(ERPT_FIELD_ID(ReportIdentifier), identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))); - auto_record->Add(ERPT_FIELD_ID(OccurrenceTimestamp), timestamp_user.value); - auto_record->Add(ERPT_FIELD_ID(OccurrenceTimestampNet), timestamp_network.value); - auto_record->Add(ERPT_FIELD_ID(ReportVisibilityFlag), type == ReportType_Visible); - auto_record->Add(ERPT_FIELD_ID(OccurrenceTick), occurrence_tick.GetInt64Value()); - auto_record->Add(ERPT_FIELD_ID(SteadyClockInternalOffset), steady_clock_internal_offset_seconds); - auto_record->Add(ERPT_FIELD_ID(SteadyClockCurrentTimePointValue), steady_clock_current_timepoint.value); - auto_record->Add(ERPT_FIELD_ID(ElapsedTimeSincePowerOn), (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()); - auto_record->Add(ERPT_FIELD_ID(ElapsedTimeSinceLastAwake), (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()); + auto_record->Add(FieldId_OsVersion, s_os_version, util::Strnlen(s_os_version, sizeof(s_os_version))); + auto_record->Add(FieldId_PrivateOsVersion, s_private_os_version, util::Strnlen(s_private_os_version, sizeof(s_private_os_version))); + auto_record->Add(FieldId_SerialNumber, s_serial_number, util::Strnlen(s_serial_number, sizeof(s_serial_number))); + auto_record->Add(FieldId_ReportIdentifier, identifier_str, util::Strnlen(identifier_str, sizeof(identifier_str))); + auto_record->Add(FieldId_OccurrenceTimestamp, timestamp_user.value); + auto_record->Add(FieldId_OccurrenceTimestampNet, timestamp_network.value); + auto_record->Add(FieldId_ReportVisibilityFlag, type == ReportType_Visible); + auto_record->Add(FieldId_OccurrenceTick, occurrence_tick.GetInt64Value()); + auto_record->Add(FieldId_SteadyClockInternalOffset, steady_clock_internal_offset_seconds); + auto_record->Add(FieldId_SteadyClockCurrentTimePointValue, steady_clock_current_timepoint.value); + auto_record->Add(FieldId_ElapsedTimeSincePowerOn, (occurrence_tick - *s_power_on_time).ToTimeSpan().GetSeconds()); + auto_record->Add(FieldId_ElapsedTimeSinceLastAwake, (occurrence_tick - *s_awake_time).ToTimeSpan().GetSeconds()); if (s_initial_launch_settings_completion_time) { s64 elapsed_seconds; if (R_SUCCEEDED(time::GetElapsedSecondsBetween(std::addressof(elapsed_seconds), *s_initial_launch_settings_completion_time, steady_clock_current_timepoint))) { - auto_record->Add(ERPT_FIELD_ID(ElapsedTimeSinceInitialLaunch), elapsed_seconds); + auto_record->Add(FieldId_ElapsedTimeSinceInitialLaunch, elapsed_seconds); } } if (s_application_launch_time) { - auto_record->Add(ERPT_FIELD_ID(ApplicationAliveTime), (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()); + auto_record->Add(FieldId_ApplicationAliveTime, (occurrence_tick - *s_application_launch_time).ToTimeSpan().GetSeconds()); } /* Submit applet active duration information. */ From 2ec3e141c7178c4ad570552bca4411946b88a22e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 11 Oct 2023 18:50:38 -0700 Subject: [PATCH 041/238] bpc.mitm/exo: support pmic reboot/shutdown on mariko (thanks @CTCaer) --- .../source/secmon_user_power_management.cpp | 26 ++++++++++++++++--- .../source/secmon_user_power_management.hpp | 2 ++ .../program/source/smc/secmon_smc_info.cpp | 14 +++++----- .../stratosphere/ams/ams_exosphere_api.hpp | 1 + .../source/ams/ams_exosphere_api.cpp | 4 +++ .../source/bpc_mitm/bpc_ams_power_utils.cpp | 17 ++++++++++++ .../source/bpc_mitm/bpcmitm_module.cpp | 5 ---- 7 files changed, 54 insertions(+), 15 deletions(-) diff --git a/exosphere/program/source/secmon_user_power_management.cpp b/exosphere/program/source/secmon_user_power_management.cpp index 719dc427a..6f81af026 100644 --- a/exosphere/program/source/secmon_user_power_management.cpp +++ b/exosphere/program/source/secmon_user_power_management.cpp @@ -70,6 +70,15 @@ namespace ams::secmon { } + void PerformUserRebootByPmic() { + /* Ensure that i2c-5 is usable for communicating with the pmic. */ + clkrst::EnableI2c5Clock(); + i2c::Initialize(i2c::Port_5); + + /* Reboot. */ + pmic::ShutdownSystem(true); + } + void PerformUserRebootToRcm() { /* Configure the bootrom to boot to rcm. */ reg::Write(PMC + APBDEV_PMC_SCRATCH0, 0x2); @@ -100,11 +109,20 @@ namespace ams::secmon { } void PerformUserShutDown() { - /* Load our reboot stub to iram. */ - LoadRebootStub(RebootStubAction_ShutDown); + if (fuse::GetSocType() == fuse::SocType_Mariko) { + /* Ensure that i2c-5 is usable for communicating with the pmic. */ + clkrst::EnableI2c5Clock(); + i2c::Initialize(i2c::Port_5); - /* Reboot. */ - PerformPmcReboot(); + /* On Mariko shutdown via pmic. */ + pmic::ShutdownSystem(false); + } else /* if (fuse::GetSocType() == fuse::SocType_Erista) */ { + /* Load our reboot stub to iram. */ + LoadRebootStub(RebootStubAction_ShutDown); + + /* Reboot. */ + PerformPmcReboot(); + } } } diff --git a/exosphere/program/source/secmon_user_power_management.hpp b/exosphere/program/source/secmon_user_power_management.hpp index ab3e1e6a6..678ae3167 100644 --- a/exosphere/program/source/secmon_user_power_management.hpp +++ b/exosphere/program/source/secmon_user_power_management.hpp @@ -23,11 +23,13 @@ namespace ams::secmon { UserRebootType_ToRcm = 1, UserRebootType_ToPayload = 2, UserRebootType_ToFatalError = 3, + UserRebootType_ByPmic = 4, }; void PerformUserRebootToRcm(); void PerformUserRebootToPayload(); void PerformUserRebootToFatalError(); + void PerformUserRebootByPmic(); void PerformUserShutDown(); } diff --git a/exosphere/program/source/smc/secmon_smc_info.cpp b/exosphere/program/source/smc/secmon_smc_info.cpp index 365d31f27..11f4a693a 100644 --- a/exosphere/program/source/smc/secmon_smc_info.cpp +++ b/exosphere/program/source/smc/secmon_smc_info.cpp @@ -357,6 +357,9 @@ namespace ams::secmon::smc { case UserRebootType_ToFatalError: PerformUserRebootToFatalError(); break; + case UserRebootType_ByPmic: + PerformUserRebootByPmic(); + break; default: return SmcResult::InvalidArgument; } @@ -365,18 +368,17 @@ namespace ams::secmon::smc { case UserRebootType_ToFatalError: PerformUserRebootToFatalError(); break; + case UserRebootType_ByPmic: + PerformUserRebootByPmic(); + break; default: return SmcResult::InvalidArgument; } } break; case ConfigItem::ExosphereNeedsShutdown: - if (soc_type == fuse::SocType_Erista) { - if (args.r[3] != 0) { - PerformUserShutDown(); - } - } else /* if (soc_type == fuse::SocType_Mariko) */ { - return SmcResult::NotSupported; + if (args.r[3] != 0) { + PerformUserShutDown(); } break; case ConfigItem::ExospherePayloadAddress: diff --git a/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp b/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp index 84cdfe9a9..2712b2b50 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/ams_exosphere_api.hpp @@ -25,6 +25,7 @@ namespace ams::exosphere { void ForceRebootToRcm(); void ForceRebootToIramPayload(); void ForceRebootToFatalError(); + void ForceRebootByPmic(); void ForceShutdown(); bool IsRcmBugPatched(); diff --git a/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp b/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp index 6c2a7cccb..d48b0ce57 100644 --- a/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp +++ b/libraries/libstratosphere/source/ams/ams_exosphere_api.cpp @@ -39,6 +39,10 @@ namespace ams::exosphere { R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 3)); } + void ForceRebootByPmic() { + R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsReboot, 4)); + } + void ForceShutdown() { R_ABORT_UNLESS(spl::impl::SetConfig(spl::ConfigItem::ExosphereNeedsShutdown, 1)); } diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp index 8ea3b9f28..12f8a0e7c 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpc_ams_power_utils.cpp @@ -33,6 +33,7 @@ namespace ams::mitm::bpc { Standard, ToRcm, ToPayload, + ByPmic, }; /* Globals. */ @@ -93,6 +94,9 @@ namespace ams::mitm::bpc { void RebootSystem() { switch (g_reboot_type) { + case RebootType::ByPmic: + exosphere::ForceRebootByPmic(); + break; case RebootType::ToRcm: exosphere::ForceRebootToRcm(); break; @@ -113,6 +117,11 @@ namespace ams::mitm::bpc { } void SetRebootPayload(const void *payload, size_t payload_size) { + /* Mariko does not support reboot-to-payload. */ + if (spl::GetSocType() == spl::SocType_Mariko) { + return; + } + /* Clear payload buffer */ std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); @@ -131,6 +140,9 @@ namespace ams::mitm::bpc { } Result LoadRebootPayload() { + /* Mariko does not support reboot-to-payload. */ + R_SUCCEED_IF(spl::GetSocType() == spl::SocType_Mariko) + /* Clear payload buffer */ std::memset(g_reboot_payload, 0xCC, sizeof(g_reboot_payload)); @@ -163,6 +175,11 @@ namespace ams::mitm::bpc { g_reboot_type = RebootType::ToPayload; } + /* TODO: Should we actually allow control over this on mariko? */ + if (spl::GetSocType() == spl::SocType_Mariko) { + g_reboot_type = RebootType::ByPmic; + } + R_SUCCEED(); } diff --git a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp index 8776c9b50..da01abc46 100644 --- a/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp +++ b/stratosphere/ams_mitm/source/bpc_mitm/bpcmitm_module.cpp @@ -67,11 +67,6 @@ namespace ams::mitm::bpc { /* Wait until initialization is complete. */ mitm::WaitInitialized(); - /* On Mariko, we can't reboot to payload/do exosphere-shutdown...so there is no point in bpc.mitm. */ - if (spl::GetSocType() == spl::SocType_Mariko) { - return; - } - /* Create bpc mitm. */ const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_2_0_0) ? MitmServiceName : DeprecatedMitmServiceName; From 02e987819bf0dd0671055a15efb754cb967ab774 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 08:17:05 -0700 Subject: [PATCH 042/238] ncm: work around change in Nintendo save handling behavior Static save files do not require an entry in the save data indexer to mount. Prior to 17.0.0, save data files were considered static if userid was 0. In 17.0.0+, only 8000000000000000 is static. However, some users using cfw do not have an entry for 8000000000000120 in the indexer, for various reasons (but mostly manual nand-restore, I think). Thus, on boot of 17.0.0+, FS will say 8000000000000120 is not present (not in indexer), and NCM will create it anew. The 8000000000000120 save will then be empty, and then the firmware can't boot. To workaround this, logic has been re-enabled on 17.0.0+ for building the content meta database. Thus, if the user encounters this error, the 8000000000000120 save will be emptied, but then it will be automatically reconstructed, fixing the problem. --- .../source/ncm/ncm_content_manager_impl.cpp | 6 ++++-- stratosphere/ncm/source/ncm_main.cpp | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp index 655a2cba1..43a497557 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp @@ -784,7 +784,8 @@ namespace ams::ncm { } Result ContentManagerImpl::BuildContentMetaDatabase(StorageId storage_id) { - if (hos::GetVersion() < hos::Version_5_0_0) { + /* NOTE: we build on 17.0.0+, to work around a change in Nintendo save handling behavior. */ + if (hos::GetVersion() < hos::Version_5_0_0 || hos::GetVersion() >= hos::Version_17_0_0) { /* Temporarily activate the database. */ R_TRY(this->ActivateContentMetaDatabase(storage_id)); ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); }; @@ -946,7 +947,8 @@ namespace ams::ncm { R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); /* Try to build or import a database, depending on our configuration. */ - if (manager_config.ShouldBuildDatabase()) { + /* NOTE: To work around a change in save management behavior in 17.0.0+, we build the database if needed. */ + if (manager_config.ShouldBuildDatabase() || hos::GetVersion() >= hos::Version_17_0_0) { /* If we should build the database, do so. */ R_TRY(this->BuildContentMetaDatabase(StorageId::BuiltInSystem)); R_TRY(this->VerifyContentMetaDatabase(StorageId::BuiltInSystem)); diff --git a/stratosphere/ncm/source/ncm_main.cpp b/stratosphere/ncm/source/ncm_main.cpp index e1fe85c59..a5f1688cc 100644 --- a/stratosphere/ncm/source/ncm_main.cpp +++ b/stratosphere/ncm/source/ncm_main.cpp @@ -170,16 +170,18 @@ namespace ams { fs::SetAllocator(Allocate, Deallocate); fs::SetEnabledAutoAbort(false); + /* Initialize ncm api. */ + /* NOTE: Nintendo does this after initializing and starting threads. */ + ncm::InitializeWithObject(g_ncm_manager_service_object.GetShared()); + /* Create and initialize the content manager. */ R_ABORT_UNLESS(g_ncm_manager_service_object.GetImpl().Initialize(ManagerConfig)); + /* Initialize ncm's server and start threads. */ R_ABORT_UNLESS(g_ncm_server_manager.Initialize()); R_ABORT_UNLESS(g_ncm_server_manager.StartThreads()); - /* Initialize ncm api. */ - ncm::InitializeWithObject(g_ncm_manager_service_object.GetShared()); - /* Initialize lr's server and start threads. */ R_ABORT_UNLESS(g_lr_server_manager.Initialize()); R_ABORT_UNLESS(g_lr_server_manager.StartThreads()); From 0c063db9260c5ef93e37e0a6bb7ee95ff09dd9b6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 08:43:27 -0700 Subject: [PATCH 043/238] loader: add usb3 patches for 17.0.0 --- stratosphere/loader/source/ldr_embedded_usb_patches.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index 66e9bc633..f655c6a94 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -54,6 +54,11 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_16_0_0[] = { { 0x7208, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_17_0_0[] = { + { 0x7170, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x71EC, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 }, @@ -64,4 +69,5 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("1C97AFF30D48AFFEB74B28A530D30ABA0ABB9FFF"), util::size(Usb30ForceEnablePatches_14_0_0), Usb30ForceEnablePatches_14_0_0 }, /* 14.0.0 */ { ParseModuleId("30B15A83E94D91750E7470795414AD1AE9C6A8DB"), util::size(Usb30ForceEnablePatches_15_0_0), Usb30ForceEnablePatches_15_0_0 }, /* 15.0.0 */ { ParseModuleId("225865A442B4B66E8BD14B3E9450B901BDF29A40"), util::size(Usb30ForceEnablePatches_16_0_0), Usb30ForceEnablePatches_16_0_0 }, /* 16.0.0 */ + { ParseModuleId("70D4C2ABCD049F16B301186924367F813DA70248"), util::size(Usb30ForceEnablePatches_17_0_0), Usb30ForceEnablePatches_17_0_0 }, /* 17.0.0 */ }; From e4d08ae0c5342cdb0875d164522a63ec9d233052 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 08:52:39 -0700 Subject: [PATCH 044/238] erpt: amend min-version for latest CreateReportWithAttachments --- .../include/stratosphere/erpt/sf/erpt_sf_i_context.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp index 94e876525..784bcc9da 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp @@ -33,7 +33,7 @@ AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_11_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ From 719858ad18dc0182920100c767b1876797e01e74 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 09:02:30 -0700 Subject: [PATCH 045/238] git subrepo push emummc subrepo: subdir: "emummc" merged: "9513a5412" upstream: origin: "https://github.com/m4xw/emummc" branch: "develop" commit: "9513a5412" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- emummc/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index 552875724..9cf888ba6 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = 30205111ee375bef96f0f76cb6a3130a2f0fc85c - parent = 81e9154a52a976f85317bddd0131426599d26a62 + commit = 9513a5412057b1f1bc44ed8e717c57c726763a88 + parent = e4d08ae0c5342cdb0875d164522a63ec9d233052 method = merge cmdver = 0.4.1 From d389ef639ed2988325523f1d95f90030a3370541 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 09:19:26 -0700 Subject: [PATCH 046/238] docs: add changelog for 1.6.0 --- docs/changelog.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 5f2c954fa..a46f2a4ac 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,20 @@ # Changelog +## 1.6.0 ++ Basic support was added for 17.0.0. + + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. + + There shouldn't be anything user visible resulting from this, but it will be addressed in a soon-to-come atmosphère update. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + `ncm` was updated to reflect the latest official behavior. + + `erpt` was partially updated to support the latest official behavior. ++ Atmosphere's gdbstub now supports waiting to attach to a specific program id on launch (as opposed to any application). + + The monitor command for this is `monitor wait `, where program id can optionally have an `0x` prefix. ++ Support was added to `haze` for editing files in-place and performing 64-bit transfers (files larger than 4 GB). ++ `bpc.mitm` was enabled on Mariko units, and now triggers pmic-based shutdowns/reboots (thanks @CTCaer). + + This should cause the console to no longer wake ~15 seconds after shutdown on Mariko. ++ A number of minor issues were fixed and improvements were made, including: + + A workaround was added for a change in 17.0.0 that would cause consoles which had previously re-built their SYSTEM partition to brick on update-to-17.0.0. ++ General system stability improvements to enhance the user's experience. ## 1.5.5 + Support was added for 16.1.0. + General system stability improvements to enhance the user's experience. From 8a9eb85e055776720abeec5517909a32aed9a32f Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 09:23:31 -0700 Subject: [PATCH 047/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "132558c33" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "132558c33" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 8d4818b89..328a6aea8 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = c3dc418a28e390bc57426016aa2c9e7e87d7a584 - parent = e488b6ee478f5b3a0380e75e4b468e1e4b1d816f + commit = 132558c33865f6a21f06caa31bdfc6b1f92bd9b2 + parent = d389ef639ed2988325523f1d95f90030a3370541 method = merge cmdver = 0.4.1 From 693fb423cbbd5ab28963c5157a6f46d1aae838cf Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 12 Oct 2023 14:25:17 -0700 Subject: [PATCH 048/238] kern: fix minor sin --- libraries/libmesosphere/source/kern_k_page_table_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 79034dcf2..bfa687aed 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -583,7 +583,7 @@ namespace ams::kern { /* Check memory state. */ const KProcessAddress last_addr = addr + size - 1; KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); - R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)) + R_TRY(this->CheckMemoryState(out_state, out_perm, out_attr, out_blocks_needed, it, last_addr, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); /* If the start address isn't aligned, we need a block. */ if (out_blocks_needed != nullptr && util::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) { From 13411902c9bb9e7fb7275999658ee4ae5dbb6782 Mon Sep 17 00:00:00 2001 From: Liam Date: Sat, 14 Oct 2023 10:42:18 -0400 Subject: [PATCH 049/238] fs: add missing stub for GetProgramId --- .../source/fssrv/fssrv_file_system_proxy_impl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp index c3336bfb7..eabc29e34 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -307,6 +307,10 @@ namespace ams::fssrv { AMS_ABORT("TODO"); } + Result FileSystemProxyImpl::GetProgramId(ams::sf::Out out_program_id, const fssrv::sf::FspPath &path, fs::ContentAttributes attr) { + AMS_ABORT("TODO"); + } + Result FileSystemProxyImpl::GetRightsIdByPath(ams::sf::Out out, const fssrv::sf::FspPath &path) { AMS_ABORT("TODO"); } From 3a8cffef57a8a9a6372985dab8a48fa2160f1ca8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 16 Oct 2023 02:37:40 -0700 Subject: [PATCH 050/238] ncm: better detect + fix 17 brick after-the-fact This adds detection for missing-save or empty-save, and rebuilds in either case. --- .../ncm/ncm_content_manager_impl.hpp | 4 + .../source/ncm/ncm_content_manager_impl.cpp | 76 ++++++++++++++----- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp index 2c4cb06f2..348acc486 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_manager_impl.hpp @@ -239,8 +239,12 @@ namespace ams::ncm { Result InitializeIntegratedContentMetaDatabaseRoot(IntegratedContentMetaDatabaseRoot *out, const IntegratedContentStorageConfig *config, size_t root_idx, size_t root_count); Result BuildContentMetaDatabase(StorageId storage_id); + Result BuildContentMetaDatabaseImpl(StorageId storage_id); Result ImportContentMetaDatabase(StorageId storage_id, bool from_signed_partition); Result ImportContentMetaDatabaseImpl(ContentMetaDatabaseRoot *root, const char *import_mount_name); + private: + /* Helpers for unofficial functionality. */ + bool IsNeedRebuildSystemContentMetaDatabase(); public: /* Actual commands. */ Result CreateContentStorage(StorageId storage_id); diff --git a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp index 43a497557..05c8d90a6 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp @@ -784,27 +784,31 @@ namespace ams::ncm { } Result ContentManagerImpl::BuildContentMetaDatabase(StorageId storage_id) { - /* NOTE: we build on 17.0.0+, to work around a change in Nintendo save handling behavior. */ - if (hos::GetVersion() < hos::Version_5_0_0 || hos::GetVersion() >= hos::Version_17_0_0) { - /* Temporarily activate the database. */ - R_TRY(this->ActivateContentMetaDatabase(storage_id)); - ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); }; - - /* Open the content meta database and storage. */ - ContentMetaDatabase meta_db; - ContentStorage storage; - R_TRY(ncm::OpenContentMetaDatabase(std::addressof(meta_db), storage_id)); - R_TRY(ncm::OpenContentStorage(std::addressof(storage), storage_id)); - - /* Create a builder, and build. */ - ContentMetaDatabaseBuilder builder(std::addressof(meta_db)); - R_RETURN(builder.BuildFromStorage(std::addressof(storage))); + if (hos::GetVersion() < hos::Version_5_0_0) { + /* On < 5.0.0, perform an actual build of the database. */ + R_RETURN(this->BuildContentMetaDatabaseImpl(storage_id)); } else { /* On 5.0.0+, building just performs an import. */ R_RETURN(this->ImportContentMetaDatabase(storage_id, false)); } } + Result ContentManagerImpl::BuildContentMetaDatabaseImpl(StorageId storage_id) { + /* Temporarily activate the database. */ + R_TRY(this->ActivateContentMetaDatabase(storage_id)); + ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(storage_id); }; + + /* Open the content meta database and storage. */ + ContentMetaDatabase meta_db; + ContentStorage storage; + R_TRY(ncm::OpenContentMetaDatabase(std::addressof(meta_db), storage_id)); + R_TRY(ncm::OpenContentStorage(std::addressof(storage), storage_id)); + + /* Create a builder, and build. */ + ContentMetaDatabaseBuilder builder(std::addressof(meta_db)); + R_RETURN(builder.BuildFromStorage(std::addressof(storage))); + } + Result ContentManagerImpl::ImportContentMetaDatabase(StorageId storage_id, bool from_signed_partition) { /* Only support importing BuiltInSystem. */ AMS_ABORT_UNLESS(storage_id == StorageId::BuiltInSystem); @@ -832,6 +836,31 @@ namespace ams::ncm { R_SUCCEED(); } + bool ContentManagerImpl::IsNeedRebuildSystemContentMetaDatabase() { + /* TODO: Should hos::GetVersion() >= hos::Version_17_0_0 be checked? */ + + /* If we do not actually have a content meta db, we should re-build. */ + if (R_FAILED(this->VerifyContentMetaDatabase(StorageId::BuiltInSystem))) { + return true; + } + + /* We have a content meta db. Temporarily, activate it. */ + if (R_FAILED(this->ActivateContentMetaDatabase(StorageId::BuiltInSystem))) { + return true; + } + ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(StorageId::BuiltInSystem); }; + + /* Open the content meta database and storage. */ + ContentMetaDatabase meta_db; + R_ABORT_UNLESS(ncm::OpenContentMetaDatabase(std::addressof(meta_db), StorageId::BuiltInSystem)); + + /* List the meta db's contents. */ + const auto list_count = meta_db.ListContentMeta(nullptr, 0); + + /* We need to rebuild if the db has zero entries. */ + return list_count.total == 0; + } + Result ContentManagerImpl::Initialize(const ContentManagerConfig &config) { /* Initialize based on whether integrated content is enabled. */ if (config.IsIntegratedSystemContentEnabled()) { @@ -942,13 +971,26 @@ namespace ams::ncm { } R_TRY(this->ActivateContentStorage(StorageId::BuiltInSystem)); + /* NOTE: This logic is unofficial. */ + /* Beginning with 17.0.0+, save management behavior changed. The primary symptom of this is either verify fail */ + /* or an empty kvs, both of which we can fix by performing a rebuild. */ + if (this->IsNeedRebuildSystemContentMetaDatabase()) { + /* Clean up the system content meta database, to ensure creation can succeed. */ + this->CleanupContentMetaDatabase(StorageId::BuiltInSystem); + + /* Create the content metadatabase. */ + R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); + + /* Rebuild the content meta database. */ + R_TRY(this->BuildContentMetaDatabaseImpl(StorageId::BuiltInSystem)); + } + /* Setup the content meta database for system. */ if (R_FAILED(this->VerifyContentMetaDatabase(StorageId::BuiltInSystem))) { R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); /* Try to build or import a database, depending on our configuration. */ - /* NOTE: To work around a change in save management behavior in 17.0.0+, we build the database if needed. */ - if (manager_config.ShouldBuildDatabase() || hos::GetVersion() >= hos::Version_17_0_0) { + if (manager_config.ShouldBuildDatabase()) { /* If we should build the database, do so. */ R_TRY(this->BuildContentMetaDatabase(StorageId::BuiltInSystem)); R_TRY(this->VerifyContentMetaDatabase(StorageId::BuiltInSystem)); From e8ac23e2ee28213f878a6cf37d0a349e3c8a7a70 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 16 Oct 2023 08:24:07 -0700 Subject: [PATCH 051/238] ncm: fix two comments --- .../libstratosphere/source/ncm/ncm_content_manager_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp index 05c8d90a6..dded90f31 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_manager_impl.cpp @@ -850,7 +850,7 @@ namespace ams::ncm { } ON_SCOPE_EXIT { this->InactivateContentMetaDatabase(StorageId::BuiltInSystem); }; - /* Open the content meta database and storage. */ + /* Open the content meta db. */ ContentMetaDatabase meta_db; R_ABORT_UNLESS(ncm::OpenContentMetaDatabase(std::addressof(meta_db), StorageId::BuiltInSystem)); @@ -978,7 +978,7 @@ namespace ams::ncm { /* Clean up the system content meta database, to ensure creation can succeed. */ this->CleanupContentMetaDatabase(StorageId::BuiltInSystem); - /* Create the content metadatabase. */ + /* Create the content meta database. */ R_TRY(this->CreateContentMetaDatabase(StorageId::BuiltInSystem)); /* Rebuild the content meta database. */ From c866c15856ba252e0168c058dc5bb9d021f46522 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 13 Oct 2023 20:59:36 -0400 Subject: [PATCH 052/238] haze: implement GetObjectPropList --- .../haze/include/haze/ptp_object_heap.hpp | 8 ++ .../haze/include/haze/ptp_responder.hpp | 1 + .../haze/include/haze/ptp_responder_types.hpp | 1 + troposphere/haze/include/haze/results.hpp | 2 + troposphere/haze/source/ptp_responder.cpp | 7 + .../source/ptp_responder_mtp_operations.cpp | 133 +++++++++++++++++- 6 files changed, 149 insertions(+), 3 deletions(-) diff --git a/troposphere/haze/include/haze/ptp_object_heap.hpp b/troposphere/haze/include/haze/ptp_object_heap.hpp index fe1090a32..ac3484e5d 100644 --- a/troposphere/haze/include/haze/ptp_object_heap.hpp +++ b/troposphere/haze/include/haze/ptp_object_heap.hpp @@ -111,6 +111,14 @@ namespace haze { } constexpr void Deallocate(void *p, size_t n) { + /* Check for overflow in alignment. */ + if (!util::CanAddWithoutOverflow(n, alignof(u64) - 1)) { + return; + } + + /* Align the amount to satisfy allocation for u64. */ + n = util::AlignUp(n, alignof(u64)); + /* If the pointer was the last allocation, return the memory to the heap. */ if (static_cast(p) + n == this->GetNextAddress()) { m_next_address = this->GetNextAddress() - n; diff --git a/troposphere/haze/include/haze/ptp_responder.hpp b/troposphere/haze/include/haze/ptp_responder.hpp index 9bd1328e5..8dc996cdd 100644 --- a/troposphere/haze/include/haze/ptp_responder.hpp +++ b/troposphere/haze/include/haze/ptp_responder.hpp @@ -83,6 +83,7 @@ namespace haze { Result GetObjectPropDesc(PtpDataParser &dp); Result GetObjectPropValue(PtpDataParser &dp); Result SetObjectPropValue(PtpDataParser &dp); + Result GetObjectPropList(PtpDataParser &dp); }; } diff --git a/troposphere/haze/include/haze/ptp_responder_types.hpp b/troposphere/haze/include/haze/ptp_responder_types.hpp index d11416437..fd91e6d79 100644 --- a/troposphere/haze/include/haze/ptp_responder_types.hpp +++ b/troposphere/haze/include/haze/ptp_responder_types.hpp @@ -57,6 +57,7 @@ namespace haze { PtpOperationCode_MtpGetObjectPropDesc, PtpOperationCode_MtpGetObjectPropValue, PtpOperationCode_MtpSetObjectPropValue, + PtpOperationCode_MtpGetObjPropList, PtpOperationCode_AndroidGetPartialObject64, PtpOperationCode_AndroidSendPartialObject, PtpOperationCode_AndroidTruncateObject, diff --git a/troposphere/haze/include/haze/results.hpp b/troposphere/haze/include/haze/results.hpp index e8c501ffc..ea3933ddf 100644 --- a/troposphere/haze/include/haze/results.hpp +++ b/troposphere/haze/include/haze/results.hpp @@ -38,5 +38,7 @@ namespace haze { R_DEFINE_ERROR_RESULT(UnknownPropertyCode, 14); R_DEFINE_ERROR_RESULT(InvalidPropertyValue, 15); R_DEFINE_ERROR_RESULT(InvalidArgument, 16); + R_DEFINE_ERROR_RESULT(GroupSpecified, 17); + R_DEFINE_ERROR_RESULT(DepthSpecified, 18); } diff --git a/troposphere/haze/source/ptp_responder.cpp b/troposphere/haze/source/ptp_responder.cpp index ad8d4abb8..8194aaf7b 100644 --- a/troposphere/haze/source/ptp_responder.cpp +++ b/troposphere/haze/source/ptp_responder.cpp @@ -91,6 +91,12 @@ namespace haze { R_CATCH(haze::ResultInvalidPropertyValue) { R_TRY(this->WriteResponse(PtpResponseCode_MtpInvalidObjectPropValue)); } + R_CATCH(haze::ResultGroupSpecified) { + R_TRY(this->WriteResponse(PtpResponseCode_MtpSpecificationByGroupUnsupported)); + } + R_CATCH(haze::ResultDepthSpecified) { + R_TRY(this->WriteResponse(PtpResponseCode_MtpSpecificationByDepthUnsupported)); + } R_CATCH(haze::ResultInvalidArgument) { R_TRY(this->WriteResponse(PtpResponseCode_GeneralError)); } @@ -134,6 +140,7 @@ namespace haze { case PtpOperationCode_MtpGetObjectPropDesc: R_RETURN(this->GetObjectPropDesc(dp)); break; case PtpOperationCode_MtpGetObjectPropValue: R_RETURN(this->GetObjectPropValue(dp)); break; case PtpOperationCode_MtpSetObjectPropValue: R_RETURN(this->SetObjectPropValue(dp)); break; + case PtpOperationCode_MtpGetObjPropList: R_RETURN(this->GetObjectPropList(dp)); break; case PtpOperationCode_AndroidGetPartialObject64: R_RETURN(this->GetPartialObject64(dp)); break; case PtpOperationCode_AndroidSendPartialObject: R_RETURN(this->SendPartialObject(dp)); break; case PtpOperationCode_AndroidTruncateObject: R_RETURN(this->TruncateObject(dp)); break; diff --git a/troposphere/haze/source/ptp_responder_mtp_operations.cpp b/troposphere/haze/source/ptp_responder_mtp_operations.cpp index 973aa98a1..46fc824c2 100644 --- a/troposphere/haze/source/ptp_responder_mtp_operations.cpp +++ b/troposphere/haze/source/ptp_responder_mtp_operations.cpp @@ -113,9 +113,6 @@ namespace haze { R_TRY(dp.Read(std::addressof(property_code))); R_TRY(dp.Finalize()); - /* Disallow renaming the storage root. */ - R_UNLESS(object_id != StorageId_SdmcFs, haze::ResultInvalidObjectId()); - /* Ensure we have a valid property code before continuing. */ R_UNLESS(IsSupportedObjectPropertyCode(property_code), haze::ResultUnknownPropertyCode()); @@ -198,6 +195,136 @@ namespace haze { R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); } + Result PtpResponder::GetObjectPropList(PtpDataParser &dp) { + u32 object_id; + u32 object_format; + s32 property_code; + s32 group_code; + s32 depth; + + R_TRY(dp.Read(std::addressof(object_id))); + R_TRY(dp.Read(std::addressof(object_format))); + R_TRY(dp.Read(std::addressof(property_code))); + R_TRY(dp.Read(std::addressof(group_code))); + R_TRY(dp.Read(std::addressof(depth))); + R_TRY(dp.Finalize()); + + /* Ensure format is unspecified. */ + R_UNLESS(object_format == 0, haze::ResultInvalidArgument()); + + /* Ensure we have a valid property code. */ + R_UNLESS(property_code == -1 || IsSupportedObjectPropertyCode(PtpObjectPropertyCode(property_code)), haze::ResultUnknownPropertyCode()); + + /* Ensure group code is the default. */ + R_UNLESS(group_code == PtpPropertyGroupCode_Default, haze::ResultGroupSpecified()); + + /* Ensure depth is 0. */ + R_UNLESS(depth == 0, haze::ResultDepthSpecified()); + + /* Check if we know about the object. If we don't, it's an error. */ + auto * const obj = m_object_database.GetObjectById(object_id); + R_UNLESS(obj != nullptr, haze::ResultInvalidObjectId()); + + /* Define helper for getting the object type. */ + const auto GetObjectType = [&] (FsDirEntryType *out_entry_type) { + R_RETURN(m_fs.GetEntryType(obj->GetName(), out_entry_type)); + }; + + /* Define helper for getting the object size. */ + const auto GetObjectSize = [&] (s64 *out_size) { + *out_size = 0; + + /* Check if this is a directory. */ + FsDirEntryType entry_type; + R_TRY(GetObjectType(std::addressof(entry_type))); + + /* If it is, we're done. */ + R_SUCCEED_IF(entry_type == FsDirEntryType_Dir); + + /* Otherwise, open as a file. */ + FsFile file; + R_TRY(m_fs.OpenFile(obj->GetName(), FsOpenMode_Read, std::addressof(file))); + + /* Ensure we maintain a clean state on exit. */ + ON_SCOPE_EXIT { m_fs.CloseFile(std::addressof(file)); }; + + R_RETURN(m_fs.GetFileSize(std::addressof(file), out_size)); + }; + + /* Define helper for determining if the property should be included. */ + const auto ShouldIncludeProperty = [&] (PtpObjectPropertyCode code) { + /* If all properties were requested, or it was the requested property, we should include the property. */ + return property_code == -1 || code == property_code; + }; + + /* Begin writing the requested object properties. */ + PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); + + R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + for (const auto obj_property : SupportedObjectProperties) { + if (!ShouldIncludeProperty(obj_property)) { + continue; + } + + /* Write the object handle. */ + R_TRY(db.Add(object_id)); + + /* Write the property code. */ + R_TRY(db.Add(obj_property)); + + /* Write the property value. */ + switch (obj_property) { + case PtpObjectPropertyCode_PersistentUniqueObjectIdentifier: + { + R_TRY(db.Add(PtpDataTypeCode_U128)); + R_TRY(db.Add(object_id)); + } + break; + case PtpObjectPropertyCode_ObjectSize: + { + s64 size; + R_TRY(GetObjectSize(std::addressof(size))); + R_TRY(db.Add(PtpDataTypeCode_U64)); + R_TRY(db.Add(size)); + } + break; + case PtpObjectPropertyCode_StorageId: + { + R_TRY(db.Add(PtpDataTypeCode_U32)); + R_TRY(db.Add(StorageId_SdmcFs)); + } + break; + case PtpObjectPropertyCode_ParentObject: + { + R_TRY(db.Add(PtpDataTypeCode_U32)); + R_TRY(db.Add(obj->GetParentId())); + } + break; + case PtpObjectPropertyCode_ObjectFormat: + { + FsDirEntryType entry_type; + R_TRY(GetObjectType(std::addressof(entry_type))); + R_TRY(db.Add(PtpDataTypeCode_U16)); + R_TRY(db.Add(entry_type == FsDirEntryType_File ? PtpObjectFormatCode_Undefined : PtpObjectFormatCode_Association)); + } + break; + case PtpObjectPropertyCode_ObjectFileName: + { + R_TRY(db.Add(PtpDataTypeCode_String)); + R_TRY(db.AddString(std::strrchr(obj->GetName(), '/') + 1)); + } + break; + HAZE_UNREACHABLE_DEFAULT_CASE(); + } + } + + R_SUCCEED(); + })); + + /* Write the success response. */ + R_RETURN(this->WriteResponse(PtpResponseCode_Ok)); + } + Result PtpResponder::SetObjectPropValue(PtpDataParser &rdp) { u32 object_id; PtpObjectPropertyCode property_code; From d9fff85bc4a3d5fa18e14d41ff853d0c16681b77 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 13 Oct 2023 21:44:52 -0400 Subject: [PATCH 053/238] haze: use gpu console for rendering --- troposphere/haze/Makefile | 58 ++- .../haze/include/haze/console_main_loop.hpp | 2 +- troposphere/haze/source/console_fsh.glsl | 15 + troposphere/haze/source/console_vsh.glsl | 35 ++ troposphere/haze/source/gpu_console.c | 487 ++++++++++++++++++ troposphere/haze/source/ptp_object_heap.cpp | 4 +- 6 files changed, 592 insertions(+), 9 deletions(-) create mode 100644 troposphere/haze/source/console_fsh.glsl create mode 100644 troposphere/haze/source/console_vsh.glsl create mode 100644 troposphere/haze/source/gpu_console.c diff --git a/troposphere/haze/Makefile b/troposphere/haze/Makefile index f80a28a07..b6d12ea14 100644 --- a/troposphere/haze/Makefile +++ b/troposphere/haze/Makefile @@ -42,7 +42,10 @@ BUILD := build SOURCES := source DATA := data INCLUDES := include ../../libraries/libvapours/include -#ROMFS := romfs +ROMFS := romfs + +# Output folders for autogenerated files in romfs +OUT_SHADERS := shaders APP_TITLE := USB File Transfer APP_AUTHOR := Atmosphere-NX @@ -63,7 +66,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++20 ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -LIBS := -lnx +LIBS := -ldeko3d -lnx -lm #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing @@ -90,6 +93,7 @@ export DEPSDIR := $(CURDIR)/$(BUILD) CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +GLSLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.glsl))) BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- @@ -155,19 +159,61 @@ ifneq ($(APP_TITLEID),) export NACPFLAGS += --titleid=$(APP_TITLEID) endif -ifneq ($(ROMFS),) +ifneq ($(strip $(ROMFS)),) + ROMFS_TARGETS := + ROMFS_FOLDERS := + ifneq ($(strip $(OUT_SHADERS)),) + ROMFS_SHADERS := $(ROMFS)/$(OUT_SHADERS) + ROMFS_TARGETS += $(patsubst %.glsl, $(ROMFS_SHADERS)/%.dksh, $(GLSLFILES)) + ROMFS_FOLDERS += $(ROMFS_SHADERS) + endif + + export ROMFS_DEPS := $(foreach file,$(ROMFS_TARGETS),$(CURDIR)/$(file)) export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS) endif .PHONY: $(BUILD) clean all #--------------------------------------------------------------------------------- -all: $(BUILD) +all: $(ROMFS_TARGETS) | $(BUILD) $(BUILD): @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile +ifneq ($(strip $(ROMFS_TARGETS)),) + +$(ROMFS_TARGETS): | $(ROMFS_FOLDERS) + +$(ROMFS_FOLDERS): + @mkdir -p $@ + +$(ROMFS_SHADERS)/%_vsh.dksh: %_vsh.glsl + @echo {vert} $(notdir $<) + @uam -s vert -o $@ $< + +$(ROMFS_SHADERS)/%_tcsh.dksh: %_tcsh.glsl + @echo {tess_ctrl} $(notdir $<) + @uam -s tess_ctrl -o $@ $< + +$(ROMFS_SHADERS)/%_tesh.dksh: %_tesh.glsl + @echo {tess_eval} $(notdir $<) + @uam -s tess_eval -o $@ $< + +$(ROMFS_SHADERS)/%_gsh.dksh: %_gsh.glsl + @echo {geom} $(notdir $<) + @uam -s geom -o $@ $< + +$(ROMFS_SHADERS)/%_fsh.dksh: %_fsh.glsl + @echo {frag} $(notdir $<) + @uam -s frag -o $@ $< + +$(ROMFS_SHADERS)/%.dksh: %.glsl + @echo {comp} $(notdir $<) + @uam -s comp -o $@ $< + +endif + #--------------------------------------------------------------------------------- clean: @echo clean ... @@ -192,9 +238,9 @@ ifeq ($(strip $(APP_JSON)),) all : $(OUTPUT).nro ifeq ($(strip $(NO_NACP)),) -$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp +$(OUTPUT).nro : $(OUTPUT).elf $(OUTPUT).nacp $(ROMFS_DEPS) else -$(OUTPUT).nro : $(OUTPUT).elf +$(OUTPUT).nro : $(OUTPUT).elf $(ROMFS_DEPS) endif else diff --git a/troposphere/haze/include/haze/console_main_loop.hpp b/troposphere/haze/include/haze/console_main_loop.hpp index b91281615..184c36fc6 100644 --- a/troposphere/haze/include/haze/console_main_loop.hpp +++ b/troposphere/haze/include/haze/console_main_loop.hpp @@ -143,7 +143,7 @@ namespace haze { if (m_is_applet_mode) { /* Print "Applet Mode" in red text. */ - printf("\n" CONSOLE_ESC(38;5;196m) "Applet Mode" CONSOLE_ESC(0m) "\n"); + printf("\n" CONSOLE_ESC(31;1m) "Applet Mode" CONSOLE_ESC(0m) "\n"); } consoleUpdate(nullptr); diff --git a/troposphere/haze/source/console_fsh.glsl b/troposphere/haze/source/console_fsh.glsl new file mode 100644 index 000000000..2875883ed --- /dev/null +++ b/troposphere/haze/source/console_fsh.glsl @@ -0,0 +1,15 @@ +#version 460 + +layout (location = 0) noperspective in vec3 inTexCoord; +layout (location = 1) flat in vec4 inFrontPal; +layout (location = 2) flat in vec4 inBackPal; + +layout (location = 0) out vec4 outColor; + +layout (binding = 0) uniform sampler2DArray tileset; + +void main() +{ + float value = texture(tileset, inTexCoord).r; + outColor = mix(inBackPal, inFrontPal, value); +} diff --git a/troposphere/haze/source/console_vsh.glsl b/troposphere/haze/source/console_vsh.glsl new file mode 100644 index 000000000..59a5b79a2 --- /dev/null +++ b/troposphere/haze/source/console_vsh.glsl @@ -0,0 +1,35 @@ +#version 460 + +layout (location = 0) in float inTileId; +layout (location = 1) in uvec2 inColorId; + +layout (location = 0) out vec3 outTexCoord; +layout (location = 1) out vec4 outFrontPal; +layout (location = 2) out vec4 outBackPal; + +layout (std140, binding = 0) uniform Config +{ + vec4 dimensions; + vec4 vertices[3]; + vec4 palettes[24]; +} u; + +void main() +{ + float id = float(gl_InstanceID); + float tileRow = floor(id / u.dimensions.z); + float tileCol = id - tileRow * u.dimensions.z; + + vec2 basePos; + basePos.x = 2.0 * (tileCol + 0.5) / u.dimensions.z - 1.0; + basePos.y = 2.0 * (1.0 - (tileRow + 0.5) / u.dimensions.w) - 1.0; + + vec2 vtxData = u.vertices[gl_VertexID].xy; + vec2 scale = vec2(1.0) / u.dimensions.zw; + gl_Position.xy = vtxData * scale + basePos; + gl_Position.zw = vec2(0.5, 1.0); + + outTexCoord = vec3(u.vertices[gl_VertexID].zw, inTileId); + outFrontPal = u.palettes[inColorId.x]; + outBackPal = u.palettes[inColorId.y]; +} diff --git a/troposphere/haze/source/gpu_console.c b/troposphere/haze/source/gpu_console.c new file mode 100644 index 000000000..cbfe62872 --- /dev/null +++ b/troposphere/haze/source/gpu_console.c @@ -0,0 +1,487 @@ +#include +#include +#include +#include + +#include +#include + +// Define the desired number of framebuffers +#define FB_NUM 2 + +// Define the size of the memory block that will hold code +#define CODEMEMSIZE (64*1024) + +// Define the size of the memory block that will hold command lists +#define CMDMEMSIZE (64*1024) + +#define NUM_IMAGE_SLOTS 1 +#define NUM_SAMPLER_SLOTS 1 + +typedef struct { + float pos[2]; + float tex[2]; +} VertexDef; + +typedef struct { + float red; + float green; + float blue; + float alpha; +} PaletteColor; + +typedef struct { + float dimensions[4]; + VertexDef vertices[3]; + PaletteColor palettes[24]; +} ConsoleConfig; + +static const VertexDef g_vertexData[3] = { + { { 0.0f, +1.0f }, { 0.5f, 0.0f, } }, + { { -1.0f, -1.0f }, { 0.0f, 1.0f, } }, + { { +1.0f, -1.0f }, { 1.0f, 1.0f, } }, +}; + +static const PaletteColor g_paletteData[24] = { + { 0.0f, 0.0f, 0.0f, 0.0f }, // black + { 0.5f, 0.0f, 0.0f, 1.0f }, // red + { 0.0f, 0.5f, 0.0f, 1.0f }, // green + { 0.5f, 0.5f, 0.0f, 1.0f }, // yellow + { 0.0f, 0.0f, 0.5f, 1.0f }, // blue + { 0.5f, 0.0f, 0.5f, 1.0f }, // magenta + { 0.0f, 0.5f, 0.5f, 1.0f }, // cyan + { 0.75f, 0.75f, 0.75f, 1.0f }, // white + + { 0.5f, 0.5f, 0.5f, 1.0f }, // bright black + { 1.0f, 0.0f, 0.0f, 1.0f }, // bright red + { 0.0f, 1.0f, 0.0f, 1.0f }, // bright green + { 1.0f, 1.0f, 0.0f, 1.0f }, // bright yellow + { 0.0f, 0.0f, 1.0f, 1.0f }, // bright blue + { 1.0f, 0.0f, 1.0f, 1.0f }, // bright magenta + { 0.0f, 1.0f, 1.0f, 1.0f }, // bright cyan + { 1.0f, 1.0f, 1.0f, 1.0f }, // bright white + + { 0.0f, 0.0f, 0.0f, 0.0f }, // faint black + { 0.25f, 0.0f, 0.0f, 1.0f }, // faint red + { 0.0f, 0.25f, 0.0f, 1.0f }, // faint green + { 0.25f, 0.25f, 0.0f, 1.0f }, // faint yellow + { 0.0f, 0.0f, 0.25f, 1.0f }, // faint blue + { 0.25f, 0.0f, 0.25f, 1.0f }, // faint magenta + { 0.0f, 0.25f, 0.25f, 1.0f }, // faint cyan + { 0.375f, 0.375f, 0.375f, 1.0f }, // faint white +}; + +typedef struct { + uint16_t tileId; + uint8_t frontPal; + uint8_t backPal; +} ConsoleChar; + +static const DkVtxAttribState g_attribState[] = { + { .bufferId=0, .isFixed=0, .offset=offsetof(ConsoleChar,tileId), .size=DkVtxAttribSize_1x16, .type=DkVtxAttribType_Uscaled, .isBgra=0 }, + { .bufferId=0, .isFixed=0, .offset=offsetof(ConsoleChar,frontPal), .size=DkVtxAttribSize_2x8, .type=DkVtxAttribType_Uint, .isBgra=0 }, +}; + +static const DkVtxBufferState g_vtxbufState[] = { + { .stride=sizeof(ConsoleChar), .divisor=1 }, +}; + +struct GpuRenderer { + ConsoleRenderer base; + + bool initialized; + + DkDevice device; + DkQueue queue; + + DkMemBlock imageMemBlock; + DkMemBlock codeMemBlock; + DkMemBlock dataMemBlock; + + DkSwapchain swapchain; + DkImage framebuffers[FB_NUM]; + DkImage tileset; + ConsoleChar* charBuf; + + uint32_t codeMemOffset; + DkShader vertexShader; + DkShader fragmentShader; + + DkCmdBuf cmdbuf; + DkCmdList cmdsBindFramebuffer[FB_NUM]; + DkCmdList cmdsRender; + + DkFence lastRenderFence; +}; + +static struct GpuRenderer* GpuRenderer(PrintConsole* con) +{ + return (struct GpuRenderer*)con->renderer; +} + +static void GpuRenderer_destroy(struct GpuRenderer* r) +{ + // Make sure the queue is idle before destroying anything + dkQueueWaitIdle(r->queue); + + // Destroy all the resources we've created + dkQueueDestroy(r->queue); + dkCmdBufDestroy(r->cmdbuf); + dkSwapchainDestroy(r->swapchain); + dkMemBlockDestroy(r->dataMemBlock); + dkMemBlockDestroy(r->codeMemBlock); + dkMemBlockDestroy(r->imageMemBlock); + dkDeviceDestroy(r->device); + + // Clear out all state + memset(&r->initialized, 0, sizeof(*r) - offsetof(struct GpuRenderer, initialized)); +} + +// Simple function for loading a shader from the filesystem +static void GpuRenderer_loadShader(struct GpuRenderer* r, DkShader* pShader, const char* path) +{ + // Open the file, and retrieve its size + FILE* f = fopen(path, "rb"); + fseek(f, 0, SEEK_END); + uint32_t size = ftell(f); + rewind(f); + + // Look for a spot in the code memory block for loading this shader. Note that + // we are just using a simple incremental offset; this isn't a general purpose + // allocation algorithm. + uint32_t codeOffset = r->codeMemOffset; + r->codeMemOffset += (size + DK_SHADER_CODE_ALIGNMENT - 1) &~ (DK_SHADER_CODE_ALIGNMENT - 1); + + // Read the file into memory, and close the file + fread((uint8_t*)dkMemBlockGetCpuAddr(r->codeMemBlock) + codeOffset, size, 1, f); + fclose(f); + + // Initialize the user provided shader object with the code we've just loaded + DkShaderMaker shaderMaker; + dkShaderMakerDefaults(&shaderMaker, r->codeMemBlock, codeOffset); + dkShaderInitialize(pShader, &shaderMaker); +} + +static bool GpuRenderer_init(PrintConsole* con) +{ + struct GpuRenderer* r = GpuRenderer(con); + + if (r->initialized) { + // We're already initialized + return true; + } + + // Create the deko3d device, which is the root object + DkDeviceMaker deviceMaker; + dkDeviceMakerDefaults(&deviceMaker); + r->device = dkDeviceCreate(&deviceMaker); + + // Create the queue + DkQueueMaker queueMaker; + dkQueueMakerDefaults(&queueMaker, r->device); + queueMaker.flags = DkQueueFlags_Graphics; + r->queue = dkQueueCreate(&queueMaker); + + // Calculate required width/height for the framebuffers + u32 width = con->font.tileWidth * con->consoleWidth; + u32 height = con->font.tileHeight * con->consoleHeight; + u32 totalConSize = con->consoleWidth * con->consoleHeight; + + // Calculate layout for the framebuffers + DkImageLayoutMaker imageLayoutMaker; + dkImageLayoutMakerDefaults(&imageLayoutMaker, r->device); + imageLayoutMaker.flags = DkImageFlags_UsageRender | DkImageFlags_UsagePresent | DkImageFlags_HwCompression; + imageLayoutMaker.format = DkImageFormat_RGBA8_Unorm; + imageLayoutMaker.dimensions[0] = width; + imageLayoutMaker.dimensions[1] = height; + + // Calculate layout for the framebuffers + DkImageLayout framebufferLayout; + dkImageLayoutInitialize(&framebufferLayout, &imageLayoutMaker); + + // Calculate layout for the tileset + dkImageLayoutMakerDefaults(&imageLayoutMaker, r->device); + imageLayoutMaker.type = DkImageType_2DArray; + imageLayoutMaker.format = DkImageFormat_R32_Float; + imageLayoutMaker.dimensions[0] = con->font.tileWidth; + imageLayoutMaker.dimensions[1] = con->font.tileHeight; + imageLayoutMaker.dimensions[2] = con->font.numChars; + + // Calculate layout for the tileset + DkImageLayout tilesetLayout; + dkImageLayoutInitialize(&tilesetLayout, &imageLayoutMaker); + + // Retrieve necessary size and alignment for the framebuffers + uint32_t framebufferSize = dkImageLayoutGetSize(&framebufferLayout); + uint32_t framebufferAlign = dkImageLayoutGetAlignment(&framebufferLayout); + framebufferSize = (framebufferSize + framebufferAlign - 1) &~ (framebufferAlign - 1); + + // Retrieve necessary size and alignment for the tileset + uint32_t tilesetSize = dkImageLayoutGetSize(&tilesetLayout); + uint32_t tilesetAlign = dkImageLayoutGetAlignment(&tilesetLayout); + tilesetSize = (tilesetSize + tilesetAlign - 1) &~ (tilesetAlign - 1); + + // Create a memory block that will host the framebuffers and the tileset + DkMemBlockMaker memBlockMaker; + dkMemBlockMakerDefaults(&memBlockMaker, r->device, FB_NUM*framebufferSize + tilesetSize); + memBlockMaker.flags = DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image; + r->imageMemBlock = dkMemBlockCreate(&memBlockMaker); + + // Initialize the framebuffers with the layout and backing memory we've just created + DkImage const* swapchainImages[FB_NUM]; + for (unsigned i = 0; i < FB_NUM; i ++) { + swapchainImages[i] = &r->framebuffers[i]; + dkImageInitialize(&r->framebuffers[i], &framebufferLayout, r->imageMemBlock, i*framebufferSize); + } + + // Create a swapchain out of the framebuffers we've just initialized + DkSwapchainMaker swapchainMaker; + dkSwapchainMakerDefaults(&swapchainMaker, r->device, nwindowGetDefault(), swapchainImages, FB_NUM); + r->swapchain = dkSwapchainCreate(&swapchainMaker); + + // Initialize the tileset + dkImageInitialize(&r->tileset, &tilesetLayout, r->imageMemBlock, FB_NUM*framebufferSize); + + // Create a memory block onto which we will load shader code + dkMemBlockMakerDefaults(&memBlockMaker, r->device, CODEMEMSIZE); + memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached | DkMemBlockFlags_Code; + r->codeMemBlock = dkMemBlockCreate(&memBlockMaker); + r->codeMemOffset = 0; + + // Load our shaders (both vertex and fragment) + romfsInit(); + GpuRenderer_loadShader(r, &r->vertexShader, "romfs:/shaders/console_vsh.dksh"); + GpuRenderer_loadShader(r, &r->fragmentShader, "romfs:/shaders/console_fsh.dksh"); + + // Generate the descriptors + struct { + DkImageDescriptor images[NUM_IMAGE_SLOTS]; + DkSamplerDescriptor samplers[NUM_SAMPLER_SLOTS]; + } descriptors; + + // Generate a image descriptor for the tileset + DkImageView tilesetView; + dkImageViewDefaults(&tilesetView, &r->tileset); + dkImageDescriptorInitialize(&descriptors.images[0], &tilesetView, false, false); + + // Generate a sampler descriptor for the tileset + DkSampler sampler; + dkSamplerDefaults(&sampler); + sampler.wrapMode[0] = DkWrapMode_ClampToEdge; + sampler.wrapMode[1] = DkWrapMode_ClampToEdge; + sampler.minFilter = DkFilter_Nearest; + sampler.magFilter = DkFilter_Nearest; + dkSamplerDescriptorInitialize(&descriptors.samplers[0], &sampler); + + uint32_t descriptorsOffset = CMDMEMSIZE; + uint32_t configOffset = (descriptorsOffset + sizeof(descriptors) + DK_UNIFORM_BUF_ALIGNMENT - 1) &~ (DK_UNIFORM_BUF_ALIGNMENT - 1); + uint32_t configSize = (sizeof(ConsoleConfig) + DK_UNIFORM_BUF_ALIGNMENT - 1) &~ (DK_UNIFORM_BUF_ALIGNMENT - 1); + + uint32_t charBufOffset = configOffset + configSize; + uint32_t charBufSize = totalConSize * sizeof(ConsoleChar); + + // Create a memory block which will be used for recording command lists using a command buffer + dkMemBlockMakerDefaults(&memBlockMaker, r->device, + (charBufOffset + charBufSize + DK_MEMBLOCK_ALIGNMENT - 1) &~ (DK_MEMBLOCK_ALIGNMENT - 1) + ); + memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached; + r->dataMemBlock = dkMemBlockCreate(&memBlockMaker); + + // Create a command buffer object + DkCmdBufMaker cmdbufMaker; + dkCmdBufMakerDefaults(&cmdbufMaker, r->device); + r->cmdbuf = dkCmdBufCreate(&cmdbufMaker); + + // Feed our memory to the command buffer so that we can start recording commands + dkCmdBufAddMemory(r->cmdbuf, r->dataMemBlock, 0, CMDMEMSIZE); + + // Create a temporary buffer that will hold the tileset + dkMemBlockMakerDefaults(&memBlockMaker, r->device, + (sizeof(float)*con->font.tileWidth*con->font.tileHeight*con->font.numChars + DK_MEMBLOCK_ALIGNMENT - 1) &~ (DK_MEMBLOCK_ALIGNMENT - 1) + ); + memBlockMaker.flags = DkMemBlockFlags_CpuUncached | DkMemBlockFlags_GpuCached; + DkMemBlock scratchMemBlock = dkMemBlockCreate(&memBlockMaker); + float* scratchMem = (float*)dkMemBlockGetCpuAddr(scratchMemBlock); + + // Unpack 1bpp tileset into a texture image the GPU can read + unsigned packedTileWidth = (con->font.tileWidth+7)/8; + for (unsigned tile = 0; tile < con->font.numChars; tile ++) { + const uint8_t* data = (const uint8_t*)con->font.gfx + con->font.tileHeight*packedTileWidth*tile; + for (unsigned y = 0; y < con->font.tileHeight; y ++) { + const uint8_t* row = &data[packedTileWidth*(y+1)]; + uint8_t c = 0; + for (unsigned x = 0; x < con->font.tileWidth; x ++) { + if (!(x & 7)) + c = *--row; + *scratchMem++ = (c & 0x80) ? 1.0f : 0.0f; + c <<= 1; + } + } + } + + // Set up configuration + DkGpuAddr configAddr = dkMemBlockGetGpuAddr(r->dataMemBlock) + configOffset; + ConsoleConfig consoleConfig = {}; + consoleConfig.dimensions[0] = width; + consoleConfig.dimensions[1] = height; + consoleConfig.dimensions[2] = con->consoleWidth; + consoleConfig.dimensions[3] = con->consoleHeight; + memcpy(consoleConfig.vertices, g_vertexData, sizeof(g_vertexData)); + memcpy(consoleConfig.palettes, g_paletteData, sizeof(g_paletteData)); + + // Generate a temporary command list for uploading stuff and run it + DkGpuAddr descriptorSet = dkMemBlockGetGpuAddr(r->dataMemBlock) + descriptorsOffset; + DkCopyBuf copySrc = { dkMemBlockGetGpuAddr(scratchMemBlock), 0, 0 }; + DkImageRect copyDst = { 0, 0, 0, con->font.tileWidth, con->font.tileHeight, con->font.numChars }; + dkCmdBufPushData(r->cmdbuf, descriptorSet, &descriptors, sizeof(descriptors)); + dkCmdBufPushConstants(r->cmdbuf, configAddr, configSize, 0, sizeof(consoleConfig), &consoleConfig); + dkCmdBufBindImageDescriptorSet(r->cmdbuf, descriptorSet, NUM_IMAGE_SLOTS); + dkCmdBufBindSamplerDescriptorSet(r->cmdbuf, descriptorSet + NUM_IMAGE_SLOTS*sizeof(DkImageDescriptor), NUM_SAMPLER_SLOTS); + dkCmdBufCopyBufferToImage(r->cmdbuf, ©Src, &tilesetView, ©Dst, 0); + dkQueueSubmitCommands(r->queue, dkCmdBufFinishList(r->cmdbuf)); + dkQueueFlush(r->queue); + dkQueueWaitIdle(r->queue); + dkCmdBufClear(r->cmdbuf); + + // Destroy the scratch memory block since we don't need it anymore + dkMemBlockDestroy(scratchMemBlock); + + // Retrieve the address of the character buffer + DkGpuAddr charBufAddr = dkMemBlockGetGpuAddr(r->dataMemBlock) + charBufOffset; + r->charBuf = (ConsoleChar*)((uint8_t*)dkMemBlockGetCpuAddr(r->dataMemBlock) + charBufOffset); + memset(r->charBuf, 0, charBufSize); + + // Generate a command list for each framebuffer, which will bind each of them as a render target + for (unsigned i = 0; i < FB_NUM; i ++) { + DkImageView imageView; + dkImageViewDefaults(&imageView, &r->framebuffers[i]); + dkCmdBufBindRenderTarget(r->cmdbuf, &imageView, NULL); + r->cmdsBindFramebuffer[i] = dkCmdBufFinishList(r->cmdbuf); + } + + // Declare structs that will be used for binding state + DkViewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f }; + DkScissor scissor = { 0, 0, width, height }; + DkShader const* shaders[] = { &r->vertexShader, &r->fragmentShader }; + DkRasterizerState rasterizerState; + DkColorState colorState; + DkColorWriteState colorWriteState; + + // Initialize state structs with the deko3d defaults + dkRasterizerStateDefaults(&rasterizerState); + dkColorStateDefaults(&colorState); + dkColorWriteStateDefaults(&colorWriteState); + + rasterizerState.fillRectangleEnable = true; + colorState.alphaCompareOp = DkCompareOp_Greater; + + // Generate the main rendering command list + dkCmdBufSetViewports(r->cmdbuf, 0, &viewport, 1); + dkCmdBufSetScissors(r->cmdbuf, 0, &scissor, 1); + //dkCmdBufClearColorFloat(r->cmdbuf, 0, DkColorMask_RGBA, 0.125f, 0.294f, 0.478f, 0.0f); + dkCmdBufClearColorFloat(r->cmdbuf, 0, DkColorMask_RGBA, 0.0f, 0.0f, 0.0f, 0.0f); + dkCmdBufBindShaders(r->cmdbuf, DkStageFlag_GraphicsMask, shaders, sizeof(shaders)/sizeof(shaders[0])); + dkCmdBufBindRasterizerState(r->cmdbuf, &rasterizerState); + dkCmdBufBindColorState(r->cmdbuf, &colorState); + dkCmdBufBindColorWriteState(r->cmdbuf, &colorWriteState); + dkCmdBufBindUniformBuffer(r->cmdbuf, DkStage_Vertex, 0, configAddr, configSize); + dkCmdBufBindTexture(r->cmdbuf, DkStage_Fragment, 0, dkMakeTextureHandle(0, 0)); + dkCmdBufBindVtxAttribState(r->cmdbuf, g_attribState, sizeof(g_attribState)/sizeof(g_attribState[0])); + dkCmdBufBindVtxBufferState(r->cmdbuf, g_vtxbufState, sizeof(g_vtxbufState)/sizeof(g_vtxbufState[0])); + dkCmdBufBindVtxBuffer(r->cmdbuf, 0, charBufAddr, charBufSize); + dkCmdBufSetAlphaRef(r->cmdbuf, 0.0f); + dkCmdBufDraw(r->cmdbuf, DkPrimitive_Triangles, 3, totalConSize, 0, 0); + r->cmdsRender = dkCmdBufFinishList(r->cmdbuf); + + r->initialized = true; + return true; +} + +static void GpuRenderer_deinit(PrintConsole* con) +{ + struct GpuRenderer* r = GpuRenderer(con); + + if (r->initialized) { + GpuRenderer_destroy(r); + } +} + +static void GpuRenderer_drawChar(PrintConsole* con, int x, int y, int c) +{ + struct GpuRenderer* r = GpuRenderer(con); + + int writingColor = con->fg; + int screenColor = con->bg; + + if (con->flags & CONSOLE_COLOR_BOLD) { + writingColor += 8; + } else if (con->flags & CONSOLE_COLOR_FAINT) { + writingColor += 16; + } + + if (con->flags & CONSOLE_COLOR_REVERSE) { + int tmp = writingColor; + writingColor = screenColor; + screenColor = tmp; + } + + // Wait for the fence + dkFenceWait(&r->lastRenderFence, UINT64_MAX); + + ConsoleChar* pos = &r->charBuf[y*con->consoleWidth+x]; + pos->tileId = c; + pos->frontPal = writingColor; + pos->backPal = screenColor; +} + +static void GpuRenderer_scrollWindow(PrintConsole* con) +{ + struct GpuRenderer* r = GpuRenderer(con); + + // Wait for the fence + dkFenceWait(&r->lastRenderFence, UINT64_MAX); + + // Perform the scrolling + for (int y = 0; y < con->windowHeight-1; y ++) { + memcpy( + &r->charBuf[(con->windowY+y+0)*con->consoleWidth + con->windowX], + &r->charBuf[(con->windowY+y+1)*con->consoleWidth + con->windowX], + sizeof(ConsoleChar)*con->windowWidth); + } +} + +static void GpuRenderer_flushAndSwap(PrintConsole* con) +{ + struct GpuRenderer* r = GpuRenderer(con); + + // Acquire a framebuffer from the swapchain (and wait for it to be available) + int slot = dkQueueAcquireImage(r->queue, r->swapchain); + + // Run the command list that binds said framebuffer as a render target + dkQueueSubmitCommands(r->queue, r->cmdsBindFramebuffer[slot]); + + // Run the main rendering command list + dkQueueSubmitCommands(r->queue, r->cmdsRender); + + // Signal the fence + dkQueueSignalFence(r->queue, &r->lastRenderFence, false); + + // Now that we are done rendering, present it to the screen + dkQueuePresentImage(r->queue, r->swapchain, slot); +} + +static struct GpuRenderer s_gpuRenderer = +{ + { + GpuRenderer_init, + GpuRenderer_deinit, + GpuRenderer_drawChar, + GpuRenderer_scrollWindow, + GpuRenderer_flushAndSwap, + } +}; + +ConsoleRenderer* getDefaultConsoleRenderer(void) +{ + return &s_gpuRenderer.base; +} diff --git a/troposphere/haze/source/ptp_object_heap.cpp b/troposphere/haze/source/ptp_object_heap.cpp index 2157b59c5..c3d947342 100644 --- a/troposphere/haze/source/ptp_object_heap.cpp +++ b/troposphere/haze/source/ptp_object_heap.cpp @@ -19,8 +19,8 @@ namespace haze { namespace { - /* Allow 20MiB for use by libnx. */ - static constexpr size_t LibnxReservedMemorySize = 20_MB; + /* Allow 30MiB for use by libnx. */ + static constexpr size_t LibnxReservedMemorySize = 30_MB; } From 0ff197b300c08199704d2d9d062606a825b6c856 Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 13 Oct 2023 23:12:47 -0400 Subject: [PATCH 054/238] haze: fix bMaxPacketSize0 --- troposphere/haze/source/usb_session.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/troposphere/haze/source/usb_session.cpp b/troposphere/haze/source/usb_session.cpp index 3c0244f5f..581edf199 100644 --- a/troposphere/haze/source/usb_session.cpp +++ b/troposphere/haze/source/usb_session.cpp @@ -191,6 +191,7 @@ namespace haze { R_TRY(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_High, std::addressof(device_descriptor))); device_descriptor.bcdUSB = 0x0300; + device_descriptor.bMaxPacketSize0 = 0x09; R_TRY(usbDsSetUsbDeviceDescriptor(UsbDeviceSpeed_Super, std::addressof(device_descriptor))); /* Binary Object Store */ From 7650c5eb96d2a03fc9cc50887e5b78f911a27a28 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 16 Oct 2023 12:30:11 -0700 Subject: [PATCH 055/238] docs: add changelog for 1.6.1 --- docs/changelog.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index a46f2a4ac..d379849ff 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,13 @@ # Changelog +## 1.6.1 ++ An improved solution to [the problem that would cause consoles which had previously re-built their SYSTEM partition to brick on update-to-17.0.0](https://gist.github.com/SciresM/2ddb708c812ed585c4d99f54e25205ff) was added. + + In particular, booting atmosphère will now automatically detect the problem and unbrick any consoles which have fallen into this state. ++ Some improvements were made to `haze`, including: + + Performance was greatly improved: + + Support was added for GetObjectPropList, which decreases the amount of requests made by ~8x. + + Haze now performs rendering on the GPU, freeing up the CPU to respond to requests in a more timely manner. + + An issue was fixed with how `haze` configures `bMaxPacketSize0` which improves support for USB3. ++ General system stability improvements to enhance the user's experience. ## 1.6.0 + Basic support was added for 17.0.0. + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. From 183f3e0d7e0c620d213be53c66d9156f55389be2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 16 Oct 2023 12:30:35 -0700 Subject: [PATCH 056/238] ams: bump version to 1.6.1 --- libraries/libvapours/include/vapours/ams/ams_api_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 8b963d6d3..243e0df39 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -17,7 +17,7 @@ #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #define ATMOSPHERE_RELEASE_VERSION_MINOR 6 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO From edb4e2ea56f154d0a8132c8749ac798c060a66a6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 16 Oct 2023 12:31:15 -0700 Subject: [PATCH 057/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "965e05b3c" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "965e05b3c" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 328a6aea8..d2c6e746a 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 132558c33865f6a21f06caa31bdfc6b1f92bd9b2 - parent = d389ef639ed2988325523f1d95f90030a3370541 + commit = 965e05b3cc5ea74de7e3071c3554135e828ce42e + parent = 183f3e0d7e0c620d213be53c66d9156f55389be2 method = merge cmdver = 0.4.1 From 7f4450f930d9bc141c777e32fd1c6ec5cbfef6e8 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 16 Oct 2023 17:31:09 -0400 Subject: [PATCH 058/238] haze: pretend to be able to write MTP server code --- .../haze/source/ptp_responder_mtp_operations.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/troposphere/haze/source/ptp_responder_mtp_operations.cpp b/troposphere/haze/source/ptp_responder_mtp_operations.cpp index 46fc824c2..eea3e5f4f 100644 --- a/troposphere/haze/source/ptp_responder_mtp_operations.cpp +++ b/troposphere/haze/source/ptp_responder_mtp_operations.cpp @@ -257,10 +257,21 @@ namespace haze { return property_code == -1 || code == property_code; }; + /* Determine how many output elements we will report. */ + u32 num_output_elements = 0; + for (const auto obj_property : SupportedObjectProperties) { + if (ShouldIncludeProperty(obj_property)) { + num_output_elements++; + } + } + /* Begin writing the requested object properties. */ PtpDataBuilder db(m_buffers->usb_bulk_write_buffer, std::addressof(m_usb_server)); R_TRY(db.WriteVariableLengthData(m_request_header, [&] { + /* Report the number of elements. */ + R_TRY(db.Add(num_output_elements)); + for (const auto obj_property : SupportedObjectProperties) { if (!ShouldIncludeProperty(obj_property)) { continue; From c44da848694aa6594dd39698865395a2c7f4e395 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 17 Oct 2023 11:10:09 -0700 Subject: [PATCH 059/238] pm: adjust resource limit function names --- .../stratosphere/pm/impl/pm_debug_monitor_interface.hpp | 2 +- .../stratosphere/pm/impl/pm_information_interface.hpp | 4 ++-- .../include/stratosphere/pm/pm_info_api.hpp | 4 ++-- .../libstratosphere/include/stratosphere/pm/pm_types.hpp | 2 +- libraries/libstratosphere/source/pm/pm_info_api.cpp | 8 ++++---- stratosphere/pm/source/impl/pm_process_manager.cpp | 8 ++++---- stratosphere/pm/source/impl/pm_process_manager.hpp | 4 ++-- stratosphere/pm/source/impl/pm_resource_manager.cpp | 8 ++++---- stratosphere/pm/source/impl/pm_resource_manager.hpp | 6 +++--- stratosphere/pm/source/pm_info_service.cpp | 8 ++++---- stratosphere/pm/source/pm_info_service.hpp | 4 ++-- 11 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp index f9e063baa..7c9676f86 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_debug_monitor_interface.hpp @@ -27,7 +27,7 @@ AMS_SF_METHOD_INFO(C, H, 4, Result, GetApplicationProcessId, (sf::Out out), (out)) \ AMS_SF_METHOD_INFO(C, H, 5, Result, HookToCreateApplicationProcess, (sf::OutCopyHandle out_hook), (out_hook)) \ AMS_SF_METHOD_INFO(C, H, 6, Result, ClearHook, (u32 which), (which), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereGetProcessInfo, (sf::OutCopyHandle out_process_handle, sf::Out out_loc, sf::Out out_status, os::ProcessId process_id), (out_process_handle, out_loc, out_status, process_id)) \ AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetCurrentLimitInfo, (sf::Out out_cur_val, sf::Out out_lim_val, u32 group, u32 resource), (out_cur_val, out_lim_val, group, resource)) diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp index 35f5d7089..6eeda3216 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_information_interface.hpp @@ -21,8 +21,8 @@ #define AMS_PM_I_INFORMATION_INTERFACE_INTERFACE_INFO(C, H) \ AMS_SF_METHOD_INFO(C, H, 0, Result, GetProgramId, (sf::Out out, os::ProcessId process_id), (out, process_id)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetAppletCurrentResourceLimitValues, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, GetAppletPeakResourceLimitValues, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetAppletResourceLimitCurrentValue, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, GetAppletResourceLimitPeakValue, (sf::Out out), (out)) \ AMS_SF_METHOD_INFO(C, H, 65000, Result, AtmosphereGetProcessId, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmosphereGetProcessInfo, (sf::Out out_loc, sf::Out out_status, os::ProcessId process_id), (out_loc, out_status, process_id)) diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp index c771eb33f..484c4fa7e 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_info_api.hpp @@ -29,8 +29,8 @@ namespace ams::pm::info { Result GetProcessId(os::ProcessId *out_process_id, ncm::ProgramId program_id); Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); - Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out); - Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out); + Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out); + Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out); Result GetProcessInfo(ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id); diff --git a/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp b/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp index 9266302fc..0fb6e3c87 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/pm_types.hpp @@ -52,7 +52,7 @@ namespace ams::pm { LaunchFlagsDeprecated_SignalOnStart = (1 << 5), }; - struct ResourceLimitValues { + struct ResourceLimitValue { u64 physical_memory; u32 thread_count; u32 event_count; diff --git a/libraries/libstratosphere/source/pm/pm_info_api.cpp b/libraries/libstratosphere/source/pm/pm_info_api.cpp index 182c09c8a..9fdf4a865 100644 --- a/libraries/libstratosphere/source/pm/pm_info_api.cpp +++ b/libraries/libstratosphere/source/pm/pm_info_api.cpp @@ -28,13 +28,13 @@ namespace ams::pm::info { R_RETURN(pminfoAtmosphereGetProcessId(reinterpret_cast(out_process_id), static_cast(program_id))); } - Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out) { - static_assert(sizeof(pm::ResourceLimitValues) == sizeof(::PmResourceLimitValues)); + Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out) { + static_assert(sizeof(pm::ResourceLimitValue) == sizeof(::PmResourceLimitValues)); R_RETURN(pminfoGetAppletCurrentResourceLimitValues(reinterpret_cast(out))); } - Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out) { - static_assert(sizeof(pm::ResourceLimitValues) == sizeof(::PmResourceLimitValues)); + Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out) { + static_assert(sizeof(pm::ResourceLimitValue) == sizeof(::PmResourceLimitValues)); R_RETURN(pminfoGetAppletPeakResourceLimitValues(reinterpret_cast(out))); } diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index db0648acc..036814f66 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -719,12 +719,12 @@ namespace ams::pm::impl { R_RETURN(resource::BoostSystemThreadResourceLimit()); } - Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out) { - R_RETURN(resource::GetCurrentResourceLimitValues(ResourceLimitGroup_Applet, out)); + Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out) { + R_RETURN(resource::GetResourceLimitCurrentValue(ResourceLimitGroup_Applet, out)); } - Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out) { - R_RETURN(resource::GetPeakResourceLimitValues(ResourceLimitGroup_Applet, out)); + Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out) { + R_RETURN(resource::GetResourceLimitPeakValue(ResourceLimitGroup_Applet, out)); } Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource) { diff --git a/stratosphere/pm/source/impl/pm_process_manager.hpp b/stratosphere/pm/source/impl/pm_process_manager.hpp index 83ccc7a85..b12e91651 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.hpp +++ b/stratosphere/pm/source/impl/pm_process_manager.hpp @@ -52,8 +52,8 @@ namespace ams::pm::impl { Result BoostSystemMemoryResourceLimit(u64 boost_size); Result BoostApplicationThreadResourceLimit(); Result BoostSystemThreadResourceLimit(); - Result GetAppletCurrentResourceLimitValues(pm::ResourceLimitValues *out); - Result GetAppletPeakResourceLimitValues(pm::ResourceLimitValues *out); + Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out); + Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out); Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource); Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size); diff --git a/stratosphere/pm/source/impl/pm_resource_manager.cpp b/stratosphere/pm/source/impl/pm_resource_manager.cpp index 6c5805b5d..fc07a5daa 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.cpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.cpp @@ -202,7 +202,7 @@ namespace ams::pm::resource { } template - ALWAYS_INLINE Result GetResourceLimitValuesImpl(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + ALWAYS_INLINE Result GetResourceLimitValuesImpl(ResourceLimitGroup group, pm::ResourceLimitValue *out) { /* Sanity check group. */ AMS_ABORT_UNLESS(group < ResourceLimitGroup_Count); @@ -451,15 +451,15 @@ namespace ams::pm::resource { } } - Result GetCurrentResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + Result GetResourceLimitCurrentValue(ResourceLimitGroup group, pm::ResourceLimitValue *out) { R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitCurrentValue>(group, out)); } - Result GetPeakResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + Result GetResourceLimitPeakValue(ResourceLimitGroup group, pm::ResourceLimitValue *out) { R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitPeakValue>(group, out)); } - Result GetLimitResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out) { + Result GetResourceLimitLimitValue(ResourceLimitGroup group, pm::ResourceLimitValue *out) { R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitLimitValue>(group, out)); } diff --git a/stratosphere/pm/source/impl/pm_resource_manager.hpp b/stratosphere/pm/source/impl/pm_resource_manager.hpp index 029458203..b6f5605af 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.hpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.hpp @@ -31,9 +31,9 @@ namespace ams::pm::resource { void WaitResourceAvailable(const ldr::ProgramInfo *info); - Result GetCurrentResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out); - Result GetPeakResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out); - Result GetLimitResourceLimitValues(ResourceLimitGroup group, pm::ResourceLimitValues *out); + Result GetResourceLimitCurrentValue(ResourceLimitGroup group, pm::ResourceLimitValue *out); + Result GetResourceLimitPeakValue(ResourceLimitGroup group, pm::ResourceLimitValue *out); + Result GetResourceLimitLimitValue(ResourceLimitGroup group, pm::ResourceLimitValue *out); Result GetResourceLimitValues(s64 *out_cur, s64 *out_lim, ResourceLimitGroup group, svc::LimitableResource resource); diff --git a/stratosphere/pm/source/pm_info_service.cpp b/stratosphere/pm/source/pm_info_service.cpp index 26c7f2781..55b308fce 100644 --- a/stratosphere/pm/source/pm_info_service.cpp +++ b/stratosphere/pm/source/pm_info_service.cpp @@ -33,12 +33,12 @@ namespace ams::pm { R_RETURN(impl::GetProgramId(out.GetPointer(), process_id)); } - Result InformationService::GetAppletCurrentResourceLimitValues(sf::Out out) { - R_RETURN(impl::GetAppletCurrentResourceLimitValues(out.GetPointer())); + Result InformationService::GetAppletResourceLimitCurrentValue(sf::Out out) { + R_RETURN(impl::GetAppletResourceLimitCurrentValue(out.GetPointer())); } - Result InformationService::GetAppletPeakResourceLimitValues(sf::Out out) { - R_RETURN(impl::GetAppletPeakResourceLimitValues(out.GetPointer())); + Result InformationService::GetAppletResourceLimitPeakValue(sf::Out out) { + R_RETURN(impl::GetAppletResourceLimitPeakValue(out.GetPointer())); } /* Atmosphere extension commands. */ diff --git a/stratosphere/pm/source/pm_info_service.hpp b/stratosphere/pm/source/pm_info_service.hpp index 1f8010f11..1fd892542 100644 --- a/stratosphere/pm/source/pm_info_service.hpp +++ b/stratosphere/pm/source/pm_info_service.hpp @@ -22,8 +22,8 @@ namespace ams::pm { public: /* Actual command implementations. */ Result GetProgramId(sf::Out out, os::ProcessId process_id); - Result GetAppletCurrentResourceLimitValues(sf::Out out); - Result GetAppletPeakResourceLimitValues(sf::Out out); + Result GetAppletResourceLimitCurrentValue(sf::Out out); + Result GetAppletResourceLimitPeakValue(sf::Out out); /* Atmosphere extension commands. */ Result AtmosphereGetProcessId(sf::Out out, ncm::ProgramId program_id); From 7f61dfdb8dde7a46f6856a96c4de95a104ddc405 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 17 Oct 2023 11:25:35 -0700 Subject: [PATCH 060/238] pm: since 15.0.0, WaitApplicationMemoryAvailable is more lenient --- stratosphere/pm/source/impl/pm_resource_manager.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/stratosphere/pm/source/impl/pm_resource_manager.cpp b/stratosphere/pm/source/impl/pm_resource_manager.cpp index fc07a5daa..f11a72dca 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.cpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.cpp @@ -170,10 +170,18 @@ namespace ams::pm::resource { } void WaitApplicationMemoryAvailable() { + /* Get firmware version. */ + const auto fw_ver = hos::GetVersion(); + + /* On 15.0.0+, pm considers application memory to be available if there is exactly 96 MB outstanding. */ + /* This is probably because this corresponds to the gameplay-recording memory. */ + constexpr u64 AllowedUsedApplicationMemory = 96_MB; + + /* Wait for memory to be available. */ u64 value = 0; while (true) { R_ABORT_UNLESS(svc::GetSystemInfo(&value, svc::SystemInfoType_UsedPhysicalMemorySize, svc::InvalidHandle, svc::PhysicalMemorySystemInfo_Application)); - if (value == 0) { + if (value == 0 || (fw_ver >= hos::Version_15_0_0 && value == AllowedUsedApplicationMemory)) { break; } os::SleepThread(TimeSpan::FromMilliSeconds(1)); From a84f725e218d03cdcc4cc3b6b66fc4c45e7bcaae Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 18 Oct 2023 02:31:26 -0700 Subject: [PATCH 061/238] jpegdec: update to reflect 17.0.0 changes --- atmosphere.mk | 4 +- .../decodersrv_decoder_control_service.cpp | 69 +++++ .../decodersrv_decoder_control_service.hpp | 4 +- .../decodersrv_software_jpeg_shrinker.cpp | 236 ++++++++++++++++++ .../decodersrv_software_jpeg_shrinker.hpp | 43 ++++ .../vapours/results/capsrv_results.hpp | 1 + 6 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp create mode 100644 libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp diff --git a/atmosphere.mk b/atmosphere.mk index cca6fc106..706b5f320 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -84,7 +84,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037 - #mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c + mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240 @@ -98,7 +98,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) cp stratosphere/fatal/$(ATMOSPHERE_OUT_DIR)/fatal.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp cp stratosphere/creport/$(ATMOSPHERE_OUT_DIR)/creport.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp cp stratosphere/ro/$(ATMOSPHERE_OUT_DIR)/ro.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp - #cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp + cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp cp stratosphere/pgl/$(ATMOSPHERE_OUT_DIR)/pgl.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp cp stratosphere/LogManager/$(ATMOSPHERE_OUT_DIR)/LogManager.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420/exefs.nsp cp stratosphere/htc/$(ATMOSPHERE_OUT_DIR)/htc.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240/exefs.nsp diff --git a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp index 8be38606a..eaa6befbe 100644 --- a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp +++ b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.cpp @@ -16,11 +16,16 @@ #include #include "decodersrv_decoder_server_object.hpp" #include "../jpeg/decodersrv_software_jpeg_decoder.hpp" +#include "../jpeg/decodersrv_software_jpeg_shrinker.hpp" namespace ams::capsrv::server { namespace { + constexpr const int JpegShrinkQualities[] = { + 98, 95, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0 + }; + Result DecodeJpegImpl(void *dst, size_t dst_size, const void *src_jpeg, size_t src_jpeg_size, u32 width, u32 height, const ScreenShotDecodeOption &option, void *work, size_t work_size) { /* Clear the work memory. */ std::memset(work, 0, work_size); @@ -67,6 +72,61 @@ namespace ams::capsrv::server { R_SUCCEED(); } + Result ShrinkJpegImpl(u64 *out_size, void *dst, size_t dst_size, const void *src_jpeg, size_t src_jpeg_size, u32 width, u32 height, const ScreenShotDecodeOption &option, void *work, size_t work_size) { + /* Validate parameters. */ + R_UNLESS(util::IsAligned(width, 0x10), capsrv::ResultAlbumOutOfRange()); + R_UNLESS(util::IsAligned(height, 0x4), capsrv::ResultAlbumOutOfRange()); + + R_UNLESS(dst != nullptr, capsrv::ResultInternalJpegOutBufferShortage()); + R_UNLESS(dst_size != 0, capsrv::ResultAlbumReadBufferShortage()); + + R_UNLESS(src_jpeg != nullptr, capsrv::ResultAlbumInvalidFileData()); + R_UNLESS(src_jpeg_size != 0, capsrv::ResultAlbumInvalidFileData()); + + /* Create the input. */ + const jpeg::SoftwareJpegShrinkerInput shrink_input = { + .jpeg = src_jpeg, + .jpeg_size = src_jpeg_size, + .width = width, + .height = height, + .fancy_upsampling = option.HasJpegDecoderFlag(ScreenShotDecoderFlag_EnableFancyUpsampling), + .block_smoothing = option.HasJpegDecoderFlag(ScreenShotDecoderFlag_EnableBlockSmoothing), + }; + + /* Create the output. */ + u64 shrunk_size = 0; + s32 shrunk_width = 0, shrunk_height = 0; + jpeg::SoftwareJpegShrinkerOutput shrink_output = { + .out_size = std::addressof(shrunk_size), + .out_width = std::addressof(shrunk_width), + .out_height = std::addressof(shrunk_height), + .dst = dst, + .dst_size = dst_size, + }; + + /* Try to shrink the jpeg at various quality levels. */ + for (auto quality : JpegShrinkQualities) { + /* Shrink at the current quality. */ + R_TRY_CATCH(jpeg::SoftwareJpegShrinker::ShrinkRgba8(shrink_output, shrink_input, quality, work, work_size)) { + /* If the output buffer isn't large enough to fit the output, we should try at a lower quality. */ + R_CATCH(capsrv::ResultInternalJpegOutBufferShortage) { + continue; + } + /* Nintendo doesn't catch this result, but our lack of work buffer use makes me think this may be necessary. */ + R_CATCH(capsrv::ResultInternalJpegWorkMemoryShortage) { + continue; + } + } R_END_TRY_CATCH; + + /* Write the output size. */ + *out_size = shrunk_size; + R_SUCCEED(); + } + + /* Nintendo aborts if no quality succeeds. */ + AMS_ABORT("ShrinkJpeg should succeed before this point\n"); + } + } Result DecoderControlService::DecodeJpeg(const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option) { @@ -78,4 +138,13 @@ namespace ams::capsrv::server { R_RETURN(DecodeJpegImpl(out.GetPointer(), out.GetSize(), in.GetPointer(), in.GetSize(), width, height, option, work, work_size)); } + Result DecoderControlService::ShrinkJpeg(ams::sf::Out out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option) { + /* Get the work buffer. */ + void *work = g_work_memory.jpeg_decoder_memory; + size_t work_size = sizeof(g_work_memory.jpeg_decoder_memory); + + /* Call the shrink implementation. */ + R_RETURN(ShrinkJpegImpl(out_size.GetPointer(), out.GetPointer(), out.GetSize(), in.GetPointer(), in.GetSize(), width, height, option, work, work_size)); + } + } \ No newline at end of file diff --git a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp index feab40ba0..1c000ef11 100644 --- a/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp +++ b/libraries/libstratosphere/source/capsrv/server/decodersrv/decodersrv_decoder_control_service.hpp @@ -17,7 +17,8 @@ #include #define AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option)) + AMS_SF_METHOD_INFO(C, H, 3001, Result, DecodeJpeg, (const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out, in, width, height, option)) \ + AMS_SF_METHOD_INFO(C, H, 4001, Result, ShrinkJpeg, (ams::sf::Out out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option), (out_size, out, in, width, height, option)) AMS_SF_DEFINE_INTERFACE(ams::capsrv::sf, IDecoderControlService, AMS_CAPSRV_DECODER_CONTROL_SERVICE_INTERFACE_INFO, 0xD168E90B) @@ -26,6 +27,7 @@ namespace ams::capsrv::server { class DecoderControlService final { public: Result DecodeJpeg(const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const ScreenShotDecodeOption &option); + Result ShrinkJpeg(ams::sf::Out out_size, const ams::sf::OutNonSecureBuffer &out, const ams::sf::InBuffer &in, u32 width, u32 height, const capsrv::ScreenShotDecodeOption &option); }; static_assert(capsrv::sf::IsIDecoderControlService); diff --git a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp new file mode 100644 index 000000000..1ba5aa0ec --- /dev/null +++ b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "decodersrv_software_jpeg_shrinker.hpp" +#include "capsrv_server_jpeg_library_types.hpp" +#include "capsrv_server_jpeg_error_handler.hpp" + + +namespace ams::capsrv::server::jpeg { + + #define CAPSRV_ABORT_UNLESS(expr) do { \ + const bool __capsrv_assert_res = (expr); \ + AMS_ASSERT(__capsrv_assert_res); \ + AMS_ABORT_UNLESS(__capsrv_assert_res); \ + } while (0) + + #define CAPSRV_ASSERT(expr) do { \ + const bool __capsrv_assert_res = (expr); \ + AMS_ASSERT(__capsrv_assert_res); \ + R_UNLESS(__capsrv_assert_res, capsrv::ResultAlbumError()); \ + } while (0) + + namespace { + + constexpr s32 ImageSizeHorizonalUnit = 0x10; + constexpr s32 ImageSizeVerticalUnitDecode = 0x4; + constexpr s32 ImageSizeVerticalUnitEncode = 0x8; + + constexpr s32 RgbColorComponentCount = 3; + constexpr s32 RgbaColorComponentCount = 4; + + Result GetRgbBufferSize(size_t *out_size, size_t *out_stride, s32 width, size_t work_size) { + /* Calculate the space we need and verify we have enough. */ + const size_t rgb_width = util::AlignUp(static_cast(width), ImageSizeHorizonalUnit); + const size_t rgb_stride = rgb_width * RgbColorComponentCount; + const size_t rgb_size = rgb_stride * ImageSizeVerticalUnitEncode; + R_UNLESS(work_size >= rgb_size, capsrv::ResultInternalJpegWorkMemoryShortage()); + + /* Return the output to the caller. */ + *out_size = rgb_size; + *out_stride = rgb_stride; + R_SUCCEED(); + } + + void SetupEncodingParameter(JpegLibraryType::jpeg_compress_struct *cinfo, const SoftwareJpegShrinkerInput &input, int quality) { + /* Set parameters. */ + cinfo->image_width = static_cast(input.width / 2); + cinfo->image_height = static_cast(input.height / 2); + cinfo->input_components = RgbColorComponentCount; + cinfo->in_color_space = JpegLibraryType::J_COLOR_SPACE::JCS_RGB; + + /* Set defaults/color space. */ + jpeg_set_defaults(cinfo); + jpeg_set_colorspace(cinfo, JpegLibraryType::J_COLOR_SPACE::JCS_YCbCr); + + /* Configure sampling. */ + /* libjpeg-turbo doesn't actually have this field, as of now. */ + /* cinfo->do_fancy_downsampling = false; */ + cinfo->comp_info[0].h_samp_factor = 2; + cinfo->comp_info[0].v_samp_factor = 1; + cinfo->comp_info[1].h_samp_factor = 1; + cinfo->comp_info[1].v_samp_factor = 1; + cinfo->comp_info[2].h_samp_factor = 1; + cinfo->comp_info[2].v_samp_factor = 1; + + /* Set the quality. */ + jpeg_set_quality(cinfo, quality, true); + + /* Configure remaining parameters. */ + cinfo->dct_method = JpegLibraryType::J_DCT_METHOD::JDCT_ISLOW; + cinfo->optimize_coding = false; + cinfo->write_JFIF_header = true; + } + + } + + Result SoftwareJpegShrinker::ShrinkRgba8(SoftwareJpegShrinkerOutput &output, const SoftwareJpegShrinkerInput &input, int quality, void *work, size_t work_size) { + CAPSRV_ABORT_UNLESS(util::IsAligned(input.width, ImageSizeHorizonalUnit)); + CAPSRV_ABORT_UNLESS(util::IsAligned(input.height, ImageSizeVerticalUnitDecode)); + + const u32 shrunk_width = input.width / 2; + const u32 shrunk_height = input.height / 2; + CAPSRV_ABORT_UNLESS(util::IsAligned(input.width, ImageSizeHorizonalUnit)); + + CAPSRV_ABORT_UNLESS(output.dst != nullptr); + + CAPSRV_ABORT_UNLESS(output.out_width != nullptr); + CAPSRV_ABORT_UNLESS(output.out_height != nullptr); + + /* Determine work buffer extents. */ + char *work_start = static_cast(work); + char *work_end = work_start + work_size; + + /* Determine the buffer extents for our linebuffers. */ + u8 *rgb_buffer = static_cast(static_cast(work_start)); + size_t rgb_buffer_size; + size_t rgb_buffer_stride; + R_TRY(GetRgbBufferSize(std::addressof(rgb_buffer_size), std::addressof(rgb_buffer_stride), input.width, work_size)); + + /* The start of the workbuffer is reserved for linebuffer space. */ + work_start += rgb_buffer_size; + + /* Create our compression structures. */ + JpegLibraryType::jpeg_decompress_struct dcinfo = {}; + JpegLibraryType::jpeg_compress_struct ecinfo = {}; + + /* Here nintendo creates a work buffer structure containing work_start + work_size. */ + /* This seems to be a custom patch for/to libjpeg-turbo. */ + /* It would be desirable for us to mimic this, because it gives Nintendo strong */ + /* fixed memory usage guarantees. */ + /* TODO: Determine if it is feasible for us to recreate this ourselves, */ + /* Either by adding support to the devkitPro libjpeg-turbo portlib or otherwise. */ + AMS_UNUSED(work_end); + + /* Create our error managers. */ + JpegErrorHandler jerr_dc = { .result = ResultSuccess(), }; + JpegErrorHandler jerr_ec = { .result = ResultSuccess(), }; + jerr_dc.error_exit = JpegErrorHandler::HandleError, + jerr_ec.error_exit = JpegErrorHandler::HandleError, + + /* Link our error managers to our compression structures. */ + dcinfo.err = jpeg_std_error(std::addressof(jerr_dc)); + ecinfo.err = jpeg_std_error(std::addressof(jerr_ec)); + + /* Use setjmp, so that on error our handler will longjmp to return an error result. */ + if (setjmp(jerr_ec.jmp_buf) == 0) { + if (setjmp(jerr_dc.jmp_buf) == 0) { + /* Create our decompressor. */ + jpeg_create_decompress(std::addressof(dcinfo)); + ON_SCOPE_EXIT { jpeg_destroy_decompress(std::addressof(dcinfo)); }; + + /* Setup our memory reader, ensure the header is correct. */ + jpeg_mem_src(std::addressof(dcinfo), const_cast(static_cast(input.jpeg)), input.jpeg_size); + R_UNLESS(jpeg_read_header(std::addressof(dcinfo), true) == JPEG_HEADER_OK, capsrv::ResultAlbumInvalidFileData()); + + /* Ensure width and height are correct. */ + R_UNLESS(dcinfo.image_width == input.width, capsrv::ResultAlbumInvalidFileData()); + R_UNLESS(dcinfo.image_height == input.height, capsrv::ResultAlbumInvalidFileData()); + + /* Set output parameters. */ + dcinfo.out_color_space = JpegLibraryType::J_COLOR_SPACE::JCS_RGB; + dcinfo.dct_method = JpegLibraryType::J_DCT_METHOD::JDCT_ISLOW; + dcinfo.do_fancy_upsampling = input.fancy_upsampling; + dcinfo.do_block_smoothing = input.block_smoothing; + dcinfo.scale_num = 1; + dcinfo.scale_denom = 2; + + /* Start decompression. */ + R_UNLESS(jpeg_start_decompress(std::addressof(dcinfo)) == TRUE, capsrv::ResultAlbumInvalidFileData()); + + /* Check the parameters. */ + CAPSRV_ASSERT(dcinfo.output_width == shrunk_width); + CAPSRV_ASSERT(dcinfo.output_height == shrunk_height); + CAPSRV_ASSERT(dcinfo.out_color_components == RgbColorComponentCount); + CAPSRV_ASSERT(dcinfo.output_components == RgbColorComponentCount); + + /* Create our compressor. */ + jpeg_create_compress(std::addressof(ecinfo)); + ON_SCOPE_EXIT { jpeg_destroy_compress(std::addressof(ecinfo)); }; + + /* Setup our memory writer. */ + unsigned long out_size = static_cast(output.dst_size); + jpeg_mem_dest(std::addressof(ecinfo), reinterpret_cast(std::addressof(output.dst)), std::addressof(out_size)); + + /* Setup the encoding parameters. */ + SetupEncodingParameter(std::addressof(ecinfo), input, quality); + + /* Start compression. */ + jpeg_start_compress(std::addressof(ecinfo), true); + + /* Parse the scanlines. */ + { + /* Create our linebuffer structure. */ + JpegLibraryType::JSAMPROW linebuffers[ImageSizeVerticalUnitEncode] = {}; + for (int i = 0; i < ImageSizeVerticalUnitEncode; i++) { + linebuffers[i] = rgb_buffer + rgb_buffer_stride * i; + } + + /* While we still have scanlines, parse! */ + while (dcinfo.output_scanline < shrunk_height) { + /* Determine remaining scanlines. */ + const auto remaining_scanlines = shrunk_height - dcinfo.output_scanline; + const auto cur_max_scanlines = std::min(remaining_scanlines, ImageSizeVerticalUnitEncode); + + /* If we have scanlines to decode, try to do so. */ + auto writable_scanlines = 0; + while (writable_scanlines < cur_max_scanlines) { + const auto decoded = jpeg_read_scanlines(std::addressof(dcinfo), linebuffers + writable_scanlines, ImageSizeVerticalUnitDecode); + CAPSRV_ASSERT(decoded <= ImageSizeVerticalUnitDecode / 2); + + writable_scanlines += decoded; + } + + /* If we have scanlines to write, try to do so. */ + jpeg_write_scanlines(std::addressof(ecinfo), linebuffers, writable_scanlines); + } + } + + /* Finish the decompression. */ + R_UNLESS(jpeg_finish_decompress(std::addressof(dcinfo)) == TRUE, capsrv::ResultAlbumInvalidFileData()); + + /* Finish the compression. */ + jpeg_finish_compress(std::addressof(ecinfo)); + + /* Set the output size. */ + *output.out_size = out_size; + } else { + /* Some unknown error was caught by our handler. */ + R_THROW(capsrv::ResultAlbumInvalidFileData()); + } + } else { + /* Return the encoding result. */ + R_THROW(jerr_ec.result); + } + + /* Write the size we decoded to output. */ + *output.out_width = static_cast(dcinfo.output_width); + *output.out_width = static_cast(dcinfo.output_height); + + R_SUCCEED(); + } + +} diff --git a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp new file mode 100644 index 000000000..a2774b20b --- /dev/null +++ b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::capsrv::server::jpeg { + + struct SoftwareJpegShrinkerInput { + const void *jpeg; + size_t jpeg_size; + u32 width; + u32 height; + bool fancy_upsampling; + bool block_smoothing; + }; + + struct SoftwareJpegShrinkerOutput { + u64 *out_size; + s32 *out_width; + s32 *out_height; + void *dst; + size_t dst_size; + }; + + class SoftwareJpegShrinker { + public: + static Result ShrinkRgba8(SoftwareJpegShrinkerOutput &output, const SoftwareJpegShrinkerInput &input, int quality, void *work, size_t work_size); + }; + +} \ No newline at end of file diff --git a/libraries/libvapours/include/vapours/results/capsrv_results.hpp b/libraries/libvapours/include/vapours/results/capsrv_results.hpp index d353ab93f..f1b36c3b9 100644 --- a/libraries/libvapours/include/vapours/results/capsrv_results.hpp +++ b/libraries/libvapours/include/vapours/results/capsrv_results.hpp @@ -54,6 +54,7 @@ namespace ams::capsrv { R_DEFINE_ERROR_RANGE(InternalError, 1024, 2047); R_DEFINE_ERROR_RESULT(InternalJpegEncoderError, 1210); + R_DEFINE_ERROR_RESULT(InternalJpegOutBufferShortage, 1211); R_DEFINE_ERROR_RESULT(InternalJpegWorkMemoryShortage, 1212); R_DEFINE_ERROR_RANGE(InternalFileDataVerificationError, 1300, 1399); From 3f19db0d9673b277575e85b17cce1a1ec90a9e1e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 18 Oct 2023 02:33:59 -0700 Subject: [PATCH 062/238] jpegdec: fix abort check on output width --- .../capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp index 1ba5aa0ec..119f52fe8 100644 --- a/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp +++ b/libraries/libstratosphere/source/capsrv/server/jpeg/decodersrv_software_jpeg_shrinker.cpp @@ -93,7 +93,7 @@ namespace ams::capsrv::server::jpeg { const u32 shrunk_width = input.width / 2; const u32 shrunk_height = input.height / 2; - CAPSRV_ABORT_UNLESS(util::IsAligned(input.width, ImageSizeHorizonalUnit)); + CAPSRV_ABORT_UNLESS(util::IsAligned(shrunk_width, ImageSizeHorizonalUnit)); CAPSRV_ABORT_UNLESS(output.dst != nullptr); From fa384fd920e7cdd2946517915e803d03f9e02536 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 25 Oct 2023 04:45:41 -0700 Subject: [PATCH 063/238] erpt: begin SubmitFsinfo (SubmitMmcDetailInfo) --- libraries/config/templates/stratosphere.mk | 2 +- .../include/stratosphere/fs.hpp | 1 + .../include/stratosphere/fs/fs_mmc.hpp | 57 ++++++ .../fssrv/sf/fssrv_sf_i_device_operator.hpp | 10 +- .../source/erpt/srv/erpt_srv_fs_info.hpp | 23 +++ .../erpt/srv/erpt_srv_fs_info.os.horizon.cpp | 183 ++++++++++++++++++ .../source/erpt/srv/erpt_srv_reporter.cpp | 10 +- .../libstratosphere/source/fs/fs_mmc.cpp | 89 +++++++++ .../fs/impl/fs_remote_device_operator.hpp | 16 ++ 9 files changed, 385 insertions(+), 6 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp create mode 100644 libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp create mode 100644 libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp create mode 100644 libraries/libstratosphere/source/fs/fs_mmc.cpp diff --git a/libraries/config/templates/stratosphere.mk b/libraries/config/templates/stratosphere.mk index d0bbf3f85..06fb362c9 100644 --- a/libraries/config/templates/stratosphere.mk +++ b/libraries/config/templates/stratosphere.mk @@ -66,7 +66,7 @@ endif ifeq ($(ATMOSPHERE_BOARD),nx-hac-001) -export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $*.map) +export LDFLAGS = -specs=$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/stratosphere.specs -specs=$(DEVKITPRO)/libnx/switch.specs $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-Map,$(notdir $*.map) -Wl,-z,relro,-z,now else ifeq ($(ATMOSPHERE_OS_NAME),macos) export LDFLAGS = $(CXXFLAGS) $(CXXWRAPS) $(CXXREQUIRED) -Wl,-map,$(notdir $@.map) else diff --git a/libraries/libstratosphere/include/stratosphere/fs.hpp b/libraries/libstratosphere/include/stratosphere/fs.hpp index 13b7603d1..5e3da8c2c 100644 --- a/libraries/libstratosphere/include/stratosphere/fs.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs.hpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp new file mode 100644 index 000000000..b954378be --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_mmc.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::fs { + + constexpr inline size_t MmcCidSize = 0x10; + + constexpr inline size_t MmcExtendedCsdSize = 0x200; + + constexpr inline int MmcExtendedCsdOffsetReEolInfo = 267; + constexpr inline int MmcExtendedCsdOffsetDeviceLifeTimeEstTypA = 268; + constexpr inline int MmcExtendedCsdOffsetDeviceLifeTimeEstTypB = 269; + + enum MmcSpeedMode { + MmcSpeedMode_Identification = 0, + MmcSpeedMode_LegacySpeed = 1, + MmcSpeedMode_HighSpeed = 2, + MmcSpeedMode_Hs200 = 3, + MmcSpeedMode_Hs400 = 4, + MmcSpeedMode_Unknown = 5, + }; + + enum class MmcPartition { + UserData = 0, + BootPartition1 = 1, + BootPartition2 = 2, + }; + + Result GetMmcCid(void *dst, size_t size); + + inline void ClearMmcCidSerialNumber(u8 *cid) { + /* Clear the serial number from the cid. */ + std::memset(cid + 1, 0, 4); + } + + Result GetMmcSpeedMode(MmcSpeedMode *out); + + Result GetMmcPatrolCount(u32 *out); + + Result GetMmcExtendedCsd(void *dst, size_t size); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp index 7334ff861..e81b31cfb 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp @@ -20,8 +20,12 @@ /* TODO */ /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) + AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 100, Result, GetMmcCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 101, Result, GetMmcSpeedMode, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 112, Result, GetMmcPatrolCount, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IDeviceOperator, AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO, 0x1484E21C) diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp new file mode 100644 index 000000000..5d9d7ad17 --- /dev/null +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.hpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::erpt::srv { + + Result SubmitFsInfo(); + +} diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp new file mode 100644 index 000000000..3c8957104 --- /dev/null +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "erpt_srv_fs_info.hpp" +#include "erpt_srv_context_record.hpp" +#include "erpt_srv_context.hpp" + +namespace ams::erpt::srv { + + namespace { + + Result SubmitMmcDetailInfo() { + /* Submit the mmc cid. */ + { + u8 mmc_cid[fs::MmcCidSize] = {}; + if (R_SUCCEEDED(fs::GetMmcCid(mmc_cid, sizeof(mmc_cid)))) { + /* Clear the serial number from the cid. */ + fs::ClearMmcCidSerialNumber(mmc_cid); + + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDTypeInfo, sizeof(mmc_cid)); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add the cid. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDType, mmc_cid, sizeof(mmc_cid))); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + + /* Submit the mmc speed mode. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDSpeedModeInfo, 0x20); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Get the speed mode. */ + fs::MmcSpeedMode speed_mode{}; + const auto res = fs::GetMmcSpeedMode(std::addressof(speed_mode)); + if (R_SUCCEEDED(res)) { + const char *speed_mode_name = "None"; + switch (speed_mode) { + case fs::MmcSpeedMode_Identification: + speed_mode_name = "Identification"; + break; + case fs::MmcSpeedMode_LegacySpeed: + speed_mode_name = "LegacySpeed"; + break; + case fs::MmcSpeedMode_HighSpeed: + speed_mode_name = "HighSpeed"; + break; + case fs::MmcSpeedMode_Hs200: + speed_mode_name = "Hs200"; + break; + case fs::MmcSpeedMode_Hs400: + speed_mode_name = "Hs400"; + break; + case fs::MmcSpeedMode_Unknown: + speed_mode_name = "Unknown"; + break; + default: + speed_mode_name = "UnDefined"; + break; + } + + R_ABORT_UNLESS(record->Add(FieldId_NANDSpeedMode, speed_mode_name, std::strlen(speed_mode_name))); + } else { + /* Getting speed mode failed, so add the result. */ + char res_str[0x20]; + util::SNPrintf(res_str, sizeof(res_str), "0x%08X", res.GetValue()); + R_ABORT_UNLESS(record->Add(FieldId_NANDSpeedMode, res_str, std::strlen(res_str))); + } + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* Submit the mmc extended csd. */ + { + u8 mmc_csd[fs::MmcExtendedCsdSize] = {}; + if (R_SUCCEEDED(fs::GetMmcExtendedCsd(mmc_csd, sizeof(mmc_csd)))) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDExtendedCsd, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields from the csd. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDPreEolInfo, static_cast(mmc_csd[fs::MmcExtendedCsdOffsetReEolInfo]))); + R_ABORT_UNLESS(record->Add(FieldId_NANDDeviceLifeTimeEstTypA, static_cast(mmc_csd[fs::MmcExtendedCsdOffsetDeviceLifeTimeEstTypA]))); + R_ABORT_UNLESS(record->Add(FieldId_NANDDeviceLifeTimeEstTypB, static_cast(mmc_csd[fs::MmcExtendedCsdOffsetDeviceLifeTimeEstTypB]))); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + + /* Submit the mmc patrol count. */ + { + u32 count = 0; + if (R_SUCCEEDED(fs::GetMmcPatrolCount(std::addressof(count)))) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDPatrolInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add the count. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDPatrolCount, count)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + + R_SUCCEED(); + } + + Result SubmitMmcErrorInfo() { + /* TODO */ + R_SUCCEED(); + } + + Result SubmitSdCardDetailInfo() { + /* TODO */ + R_SUCCEED(); + } + + Result SubmitSdCardErrorInfo() { + /* TODO */ + R_SUCCEED(); + } + + Result SubmitGameCardDetailInfo() { + /* TODO */ + R_SUCCEED(); + } + + Result SubmitGameCardErrorInfo() { + /* TODO */ + R_SUCCEED(); + } + + Result SubmitFileSystemErrorInfo() { + /* TODO */ + R_SUCCEED(); + } + + Result SubmitMemoryReportInfo() { + /* TODO */ + R_SUCCEED(); + } + + } + + Result SubmitFsInfo() { + /* Temporarily disable auto-abort. */ + fs::ScopedAutoAbortDisabler aad; + + /* Submit various FS info. */ + R_TRY(SubmitMmcDetailInfo()); + R_TRY(SubmitMmcErrorInfo()); + R_TRY(SubmitSdCardDetailInfo()); + R_TRY(SubmitSdCardErrorInfo()); + R_TRY(SubmitGameCardDetailInfo()); + R_TRY(SubmitGameCardErrorInfo()); + R_TRY(SubmitFileSystemErrorInfo()); + R_TRY(SubmitMemoryReportInfo()); + + R_SUCCEED(); + } + +} diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index ae0429a6d..afe0ce1fa 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -19,6 +19,7 @@ #include "erpt_srv_journal.hpp" #include "erpt_srv_context_record.hpp" #include "erpt_srv_context.hpp" +#include "erpt_srv_fs_info.hpp" namespace ams::erpt::srv { @@ -530,9 +531,14 @@ namespace ams::erpt::srv { SubmitResourceLimitContexts(); #endif - if (flags.Test()) { - /* TODO: 17.0.0 SubmitFsInfo() */ + /* If we should, submit fs info. */ + #if defined(ATMOSPHERE_OS_HORIZON) + if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test()) { + /* NOTE: Nintendo ignores the result of this call. */ + SubmitFsInfo(); } + #endif + R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fs/fs_mmc.cpp b/libraries/libstratosphere/source/fs/fs_mmc.cpp new file mode 100644 index 000000000..f0f8d6587 --- /dev/null +++ b/libraries/libstratosphere/source/fs/fs_mmc.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "fsa/fs_mount_utils.hpp" +#include "impl/fs_file_system_proxy_service_object.hpp" +#include "impl/fs_file_system_service_object_adapter.hpp" + +namespace ams::fs { + + Result GetMmcCid(void *dst, size_t size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the cid. */ + AMS_FS_R_TRY(device_operator->GetMmcCid(sf::OutBuffer(dst, size), static_cast(size))); + + R_SUCCEED(); + } + + Result GetMmcSpeedMode(MmcSpeedMode *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the speed mode. */ + s64 speed_mode = 0; + AMS_FS_R_TRY(device_operator->GetMmcSpeedMode(std::addressof(speed_mode))); + + *out = static_cast(speed_mode); + R_SUCCEED(); + } + + Result GetMmcPatrolCount(u32 *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the patrol count. */ + AMS_FS_R_TRY(device_operator->GetMmcPatrolCount(out)); + + R_SUCCEED(); + } + + Result GetMmcExtendedCsd(void *dst, size_t size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the csd. */ + AMS_FS_R_TRY(device_operator->GetMmcExtendedCsd(sf::OutBuffer(dst, size), static_cast(size))); + + R_SUCCEED(); + } + +} diff --git a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp index c6e674660..6b5c109ab 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp +++ b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp @@ -33,6 +33,22 @@ namespace ams::fs::impl { R_RETURN(fsDeviceOperatorIsSdCardInserted(std::addressof(m_operator), out.GetPointer())); } + Result GetMmcCid(ams::sf::OutBuffer out, s64 size) { + R_RETURN(fsDeviceOperatorGetMmcCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); + } + + Result GetMmcSpeedMode(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetMmcSpeedMode(std::addressof(m_operator), out.GetPointer())); + } + + Result GetMmcPatrolCount(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetMmcPatrolCount(std::addressof(m_operator), out.GetPointer())); + } + + Result GetMmcExtendedCsd(ams::sf::OutBuffer out, s64 size) { + R_RETURN(fsDeviceOperatorGetMmcExtendedCsd(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); + } + Result IsGameCardInserted(ams::sf::Out out) { R_RETURN(fsDeviceOperatorIsGameCardInserted(std::addressof(m_operator), out.GetPointer())); } From 60974a5f4ee28680ce0a76b8d6dd7ea27c60e603 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 25 Oct 2023 12:41:18 -0700 Subject: [PATCH 064/238] erpt: GetMmcErrorInfo, GetSdCard*Info --- .../include/stratosphere/fat.hpp | 17 ++ .../stratosphere/fat/fat_file_system.hpp | 55 ++++++ .../include/stratosphere/fs.hpp | 1 + .../include/stratosphere/fs/fs_error_info.hpp | 58 ++++++ .../include/stratosphere/fs/fs_sd_card.hpp | 26 +++ .../fssrv/sf/fssrv_sf_i_device_operator.hpp | 21 ++- .../erpt/srv/erpt_srv_fs_info.os.horizon.cpp | 172 +++++++++++++++++- .../libstratosphere/source/fs/fs_mmc.cpp | 20 ++ .../libstratosphere/source/fs/fs_sd_card.cpp | 86 +++++++++ .../fs/impl/fs_remote_device_operator.hpp | 26 +++ 10 files changed, 472 insertions(+), 10 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/fat.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp diff --git a/libraries/libstratosphere/include/stratosphere/fat.hpp b/libraries/libstratosphere/include/stratosphere/fat.hpp new file mode 100644 index 000000000..995267a2a --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fat.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include \ No newline at end of file diff --git a/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp new file mode 100644 index 000000000..2be687b83 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::fat { + + constexpr inline size_t FatErrorNameMaxLength = 0x10; + + struct FatError { + int error; + int extra_error; + int device_id; + char name[FatErrorNameMaxLength]; + u8 reserved[4]; + }; + static_assert(sizeof(FatError) == 0x20); + static_assert(util::is_pod::value); + + struct FatReportInfo1 { + u16 file_peak_open_count; + u16 directory_peak_open_count; + }; + static_assert(sizeof(FatReportInfo1) == 4); + static_assert(util::is_pod::value); + + struct FatReportInfo2 { + u16 unique_file_entry_peak_open_count; + u16 unique_directory_entry_peak_open_count; + }; + static_assert(sizeof(FatReportInfo2) == 4); + static_assert(util::is_pod::value); + + struct FatSafeInfo { + u32 result; + u32 error_number; + u32 safe_error_number; + }; + static_assert(sizeof(FatSafeInfo) == 12); + static_assert(util::is_pod::value); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fs.hpp b/libraries/libstratosphere/include/stratosphere/fs.hpp index 5e3da8c2c..9c3414051 100644 --- a/libraries/libstratosphere/include/stratosphere/fs.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs.hpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp new file mode 100644 index 000000000..71ed0d8d2 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::fs { + + struct StorageErrorInfo { + u32 num_activation_failures; + u32 num_activation_error_corrections; + u32 num_read_write_failures; + u32 num_read_write_error_corrections; + }; + static_assert(sizeof(StorageErrorInfo) == 0x10); + static_assert(util::is_pod::value); + + struct FileSystemProxyErrorInfo { + u32 rom_fs_remont_for_data_corruption_count; + u32 rom_fs_unrecoverable_data_corruption_by_remount_count; + fat::FatError fat_fs_error; + u32 rom_fs_recovered_by_invalidate_cache_count; + u32 save_data_index_count; + fat::FatReportInfo1 bis_system_report1; + fat::FatReportInfo1 bis_user_report1; + fat::FatReportInfo1 sd_card_report1; + fat::FatReportInfo2 bis_system_report2; + fat::FatReportInfo2 bis_user_report2; + fat::FatReportInfo2 sd_card_report2; + u32 rom_fs_deep_retry_start_count; + u32 rom_fs_unrecoverable_by_game_card_access_failed_count; + fat::FatSafeInfo bis_system_fat_safe_info; + fat::FatSafeInfo bis_user_fat_safe_info; + + u8 reserved[0x18]; + }; + static_assert(sizeof(FileSystemProxyErrorInfo) == 0x80); + static_assert(util::is_pod::value); + + Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size); + Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size); + + Result GetAndClearFileSystemProxyErrorInfo(FileSystemProxyErrorInfo *out); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp index 6ceda83db..b72d90709 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_sd_card.hpp @@ -21,12 +21,38 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: Unknown */ class IEventNotifier; + constexpr inline size_t SdCardCidSize = 0x10; + + enum SdCardSpeedMode { + SdCardSpeedMode_Identification = 0, + SdCardSpeedMode_DefaultSpeed = 1, + SdCardSpeedMode_HighSpeed = 2, + SdCardSpeedMode_Sdr12 = 3, + SdCardSpeedMode_Sdr25 = 4, + SdCardSpeedMode_Sdr50 = 5, + SdCardSpeedMode_Sdr104 = 6, + SdCardSpeedMode_Ddr50 = 7, + SdCardSpeedMode_Unknown = 8, + }; + struct EncryptionSeed { char value[0x10]; }; static_assert(util::is_pod::value); static_assert(sizeof(EncryptionSeed) == 0x10); + Result GetSdCardCid(void *dst, size_t size); + + inline void ClearSdCardCidSerialNumber(u8 *cid) { + /* Clear the serial number from the cid. */ + std::memset(cid + 2, 0, 4); + } + + Result GetSdCardUserAreaSize(s64 *out); + Result GetSdCardProtectedAreaSize(s64 *out); + + Result GetSdCardSpeedMode(SdCardSpeedMode *out); + Result MountSdCard(const char *name); Result MountSdCardErrorReportDirectoryForAtmosphere(const char *name); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp index e81b31cfb..4d6fa71ef 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp @@ -16,16 +16,23 @@ #pragma once #include #include +#include /* TODO */ /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 100, Result, GetMmcCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 101, Result, GetMmcSpeedMode, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 112, Result, GetMmcPatrolCount, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ - AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) + AMS_SF_METHOD_INFO(C, H, 0, Result, IsSdCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetSdCardSpeedMode, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, GetSdCardCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, GetSdCardUserAreaSize, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetSdCardProtectedAreaSize, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetAndClearSdCardErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ + AMS_SF_METHOD_INFO(C, H, 100, Result, GetMmcCid, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 101, Result, GetMmcSpeedMode, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 112, Result, GetMmcPatrolCount, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 113, Result, GetAndClearMmcErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ + AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IDeviceOperator, AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO, 0x1484E21C) diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp index 3c8957104..0290b2fd3 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -127,17 +127,183 @@ namespace ams::erpt::srv { } Result SubmitMmcErrorInfo() { - /* TODO */ + /* Get the mmc error info. */ + fs::StorageErrorInfo sei = {}; + char log_buffer[erpt::ArrayBufferSizeDefault] = {}; + size_t log_size = 0; + if (R_SUCCEEDED(fs::GetAndClearMmcErrorInfo(std::addressof(sei), std::addressof(log_size), log_buffer, sizeof(log_buffer)))) { + /* Submit the error info. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDErrorInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDNumActivationFailures, sei.num_activation_failures)); + R_ABORT_UNLESS(record->Add(FieldId_NANDNumActivationErrorCorrections, sei.num_activation_error_corrections)); + R_ABORT_UNLESS(record->Add(FieldId_NANDNumReadWriteFailures, sei.num_read_write_failures)); + R_ABORT_UNLESS(record->Add(FieldId_NANDNumReadWriteErrorCorrections, sei.num_read_write_error_corrections)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* If we have a log, submit it. */ + if (log_size > 0) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_NANDDriverLog, log_size); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_NANDErrorLog, log_buffer, log_size)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } Result SubmitSdCardDetailInfo() { - /* TODO */ + /* Submit the sd card cid. */ + { + u8 sd_cid[fs::SdCardCidSize] = {}; + if (R_SUCCEEDED(fs::GetSdCardCid(sd_cid, sizeof(sd_cid)))) { + /* Clear the serial number from the cid. */ + fs::ClearSdCardCidSerialNumber(sd_cid); + + /* Create a record. */ + auto record = std::make_unique(CategoryId_MicroSDTypeInfo, sizeof(sd_cid)); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add the cid. */ + R_ABORT_UNLESS(record->Add(FieldId_MicroSDType, sd_cid, sizeof(sd_cid))); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + + /* Submit the sd card speed mode. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_MicroSDSpeedModeInfo, 0x20); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Get the speed mode. */ + fs::SdCardSpeedMode speed_mode{}; + const auto res = fs::GetSdCardSpeedMode(std::addressof(speed_mode)); + if (R_SUCCEEDED(res)) { + const char *speed_mode_name = "None"; + switch (speed_mode) { + case fs::SdCardSpeedMode_Identification: + speed_mode_name = "Identification"; + break; + case fs::SdCardSpeedMode_DefaultSpeed: + speed_mode_name = "DefaultSpeed"; + break; + case fs::SdCardSpeedMode_HighSpeed: + speed_mode_name = "HighSpeed"; + break; + case fs::SdCardSpeedMode_Sdr12: + speed_mode_name = "Sdr12"; + break; + case fs::SdCardSpeedMode_Sdr25: + speed_mode_name = "Sdr25"; + break; + case fs::SdCardSpeedMode_Sdr50: + speed_mode_name = "Sdr50"; + break; + case fs::SdCardSpeedMode_Sdr104: + speed_mode_name = "Sdr104"; + break; + case fs::SdCardSpeedMode_Ddr50: + speed_mode_name = "Ddr50"; + break; + case fs::SdCardSpeedMode_Unknown: + speed_mode_name = "Unknown"; + break; + default: + speed_mode_name = "UnDefined"; + break; + } + + R_ABORT_UNLESS(record->Add(FieldId_MicroSDSpeedMode, speed_mode_name, std::strlen(speed_mode_name))); + } else { + /* Getting speed mode failed, so add the result. */ + char res_str[0x20]; + util::SNPrintf(res_str, sizeof(res_str), "0x%08X", res.GetValue()); + R_ABORT_UNLESS(record->Add(FieldId_MicroSDSpeedMode, res_str, std::strlen(res_str))); + } + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* Submit the area sizes. */ + { + s64 user_area_size = 0; + s64 prot_area_size = 0; + const Result res_user = fs::GetSdCardUserAreaSize(std::addressof(user_area_size)); + const Result res_prot = fs::GetSdCardProtectedAreaSize(std::addressof(prot_area_size)); + if (R_SUCCEEDED(res_user) || R_SUCCEEDED(res_prot)) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_SdCardSizeSpec, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add sizes. */ + if (R_SUCCEEDED(res_user)) { + R_ABORT_UNLESS(record->Add(FieldId_SdCardUserAreaSize, user_area_size)); + } + if (R_SUCCEEDED(res_prot)) { + R_ABORT_UNLESS(record->Add(FieldId_SdCardProtectedAreaSize, prot_area_size)); + } + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } Result SubmitSdCardErrorInfo() { - /* TODO */ + /* Get the sd card error info. */ + fs::StorageErrorInfo sei = {}; + char log_buffer[erpt::ArrayBufferSizeDefault] = {}; + size_t log_size = 0; + if (R_SUCCEEDED(fs::GetAndClearSdCardErrorInfo(std::addressof(sei), std::addressof(log_size), log_buffer, sizeof(log_buffer)))) { + /* Submit the error info. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_SdCardErrorInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumActivationFailures, sei.num_activation_failures)); + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumActivationErrorCorrections, sei.num_activation_error_corrections)); + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumReadWriteFailures, sei.num_read_write_failures)); + R_ABORT_UNLESS(record->Add(FieldId_SdCardNumReadWriteErrorCorrections, sei.num_read_write_error_corrections)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* If we have a log, submit it. */ + if (log_size > 0) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_SdCardDriverLog, log_size); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_SdCardErrorLog, log_buffer, log_size)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fs/fs_mmc.cpp b/libraries/libstratosphere/source/fs/fs_mmc.cpp index f0f8d6587..f14364b92 100644 --- a/libraries/libstratosphere/source/fs/fs_mmc.cpp +++ b/libraries/libstratosphere/source/fs/fs_mmc.cpp @@ -70,6 +70,26 @@ namespace ams::fs { R_SUCCEED(); } + Result GetAndClearMmcErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out_sei != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_size != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_buffer != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the error info. */ + s64 log_size = 0; + AMS_FS_R_TRY(device_operator->GetAndClearMmcErrorInfo(out_sei, std::addressof(log_size), sf::OutBuffer(out_log_buffer, log_buffer_size), static_cast(log_buffer_size))); + + *out_log_size = static_cast(log_size); + R_SUCCEED(); + } + Result GetMmcExtendedCsd(void *dst, size_t size) { /* Check pre-conditions. */ AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); diff --git a/libraries/libstratosphere/source/fs/fs_sd_card.cpp b/libraries/libstratosphere/source/fs/fs_sd_card.cpp index a1e5964ef..cf923c3fd 100644 --- a/libraries/libstratosphere/source/fs/fs_sd_card.cpp +++ b/libraries/libstratosphere/source/fs/fs_sd_card.cpp @@ -124,4 +124,90 @@ namespace ams::fs { return inserted; } + Result GetSdCardSpeedMode(SdCardSpeedMode *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the speed mode. */ + s64 speed_mode = 0; + AMS_FS_R_TRY(device_operator->GetSdCardSpeedMode(std::addressof(speed_mode))); + + *out = static_cast(speed_mode); + R_SUCCEED(); + } + + Result GetSdCardCid(void *dst, size_t size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(dst != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the cid. */ + AMS_FS_R_TRY(device_operator->GetSdCardCid(sf::OutBuffer(dst, size), static_cast(size))); + + R_SUCCEED(); + } + + Result GetSdCardUserAreaSize(s64 *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the size. */ + AMS_FS_R_TRY(device_operator->GetSdCardUserAreaSize(out)); + + R_SUCCEED(); + } + + Result GetSdCardProtectedAreaSize(s64 *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the size. */ + AMS_FS_R_TRY(device_operator->GetSdCardProtectedAreaSize(out)); + + R_SUCCEED(); + } + + Result GetAndClearSdCardErrorInfo(StorageErrorInfo *out_sei, size_t *out_log_size, char *out_log_buffer, size_t log_buffer_size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out_sei != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_size != nullptr, fs::ResultNullptrArgument()); + AMS_FS_R_UNLESS(out_log_buffer != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the error info. */ + s64 log_size = 0; + AMS_FS_R_TRY(device_operator->GetAndClearSdCardErrorInfo(out_sei, std::addressof(log_size), sf::OutBuffer(out_log_buffer, log_buffer_size), static_cast(log_buffer_size))); + + *out_log_size = static_cast(log_size); + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp index 6b5c109ab..98860fe1f 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp +++ b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp @@ -33,6 +33,27 @@ namespace ams::fs::impl { R_RETURN(fsDeviceOperatorIsSdCardInserted(std::addressof(m_operator), out.GetPointer())); } + Result GetSdCardSpeedMode(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetSdCardSpeedMode(std::addressof(m_operator), out.GetPointer())); + } + + Result GetSdCardCid(ams::sf::OutBuffer out, s64 size) { + R_RETURN(fsDeviceOperatorGetSdCardCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); + } + + Result GetSdCardUserAreaSize(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetSdCardUserAreaSize(std::addressof(m_operator), out.GetPointer())); + } + + Result GetSdCardProtectedAreaSize(ams::sf::Out out) { + R_RETURN(fsDeviceOperatorGetSdCardProtectedAreaSize(std::addressof(m_operator), out.GetPointer())); + } + + Result GetAndClearSdCardErrorInfo(ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size) { + static_assert(sizeof(::FsStorageErrorInfo) == sizeof(fs::StorageErrorInfo)); + R_RETURN(fsDeviceOperatorGetAndClearSdCardErrorInfo(std::addressof(m_operator), reinterpret_cast<::FsStorageErrorInfo *>(out_sei.GetPointer()), out_size.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), size)); + } + Result GetMmcCid(ams::sf::OutBuffer out, s64 size) { R_RETURN(fsDeviceOperatorGetMmcCid(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); } @@ -45,6 +66,11 @@ namespace ams::fs::impl { R_RETURN(fsDeviceOperatorGetMmcPatrolCount(std::addressof(m_operator), out.GetPointer())); } + Result GetAndClearMmcErrorInfo(ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size) { + static_assert(sizeof(::FsStorageErrorInfo) == sizeof(fs::StorageErrorInfo)); + R_RETURN(fsDeviceOperatorGetAndClearMmcErrorInfo(std::addressof(m_operator), reinterpret_cast<::FsStorageErrorInfo *>(out_sei.GetPointer()), out_size.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), size)); + } + Result GetMmcExtendedCsd(ams::sf::OutBuffer out, s64 size) { R_RETURN(fsDeviceOperatorGetMmcExtendedCsd(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); } From 2ed8450446c88af403316790c578971961132ce3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 25 Oct 2023 14:21:27 -0700 Subject: [PATCH 065/238] erpt: SubmitFileSystemProxyErrorInfo --- .../stratosphere/fat/fat_file_system.hpp | 10 +-- .../include/stratosphere/fs/fs_error_info.hpp | 14 ++-- .../fssrv/fssrv_file_system_proxy_impl.hpp | 1 + .../fssrv/sf/fssrv_sf_i_file_system_proxy.hpp | 3 +- .../erpt/srv/erpt_srv_fs_info.os.horizon.cpp | 67 ++++++++++++++++++- .../source/fs/fs_error_info.cpp | 35 ++++++++++ .../source/fs/fs_remote_file_system_proxy.hpp | 5 ++ .../fssrv/fssrv_file_system_proxy_impl.cpp | 4 ++ 8 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 libraries/libstratosphere/source/fs/fs_error_info.cpp diff --git a/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp index 2be687b83..46212a109 100644 --- a/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp +++ b/libraries/libstratosphere/include/stratosphere/fat/fat_file_system.hpp @@ -23,7 +23,7 @@ namespace ams::fat { struct FatError { int error; int extra_error; - int device_id; + int drive_id; char name[FatErrorNameMaxLength]; u8 reserved[4]; }; @@ -31,15 +31,15 @@ namespace ams::fat { static_assert(util::is_pod::value); struct FatReportInfo1 { - u16 file_peak_open_count; - u16 directory_peak_open_count; + u16 open_file_peak_count; + u16 open_directory_peak_count; }; static_assert(sizeof(FatReportInfo1) == 4); static_assert(util::is_pod::value); struct FatReportInfo2 { - u16 unique_file_entry_peak_open_count; - u16 unique_directory_entry_peak_open_count; + u16 open_unique_file_entry_peak_count; + u16 open_unique_directory_entry_peak_count; }; static_assert(sizeof(FatReportInfo2) == 4); static_assert(util::is_pod::value); diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp index 71ed0d8d2..06044631e 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_error_info.hpp @@ -29,17 +29,17 @@ namespace ams::fs { static_assert(util::is_pod::value); struct FileSystemProxyErrorInfo { - u32 rom_fs_remont_for_data_corruption_count; + u32 rom_fs_remount_for_data_corruption_count; u32 rom_fs_unrecoverable_data_corruption_by_remount_count; fat::FatError fat_fs_error; u32 rom_fs_recovered_by_invalidate_cache_count; u32 save_data_index_count; - fat::FatReportInfo1 bis_system_report1; - fat::FatReportInfo1 bis_user_report1; - fat::FatReportInfo1 sd_card_report1; - fat::FatReportInfo2 bis_system_report2; - fat::FatReportInfo2 bis_user_report2; - fat::FatReportInfo2 sd_card_report2; + fat::FatReportInfo1 bis_system_fat_report_info_1; + fat::FatReportInfo1 bis_user_fat_report_info_1; + fat::FatReportInfo1 sd_card_fat_report_info_1; + fat::FatReportInfo2 bis_system_fat_report_info_2; + fat::FatReportInfo2 bis_user_fat_report_info_2; + fat::FatReportInfo2 sd_card_fat_report_info_2; u32 rom_fs_deep_retry_start_count; u32 rom_fs_unrecoverable_by_game_card_access_failed_count; fat::FatSafeInfo bis_system_fat_safe_info; diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp index 64d43c1d2..e8f1be65d 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -121,6 +121,7 @@ namespace ams::fssrv { Result IsSignedSystemPartitionOnSdCardValid(ams::sf::Out out); Result OpenAccessFailureDetectionEventNotifier(); /* ... */ + Result GetAndClearErrorInfo(ams::sf::Out out); Result RegisterProgramIndexMapInfo(const ams::sf::InBuffer &buffer, s32 count); Result SetBisRootForHost(u32 id, const fssrv::sf::FspPath &path); Result SetSaveDataSize(s64 size, s64 journal_size); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp index ba41abb80..6d00f9bf8 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp @@ -20,6 +20,7 @@ #include #include #include +#include /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_FILE_SYSTEM_PROXY_INTERFACE_INFO(C, H) \ @@ -125,7 +126,7 @@ /* AMS_SF_METHOD_INFO(C, H, 702, Result, IsAccessFailureDetected, (), (), hos::Version_5_0_0) */ \ /* AMS_SF_METHOD_INFO(C, H, 710, Result, ResolveAccessFailure, (), (), hos::Version_5_0_0) */ \ /* AMS_SF_METHOD_INFO(C, H, 720, Result, AbandonAccessFailure, (), (), hos::Version_5_0_0) */ \ - /* AMS_SF_METHOD_INFO(C, H, 800, Result, GetAndClearErrorInfo, (), (), hos::Version_2_0_0) */ \ + AMS_SF_METHOD_INFO(C, H, 800, Result, GetAndClearErrorInfo, (ams::sf::Out out), (out), hos::Version_2_0_0) \ AMS_SF_METHOD_INFO(C, H, 810, Result, RegisterProgramIndexMapInfo, (const ams::sf::InBuffer &buffer, s32 count), (buffer, count), hos::Version_7_0_0) \ AMS_SF_METHOD_INFO(C, H, 1000, Result, SetBisRootForHost, (u32 id, const fssrv::sf::FspPath &path), (id, path), hos::Version_Min, hos::Version_9_2_0) \ AMS_SF_METHOD_INFO(C, H, 1001, Result, SetSaveDataSize, (s64 size, s64 journal_size), (size, journal_size)) \ diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp index 0290b2fd3..cdb70324b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -318,7 +318,72 @@ namespace ams::erpt::srv { } Result SubmitFileSystemErrorInfo() { - /* TODO */ + /* Get the fsp error info. */ + fs::FileSystemProxyErrorInfo ei = {}; + if (R_SUCCEEDED(fs::GetAndClearFileSystemProxyErrorInfo(std::addressof(ei)))) { + /* Submit FsProxyErrorInfo. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_FsProxyErrorInfo, fat::FatErrorNameMaxLength); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_FsRemountForDataCorruptCount, ei.rom_fs_remount_for_data_corruption_count)); + R_ABORT_UNLESS(record->Add(FieldId_FsRemountForDataCorruptRetryOutCount, ei.rom_fs_unrecoverable_data_corruption_by_remount_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsError, ei.fat_fs_error.error)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsExtraError, ei.fat_fs_error.extra_error)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsErrorDrive, ei.fat_fs_error.drive_id)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsErrorName, ei.fat_fs_error.name, fat::FatErrorNameMaxLength)); + + R_ABORT_UNLESS(record->Add(FieldId_FsRecoveredByInvalidateCacheCount, ei.rom_fs_recovered_by_invalidate_cache_count)); + R_ABORT_UNLESS(record->Add(FieldId_FsSaveDataIndexCount, ei.save_data_index_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFilePeakOpenCount, ei.bis_system_fat_report_info_1.open_file_peak_count)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemDirectoryPeakOpenCount, ei.bis_system_fat_report_info_1.open_directory_peak_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFilePeakOpenCount, ei.bis_user_fat_report_info_1.open_file_peak_count)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserDirectoryPeakOpenCount, ei.bis_user_fat_report_info_1.open_directory_peak_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardFilePeakOpenCount, ei.sd_card_fat_report_info_1.open_file_peak_count)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardDirectoryPeakOpenCount, ei.sd_card_fat_report_info_1.open_directory_peak_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemUniqueFileEntryPeakOpenCount, ei.bis_system_fat_report_info_2.open_unique_file_entry_peak_count)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, ei.bis_system_fat_report_info_2.open_unique_directory_entry_peak_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserUniqueFileEntryPeakOpenCount, ei.bis_user_fat_report_info_2.open_unique_file_entry_peak_count)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserUniqueDirectoryEntryPeakOpenCount, ei.bis_user_fat_report_info_2.open_unique_directory_entry_peak_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardUniqueFileEntryPeakOpenCount, ei.sd_card_fat_report_info_2.open_unique_file_entry_peak_count)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsSdCardUniqueDirectoryEntryPeakOpenCount, ei.sd_card_fat_report_info_2.open_unique_directory_entry_peak_count)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + + /* Submit FsProxyErrorInfo2. */ + { + /* Create a record. */ + auto record = std::make_unique(CategoryId_FsProxyErrorInfo2, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_FsDeepRetryStartCount, ei.rom_fs_deep_retry_start_count)); + R_ABORT_UNLESS(record->Add(FieldId_FsUnrecoverableByGameCardAccessFailedCount, ei.rom_fs_unrecoverable_by_game_card_access_failed_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFatSafeControlResult, static_cast(ei.bis_system_fat_safe_info.result))); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFatErrorNumber, ei.bis_system_fat_safe_info.error_number)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisSystemFatSafeErrorNumber, ei.bis_system_fat_safe_info.safe_error_number)); + + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFatSafeControlResult, static_cast(ei.bis_user_fat_safe_info.result))); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFatErrorNumber, ei.bis_user_fat_safe_info.error_number)); + R_ABORT_UNLESS(record->Add(FieldId_FatFsBisUserFatSafeErrorNumber, ei.bis_user_fat_safe_info.safe_error_number)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + } + R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fs/fs_error_info.cpp b/libraries/libstratosphere/source/fs/fs_error_info.cpp new file mode 100644 index 000000000..a6dab78e4 --- /dev/null +++ b/libraries/libstratosphere/source/fs/fs_error_info.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "fsa/fs_mount_utils.hpp" +#include "impl/fs_file_system_proxy_service_object.hpp" +#include "impl/fs_file_system_service_object_adapter.hpp" + +namespace ams::fs { + + Result GetAndClearFileSystemProxyErrorInfo(FileSystemProxyErrorInfo *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Get the error info. */ + AMS_FS_R_TRY(fsp->GetAndClearErrorInfo(out)); + + R_SUCCEED(); + } + +} diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp index ae9b8b492..4a284bd1c 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp @@ -389,6 +389,11 @@ namespace ams::fs { /* ... */ + Result GetAndClearErrorInfo(ams::sf::Out out) { + static_assert(sizeof(fs::FileSystemProxyErrorInfo) == sizeof(::FsFileSystemProxyErrorInfo)); + R_RETURN(::fsGetAndClearErrorInfo(reinterpret_cast<::FsFileSystemProxyErrorInfo *>(out.GetPointer()))); + } + Result RegisterProgramIndexMapInfo(const ams::sf::InBuffer &buffer, s32 count) { AMS_ABORT("TODO"); } diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp index eabc29e34..34df93942 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -373,6 +373,10 @@ namespace ams::fssrv { /* ... */ + Result FileSystemProxyImpl::GetAndClearErrorInfo(ams::sf::Out out) { + AMS_ABORT("TODO"); + } + Result FileSystemProxyImpl::RegisterProgramIndexMapInfo(const ams::sf::InBuffer &buffer, s32 count) { AMS_ABORT("TODO"); } From 274f6b63f2744b9f4ea7efdc3c25c208874d1041 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 25 Oct 2023 16:08:12 -0700 Subject: [PATCH 066/238] erpt: add remaining SubmitFsInfo helpers --- .../include/stratosphere/fs/fs_game_card.hpp | 38 ++++++++ .../stratosphere/fs/fs_memory_report_info.hpp | 42 +++++++++ .../fssrv/fssrv_file_system_proxy_impl.hpp | 1 + .../fssrv/sf/fssrv_sf_i_device_operator.hpp | 6 +- .../fssrv/sf/fssrv_sf_i_file_system_proxy.hpp | 3 +- .../include/stratosphere/gc.hpp | 1 + .../include/stratosphere/gc/gc.hpp | 30 ++++++ .../include/stratosphere/gc/impl/gc_types.hpp | 49 ++++++++++ .../erpt/srv/erpt_srv_fs_info.os.horizon.cpp | 91 ++++++++++++++++++- .../source/fs/fs_game_card.cpp | 61 +++++++++++++ .../source/fs/fs_memory_report_info.cpp | 35 +++++++ .../source/fs/fs_remote_file_system_proxy.hpp | 5 + .../fs/impl/fs_remote_device_operator.hpp | 13 +++ .../fssrv/fssrv_file_system_proxy_impl.cpp | 4 + 14 files changed, 374 insertions(+), 5 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/gc/gc.hpp create mode 100644 libraries/libstratosphere/source/fs/fs_memory_report_info.cpp diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp index 2ebb52fa6..ccfc0fc8f 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_game_card.hpp @@ -19,6 +19,9 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: Unknown */ + constexpr inline size_t GameCardCidSize = 0x10; + constexpr inline size_t GameCardDeviceIdSize = 0x10; + enum class GameCardPartition { Update = 0, Normal = 1, @@ -47,9 +50,44 @@ namespace ams::fs { Terra = 1, }; + struct GameCardErrorReportInfo { + u16 game_card_crc_error_num; + u16 reserved1; + u16 asic_crc_error_num; + u16 reserved2; + u16 refresh_num; + u16 reserved3; + u16 retry_limit_out_num; + u16 timeout_retry_num; + u16 asic_reinitialize_failure_detail; + u16 insertion_count; + u16 removal_count; + u16 asic_reinitialize_num; + u32 initialize_count; + u16 asic_reinitialize_failure_num; + u16 awaken_failure_num; + u16 reserved4; + u16 refresh_succeeded_count; + u32 last_read_error_page_address; + u32 last_read_error_page_count; + u32 awaken_count; + u32 read_count_from_insert; + u32 read_count_from_awaken; + u8 reserved5[8]; + }; + static_assert(util::is_pod::value); + static_assert(sizeof(GameCardErrorReportInfo) == 0x40); + using GameCardHandle = u32; Result GetGameCardHandle(GameCardHandle *out); Result MountGameCardPartition(const char *name, GameCardHandle handle, GameCardPartition partition); + Result GetGameCardCid(void *dst, size_t size); + Result GetGameCardDeviceId(void *dst, size_t size); + + Result GetGameCardErrorReportInfo(GameCardErrorReportInfo *out); + + bool IsGameCardInserted(); + } diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp new file mode 100644 index 000000000..3f72e819e --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_memory_report_info.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::fs { + + struct MemoryReportInfo { + u64 pooled_buffer_peak_free_size; + u64 pooled_buffer_retried_count; + u64 pooled_buffer_reduce_allocation_count; + u64 buffer_manager_peak_free_size; + u64 buffer_manager_retried_count; + u64 exp_heap_peak_free_size; + u64 buffer_pool_peak_free_size; + u64 patrol_read_allocate_buffer_success_count; + u64 patrol_read_allocate_buffer_failure_count; + u64 buffer_manager_peak_total_allocatable_size; + u64 buffer_pool_max_allocate_size; + u64 pooled_buffer_failed_ideal_allocation_count_on_async_access; + + u8 reserved[0x20]; + }; + static_assert(sizeof(MemoryReportInfo) == 0x80); + static_assert(util::is_pod::value); + + Result GetAndClearMemoryReportInfo(MemoryReportInfo *out); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp index e8f1be65d..f5373ac8d 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -132,6 +132,7 @@ namespace ams::fssrv { Result OutputAccessLogToSdCard(const ams::sf::InBuffer &buf); Result RegisterUpdatePartition(); Result OpenRegisteredUpdatePartition(ams::sf::Out> out); + Result GetAndClearMemoryReportInfo(ams::sf::Out out); /* ... */ Result GetProgramIndexForAccessLog(ams::sf::Out out_idx, ams::sf::Out out_count); Result GetFsStackUsage(ams::sf::Out out, u32 type); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp index 4d6fa71ef..c251223c5 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_device_operator.hpp @@ -17,6 +17,7 @@ #include #include #include +#include /* TODO */ /* ACCURATE_TO_VERSION: 13.4.0.0 */ @@ -33,6 +34,9 @@ AMS_SF_METHOD_INFO(C, H, 113, Result, GetAndClearMmcErrorInfo, (ams::sf::Out out_sei, ams::sf::Out out_size, ams::sf::OutBuffer out_buf, s64 size), (out_sei, out_size, out_buf, size)) \ AMS_SF_METHOD_INFO(C, H, 114, Result, GetMmcExtendedCsd, (ams::sf::OutBuffer out, s64 size), (out, size)) \ AMS_SF_METHOD_INFO(C, H, 200, Result, IsGameCardInserted, (ams::sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) + AMS_SF_METHOD_INFO(C, H, 202, Result, GetGameCardHandle, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 208, Result, GetGameCardIdSet, (ams::sf::OutBuffer out, s64 size), (out, size)) \ + AMS_SF_METHOD_INFO(C, H, 217, Result, GetGameCardErrorReportInfo, (ams::sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 218, Result, GetGameCardDeviceId, (ams::sf::OutBuffer out, s64 size), (out, size)) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IDeviceOperator, AMS_FSSRV_I_DEVICE_OPERATOR_INTERFACE_INFO, 0x1484E21C) diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp index 6d00f9bf8..5ccee0cdf 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy.hpp @@ -21,6 +21,7 @@ #include #include #include +#include /* ACCURATE_TO_VERSION: 13.4.0.0 */ #define AMS_FSSRV_I_FILE_SYSTEM_PROXY_INTERFACE_INFO(C, H) \ @@ -137,7 +138,7 @@ AMS_SF_METHOD_INFO(C, H, 1006, Result, OutputAccessLogToSdCard, (const ams::sf::InBuffer &buf), (buf)) \ AMS_SF_METHOD_INFO(C, H, 1007, Result, RegisterUpdatePartition, (), (), hos::Version_4_0_0) \ AMS_SF_METHOD_INFO(C, H, 1008, Result, OpenRegisteredUpdatePartition, (ams::sf::Out> out), (out), hos::Version_4_0_0) \ - /* AMS_SF_METHOD_INFO(C, H, 1009, Result, GetAndClearMemoryReportInfo, (ams::sf::Out out), (out), hos::Version_4_0_0) */ \ + AMS_SF_METHOD_INFO(C, H, 1009, Result, GetAndClearMemoryReportInfo, (ams::sf::Out out), (out), hos::Version_4_0_0) \ /* AMS_SF_METHOD_INFO(C, H, 1010, Result, SetDataStorageRedirectTarget, (), (), hos::Version_5_1_0, hos::Version_6_2_0) */ \ AMS_SF_METHOD_INFO(C, H, 1011, Result, GetProgramIndexForAccessLog, (ams::sf::Out out_idx, ams::sf::Out out_count), (out_idx, out_count), hos::Version_7_0_0) \ AMS_SF_METHOD_INFO(C, H, 1012, Result, GetFsStackUsage, (ams::sf::Out out, u32 type), (out, type), hos::Version_9_0_0) \ diff --git a/libraries/libstratosphere/include/stratosphere/gc.hpp b/libraries/libstratosphere/include/stratosphere/gc.hpp index 8eb6b8ec8..80007a74d 100644 --- a/libraries/libstratosphere/include/stratosphere/gc.hpp +++ b/libraries/libstratosphere/include/stratosphere/gc.hpp @@ -18,3 +18,4 @@ #include #include #include +#include diff --git a/libraries/libstratosphere/include/stratosphere/gc/gc.hpp b/libraries/libstratosphere/include/stratosphere/gc/gc.hpp new file mode 100644 index 000000000..797bb8bb4 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/gc/gc.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::gc { + + struct GameCardIdSet { + gc::impl::CardId1 id1; + gc::impl::CardId2 id2; + gc::impl::CardId3 id3; + }; + static_assert(util::is_pod::value); + static_assert(sizeof(GameCardIdSet) == 0xC); + +} diff --git a/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp b/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp index 98b56c8b2..a6b1043f8 100644 --- a/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/gc/impl/gc_types.hpp @@ -76,6 +76,11 @@ namespace ams::gc::impl { static_assert(util::is_pod::value); static_assert(sizeof(CardHeaderEncryptedData) == 0x70); + enum MakerCodeForCardId1 : u8 { + MakerCodeForCardId1_MegaChips = 0xC2, + MakerCodeForCardId1_Lapis = 0xAE, + }; + enum MemoryCapacity : u8 { MemoryCapacity_1GB = 0xFA, MemoryCapacity_2GB = 0xF8, @@ -85,6 +90,33 @@ namespace ams::gc::impl { MemoryCapacity_32GB = 0xE2, }; + enum MemoryType : u8 { + MemoryType_T1RomFast = 0x01, + MemoryType_T2RomFast = 0x02, + MemoryType_T1NandFast = 0x09, + MemoryType_T2NandFast = 0x0A, + MemoryType_T1RomLate = 0x21, + MemoryType_T2RomLate = 0x22, + MemoryType_T1NandLate = 0x29, + MemoryType_T2NandLate = 0x2A, + }; + + enum CardSecurityNumber : u8 { + CardSecurityNumber_0 = 0x00, + CardSecurityNumber_1 = 0x01, + CardSecurityNumber_2 = 0x02, + CardSecurityNumber_3 = 0x03, + CardSecurityNumber_4 = 0x04, + }; + + enum CardType : u8 { + CardType_Rom = 0x00, + CardType_Writable_Dev_T1 = 0x01, + CardType_Writable_Prod_T1 = 0x02, + CardType_Writable_Dev_T2 = 0x03, + CardType_Writable_Prod_T2 = 0x04, + }; + enum AccessControl1ClockRate : u32 { AccessControl1ClockRate_25MHz = 0x00A10011, AccessControl1ClockRate_50MHz = 0x00A10010, @@ -95,6 +127,23 @@ namespace ams::gc::impl { SelSec_T2 = 2, }; + struct CardId1 { + MakerCodeForCardId1 maker_code; + MemoryCapacity memory_capacity; + u8 reserved; + MemoryType memory_type; + }; + + struct CardId2 { + CardSecurityNumber card_security_number; + CardType card_type; + u8 reserved[2]; + }; + + struct CardId3 { + u8 reserved[4]; + }; + struct CardHeader { static constexpr u32 Magic = util::FourCC<'H','E','A','D'>::Code; diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp index cdb70324b..1b7840783 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_fs_info.os.horizon.cpp @@ -308,12 +308,66 @@ namespace ams::erpt::srv { } Result SubmitGameCardDetailInfo() { - /* TODO */ + /* Create a record. */ + auto record = std::make_unique(CategoryId_GameCardCIDInfo, fs::GameCardCidSize + fs::GameCardDeviceIdSize); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add the game card cid. */ + { + u8 gc_cid[fs::GameCardCidSize] = {}; + if (fs::IsGameCardInserted() && R_SUCCEEDED(fs::GetGameCardCid(gc_cid, sizeof(gc_cid)))) { + /* Add the cid. */ + R_ABORT_UNLESS(record->Add(FieldId_GameCardCID, gc_cid, sizeof(gc_cid))); + } + } + + /* Add the game card device id. */ + { + u8 gc_device_id[fs::GameCardDeviceIdSize] = {}; + if (fs::IsGameCardInserted() && R_SUCCEEDED(fs::GetGameCardDeviceId(gc_device_id, sizeof(gc_device_id)))) { + /* Add the cid. */ + R_ABORT_UNLESS(record->Add(FieldId_GameCardDeviceId, gc_device_id, sizeof(gc_device_id))); + } + } + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + R_SUCCEED(); } Result SubmitGameCardErrorInfo() { - /* TODO */ + /* Get the game card error info. */ + fs::GameCardErrorReportInfo ei = {}; + if (R_SUCCEEDED(fs::GetGameCardErrorReportInfo(std::addressof(ei)))) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_GameCardErrorInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_GameCardCrcErrorCount, static_cast(ei.game_card_crc_error_num))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicCrcErrorCount, static_cast(ei.asic_crc_error_num))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardRefreshCount, static_cast(ei.refresh_num))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardReadRetryCount, static_cast(ei.retry_limit_out_num))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardTimeoutRetryErrorCount, static_cast(ei.timeout_retry_num))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardInsertionCount, static_cast(ei.insertion_count))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardRemovalCount, static_cast(ei.removal_count))); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicInitializeCount, ei.initialize_count)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicReinitializeCount, ei.asic_reinitialize_num)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicReinitializeFailureCount, ei.asic_reinitialize_failure_num)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAsicReinitializeFailureDetail, ei.asic_reinitialize_failure_detail)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardRefreshSuccessCount, ei.refresh_succeeded_count)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAwakenCount, ei.awaken_count)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardAwakenFailureCount, ei.awaken_failure_num)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromInsert, ei.read_count_from_insert)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address)); + R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + R_SUCCEED(); } @@ -388,7 +442,38 @@ namespace ams::erpt::srv { } Result SubmitMemoryReportInfo() { - /* TODO */ + /* Get the memory report info. */ + fs::MemoryReportInfo mri = {}; + if (R_SUCCEEDED(fs::GetAndClearMemoryReportInfo(std::addressof(mri)))) { + /* Create a record. */ + auto record = std::make_unique(CategoryId_FsMemoryInfo, 0); + R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); + + /* Add fields. */ + R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferPeakFreeSize, mri.pooled_buffer_peak_free_size)); + R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferRetriedCount, mri.pooled_buffer_retried_count)); + R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferReduceAllocationCount, mri.pooled_buffer_reduce_allocation_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FsBufferManagerPeakFreeSize, mri.buffer_manager_peak_free_size)); + R_ABORT_UNLESS(record->Add(FieldId_FsBufferManagerRetriedCount, mri.buffer_manager_retried_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FsExpHeapPeakFreeSize, mri.exp_heap_peak_free_size)); + + R_ABORT_UNLESS(record->Add(FieldId_FsBufferPoolPeakFreeSize, mri.buffer_pool_peak_free_size)); + + R_ABORT_UNLESS(record->Add(FieldId_FsPatrolReadAllocateBufferSuccessCount, mri.patrol_read_allocate_buffer_success_count)); + R_ABORT_UNLESS(record->Add(FieldId_FsPatrolReadAllocateBufferFailureCount, mri.patrol_read_allocate_buffer_failure_count)); + + R_ABORT_UNLESS(record->Add(FieldId_FsBufferManagerPeakTotalAllocatableSize, mri.buffer_manager_peak_total_allocatable_size)); + + R_ABORT_UNLESS(record->Add(FieldId_FsBufferPoolMaxAllocateSize, mri.buffer_pool_max_allocate_size)); + + R_ABORT_UNLESS(record->Add(FieldId_FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, mri.pooled_buffer_failed_ideal_allocation_count_on_async_access)); + + /* Submit the record. */ + R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record))); + } + R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/fs/fs_game_card.cpp b/libraries/libstratosphere/source/fs/fs_game_card.cpp index 023185c62..08e88ecb1 100644 --- a/libraries/libstratosphere/source/fs/fs_game_card.cpp +++ b/libraries/libstratosphere/source/fs/fs_game_card.cpp @@ -100,4 +100,65 @@ namespace ams::fs { R_SUCCEED(); } + bool IsGameCardInserted() { + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_ABORT_UNLESS(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get insertion status. */ + bool inserted; + AMS_FS_R_ABORT_UNLESS(device_operator->IsGameCardInserted(std::addressof(inserted))); + + return inserted; + } + + Result GetGameCardCid(void *dst, size_t size) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(size >= sizeof(gc::GameCardIdSet), fs::ResultInvalidSize()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the id set. */ + gc::GameCardIdSet gc_id_set; + AMS_FS_R_TRY(device_operator->GetGameCardIdSet(sf::OutBuffer(std::addressof(gc_id_set), sizeof(gc_id_set)), static_cast(sizeof(gc_id_set)))); + + /* Copy the id set to output. */ + std::memcpy(dst, std::addressof(gc_id_set), sizeof(gc_id_set)); + + R_SUCCEED(); + + } + + Result GetGameCardDeviceId(void *dst, size_t size) { + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the cid. */ + AMS_FS_R_TRY(device_operator->GetGameCardDeviceId(sf::OutBuffer(dst, size), static_cast(size))); + + R_SUCCEED(); + } + + Result GetGameCardErrorReportInfo(GameCardErrorReportInfo *out) { + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Open a device operator. */ + sf::SharedPointer device_operator; + AMS_FS_R_TRY(fsp->OpenDeviceOperator(std::addressof(device_operator))); + + /* Get the error report info. */ + AMS_FS_R_TRY(device_operator->GetGameCardErrorReportInfo(out)); + + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/fs/fs_memory_report_info.cpp b/libraries/libstratosphere/source/fs/fs_memory_report_info.cpp new file mode 100644 index 000000000..f858aea33 --- /dev/null +++ b/libraries/libstratosphere/source/fs/fs_memory_report_info.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "fsa/fs_mount_utils.hpp" +#include "impl/fs_file_system_proxy_service_object.hpp" +#include "impl/fs_file_system_service_object_adapter.hpp" + +namespace ams::fs { + + Result GetAndClearMemoryReportInfo(MemoryReportInfo *out) { + /* Check pre-conditions. */ + AMS_FS_R_UNLESS(out != nullptr, fs::ResultNullptrArgument()); + + auto fsp = impl::GetFileSystemProxyServiceObject(); + + /* Get the memory report info. */ + AMS_FS_R_TRY(fsp->GetAndClearMemoryReportInfo(out)); + + R_SUCCEED(); + } + +} diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp index 4a284bd1c..6cfcd8ab4 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy.hpp @@ -434,6 +434,11 @@ namespace ams::fs { AMS_ABORT("TODO"); } + Result GetAndClearMemoryReportInfo(ams::sf::Out out) { + static_assert(sizeof(fs::MemoryReportInfo) == sizeof(::FsMemoryReportInfo)); + R_RETURN(::fsGetAndClearMemoryReportInfo(reinterpret_cast<::FsMemoryReportInfo *>(out.GetPointer()))); + } + /* ... */ Result GetProgramIndexForAccessLog(ams::sf::Out out_idx, ams::sf::Out out_count) { diff --git a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp index 98860fe1f..d3f656c20 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp +++ b/libraries/libstratosphere/source/fs/impl/fs_remote_device_operator.hpp @@ -83,6 +83,19 @@ namespace ams::fs::impl { static_assert(sizeof(::FsGameCardHandle) == sizeof(u32)); R_RETURN(fsDeviceOperatorGetGameCardHandle(std::addressof(m_operator), reinterpret_cast<::FsGameCardHandle *>(out.GetPointer()))); } + + Result GetGameCardIdSet(ams::sf::OutBuffer out, s64 size) { + R_RETURN(fsDeviceOperatorGetGameCardIdSet(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); + } + + Result GetGameCardErrorReportInfo(ams::sf::Out out) { + static_assert(sizeof(::FsGameCardErrorReportInfo) == sizeof(fs::GameCardErrorReportInfo)); + R_RETURN(fsDeviceOperatorGetGameCardErrorReportInfo(std::addressof(m_operator), reinterpret_cast<::FsGameCardErrorReportInfo *>(out.GetPointer()))); + } + + Result GetGameCardDeviceId(ams::sf::OutBuffer out, s64 size) { + R_RETURN(fsDeviceOperatorGetGameCardDeviceId(std::addressof(m_operator), out.GetPointer(), out.GetSize(), size)); + } }; static_assert(fssrv::sf::IsIDeviceOperator); #endif diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp index 34df93942..39b784d52 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -417,6 +417,10 @@ namespace ams::fssrv { AMS_ABORT("TODO"); } + Result FileSystemProxyImpl::GetAndClearMemoryReportInfo(ams::sf::Out out) { + AMS_ABORT("TODO"); + } + /* ... */ Result FileSystemProxyImpl::GetProgramIndexForAccessLog(ams::sf::Out out_idx, ams::sf::Out out_count) { From 0c3afff4d314c2ecc9830e85b830ad6d37041d7a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 26 Oct 2023 14:44:32 -0700 Subject: [PATCH 067/238] pm: update to reflect 17.0.0 internal design changes --- stratosphere/pm/pm.json | 2 +- .../pm/source/impl/pm_process_info.cpp | 81 +++- .../pm/source/impl/pm_process_info.hpp | 10 +- .../pm/source/impl/pm_process_manager.cpp | 352 +++--------------- .../pm/source/impl/pm_process_manager.hpp | 9 - .../pm/source/impl/pm_process_tracker.cpp | 193 ++++++++++ .../pm/source/impl/pm_process_tracker.hpp | 57 +++ .../{pm_resource_manager.cpp => pm_spec.cpp} | 33 +- .../{pm_resource_manager.hpp => pm_spec.hpp} | 12 +- .../pm/source/pm_boot_mode_service.cpp | 2 +- .../pm/source/pm_debug_monitor_service.cpp | 3 +- stratosphere/pm/source/pm_info_service.cpp | 5 +- stratosphere/pm/source/pm_shell_service.cpp | 1 + 13 files changed, 428 insertions(+), 332 deletions(-) create mode 100644 stratosphere/pm/source/impl/pm_process_tracker.cpp create mode 100644 stratosphere/pm/source/impl/pm_process_tracker.hpp rename stratosphere/pm/source/impl/{pm_resource_manager.cpp => pm_spec.cpp} (93%) rename stratosphere/pm/source/impl/{pm_resource_manager.hpp => pm_spec.hpp} (76%) diff --git a/stratosphere/pm/pm.json b/stratosphere/pm/pm.json index f999cdcc7..005504b72 100644 --- a/stratosphere/pm/pm.json +++ b/stratosphere/pm/pm.json @@ -1,7 +1,7 @@ { "name": "ProcessManager", "title_id": "0x0100000000000003", - "main_thread_stack_size": "0x00002000", + "main_thread_stack_size": "0x00003000", "main_thread_priority": 49, "default_cpu_id": 3, "process_category": 1, diff --git a/stratosphere/pm/source/impl/pm_process_info.cpp b/stratosphere/pm/source/impl/pm_process_info.cpp index a867cac5b..90373b55a 100644 --- a/stratosphere/pm/source/impl/pm_process_info.cpp +++ b/stratosphere/pm/source/impl/pm_process_info.cpp @@ -18,6 +18,64 @@ namespace ams::pm::impl { + namespace { + + template + class ProcessInfoAllocator { + NON_COPYABLE(ProcessInfoAllocator); + NON_MOVEABLE(ProcessInfoAllocator); + static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small."); + private: + util::TypedStorage m_process_info_storages[MaxProcessInfos]{}; + bool m_process_info_allocated[MaxProcessInfos]{}; + os::SdkMutex m_lock{}; + private: + constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const { + return process_info - GetPointer(m_process_info_storages[0]); + } + public: + constexpr ProcessInfoAllocator() = default; + + template + ProcessInfo *AllocateProcessInfo(Args &&... args) { + std::scoped_lock lk(m_lock); + + for (size_t i = 0; i < MaxProcessInfos; i++) { + if (!m_process_info_allocated[i]) { + m_process_info_allocated[i] = true; + + std::memset(m_process_info_storages + i, 0, sizeof(m_process_info_storages[i])); + + return util::ConstructAt(m_process_info_storages[i], std::forward(args)...); + } + } + + return nullptr; + } + + void FreeProcessInfo(ProcessInfo *process_info) { + std::scoped_lock lk(m_lock); + + const size_t index = this->GetProcessInfoIndex(process_info); + AMS_ABORT_UNLESS(index < MaxProcessInfos); + AMS_ABORT_UNLESS(m_process_info_allocated[index]); + + util::DestroyAt(m_process_info_storages[index]); + m_process_info_allocated[index] = false; + } + }; + + /* Process lists. */ + constinit ProcessList g_process_list; + constinit ProcessList g_exit_list; + + /* Process Info Allocation. */ + /* Note: The kernel slabheap is size 0x50 -- we allow slightly larger to account for the dead process list. */ + constexpr size_t MaxProcessCount = 0x60; + constinit ProcessInfoAllocator g_process_info_allocator; + + } + ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : m_process_id(pid), m_pin_id(pin), m_loc(l), m_status(s), m_handle(h), m_state(svc::ProcessState_Created), m_flags(0) { os::InitializeMultiWaitHolder(std::addressof(m_multi_wait_holder), m_handle); os::SetMultiWaitHolderUserData(std::addressof(m_multi_wait_holder), reinterpret_cast(this)); @@ -37,10 +95,27 @@ namespace ams::pm::impl { /* Close the process's handle. */ os::CloseNativeHandle(m_handle); m_handle = os::InvalidNativeHandle; - - /* Unlink the process from its multi wait. */ - os::UnlinkMultiWaitHolder(std::addressof(m_multi_wait_holder)); } } + ProcessListAccessor GetProcessList() { + return ProcessListAccessor(g_process_list); + } + + ProcessListAccessor GetExitList() { + return ProcessListAccessor(g_exit_list); + } + + ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status) { + return g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status); + } + + void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info) { + /* Remove the process from the list. */ + list->Remove(process_info); + + /* Delete the process. */ + g_process_info_allocator.FreeProcessInfo(process_info); + } + } diff --git a/stratosphere/pm/source/impl/pm_process_info.hpp b/stratosphere/pm/source/impl/pm_process_info.hpp index f89403767..f2dae02ae 100644 --- a/stratosphere/pm/source/impl/pm_process_info.hpp +++ b/stratosphere/pm/source/impl/pm_process_info.hpp @@ -64,8 +64,8 @@ namespace ams::pm::impl { ~ProcessInfo(); void Cleanup(); - void LinkToMultiWait(os::MultiWaitType &multi_wait) { - os::LinkMultiWaitHolder(std::addressof(multi_wait), std::addressof(m_multi_wait_holder)); + os::MultiWaitHolderType *GetMultiWaitHolder() { + return std::addressof(m_multi_wait_holder); } os::NativeHandle GetHandle() const { @@ -232,4 +232,10 @@ namespace ams::pm::impl { } }; + ProcessListAccessor GetProcessList(); + ProcessListAccessor GetExitList(); + + ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status); + void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info); + } diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 036814f66..32ef0feac 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -15,9 +15,9 @@ */ #include #include "pm_process_manager.hpp" -#include "pm_resource_manager.hpp" - +#include "pm_process_tracker.hpp" #include "pm_process_info.hpp" +#include "pm_spec.hpp" namespace ams::pm::impl { @@ -29,13 +29,7 @@ namespace ams::pm::impl { HookType_Application = (1 << 1), }; - struct LaunchProcessArgs { - os::ProcessId *out_process_id; - ncm::ProgramLocation location; - u32 flags; - }; - -#define GET_FLAG_MASK(flag) (hos_version >= hos::Version_5_0_0 ? static_cast(LaunchFlags_##flag) : static_cast(LaunchFlagsDeprecated_##flag)) + #define GET_FLAG_MASK(flag) (hos_version >= hos::Version_5_0_0 ? static_cast(LaunchFlags_##flag) : static_cast(LaunchFlagsDeprecated_##flag)) inline bool ShouldSignalOnExit(u32 launch_flags) { const auto hos_version = hos::GetVersion(); @@ -70,115 +64,26 @@ namespace ams::pm::impl { return launch_flags & GET_FLAG_MASK(DisableAslr); } -#undef GET_FLAG_MASK - - template - class ProcessInfoAllocator { - NON_COPYABLE(ProcessInfoAllocator); - NON_MOVEABLE(ProcessInfoAllocator); - static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small."); - private: - util::TypedStorage m_process_info_storages[MaxProcessInfos]{}; - bool m_process_info_allocated[MaxProcessInfos]{}; - os::SdkMutex m_lock{}; - private: - constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const { - return process_info - GetPointer(m_process_info_storages[0]); - } - public: - constexpr ProcessInfoAllocator() = default; - - template - ProcessInfo *AllocateProcessInfo(Args &&... args) { - std::scoped_lock lk(m_lock); - - for (size_t i = 0; i < MaxProcessInfos; i++) { - if (!m_process_info_allocated[i]) { - m_process_info_allocated[i] = true; - - std::memset(m_process_info_storages + i, 0, sizeof(m_process_info_storages[i])); - - return util::ConstructAt(m_process_info_storages[i], std::forward(args)...); - } - } - - return nullptr; - } - - void FreeProcessInfo(ProcessInfo *process_info) { - std::scoped_lock lk(m_lock); - - const size_t index = this->GetProcessInfoIndex(process_info); - AMS_ABORT_UNLESS(index < MaxProcessInfos); - AMS_ABORT_UNLESS(m_process_info_allocated[index]); - - util::DestroyAt(m_process_info_storages[index]); - m_process_info_allocated[index] = false; - } - }; + #undef GET_FLAG_MASK /* Process Tracking globals. */ - void ProcessTrackingMain(void *); - - constinit os::ThreadType g_process_track_thread; - alignas(os::ThreadStackAlignment) constinit u8 g_process_track_thread_stack[16_KB]; - - /* Process lists. */ - constinit ProcessList g_process_list; - constinit ProcessList g_dead_process_list; - - /* Process Info Allocation. */ - /* Note: The kernel slabheap is size 0x50 -- we allow slightly larger to account for the dead process list. */ - constexpr size_t MaxProcessCount = 0x60; - constinit ProcessInfoAllocator g_process_info_allocator; + constinit ProcessTracker g_process_tracker; + alignas(os::ThreadStackAlignment) constinit u8 g_process_track_thread_stack[8_KB]; /* Global events. */ - constinit os::SystemEventType g_process_event; constinit os::SystemEventType g_hook_to_create_process_event; constinit os::SystemEventType g_hook_to_create_application_process_event; constinit os::SystemEventType g_boot_finished_event; - /* Process Launch synchronization globals. */ - constinit os::SdkMutex g_launch_program_lock; - os::Event g_process_launch_start_event(os::EventClearMode_AutoClear); - os::Event g_process_launch_finish_event(os::EventClearMode_AutoClear); - constinit Result g_process_launch_result = ResultSuccess(); - constinit LaunchProcessArgs g_process_launch_args = {}; - /* Hook globals. */ constinit std::atomic g_program_id_hook; constinit std::atomic g_application_hook; - /* Forward declarations. */ - Result LaunchProcess(os::MultiWaitType &multi_wait, const LaunchProcessArgs &args); - void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info); - /* Helpers. */ - void ProcessTrackingMain(void *) { - /* This is the main loop of the process tracking thread. */ - - /* Setup multi wait/holders. */ - os::MultiWaitType process_multi_wait; - os::MultiWaitHolderType start_event_holder; - os::InitializeMultiWait(std::addressof(process_multi_wait)); - os::InitializeMultiWaitHolder(std::addressof(start_event_holder), g_process_launch_start_event.GetBase()); - os::LinkMultiWaitHolder(std::addressof(process_multi_wait), std::addressof(start_event_holder)); - - while (true) { - auto signaled_holder = os::WaitAny(std::addressof(process_multi_wait)); - if (signaled_holder == std::addressof(start_event_holder)) { - /* Launch start event signaled. */ - /* TryWait will clear signaled, preventing duplicate notifications. */ - if (g_process_launch_start_event.TryWait()) { - g_process_launch_result = LaunchProcess(process_multi_wait, g_process_launch_args); - g_process_launch_finish_event.Signal(); - } - } else { - /* Some process was signaled. */ - ProcessListAccessor list(g_process_list); - OnProcessSignaled(list, reinterpret_cast(os::GetMultiWaitHolderUserData(signaled_holder))); - } - } + void CreateDebuggerEvent() { + /* Create debugger hook events. */ + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_process_event), os::EventClearMode_AutoClear, true)); + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_application_process_event), os::EventClearMode_AutoClear, true)); } inline u32 GetLoaderCreateProcessFlags(u32 launch_flags) { @@ -195,7 +100,7 @@ namespace ams::pm::impl { } bool HasApplicationProcess() { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); for (auto &process : *list) { if (process.IsApplication()) { @@ -212,19 +117,14 @@ namespace ams::pm::impl { R_SUCCEED(); } - void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info) { - /* Remove the process from the list. */ - list->Remove(process_info); + Result LaunchProgramImpl(ProcessInfo **out_process_info, os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags) { + /* Set the output to nullptr, if we fail. */ + *out_process_info = nullptr; - /* Delete the process. */ - g_process_info_allocator.FreeProcessInfo(process_info); - } - - Result LaunchProcess(os::MultiWaitType &multi_wait, const LaunchProcessArgs &args) { /* Get Program Info. */ ldr::ProgramInfo program_info; cfg::OverrideStatus override_status; - R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), args.location)); + R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), loc)); const bool is_application = (program_info.flags & ldr::ProgramInfoFlag_ApplicationTypeMask) == ldr::ProgramInfoFlag_Application; const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || hos::GetVersion() < hos::Version_2_0_0; @@ -232,14 +132,14 @@ namespace ams::pm::impl { R_UNLESS(!is_application || !HasApplicationProcess(), pm::ResultApplicationRunning()); /* Fix the program location to use the right program id. */ - const ncm::ProgramLocation location = ncm::ProgramLocation::Make(program_info.program_id, static_cast(args.location.storage_id)); + const ncm::ProgramLocation fixed_location = ncm::ProgramLocation::Make(program_info.program_id, static_cast(loc.storage_id)); /* Pin and create the process. */ os::NativeHandle process_handle; ldr::PinId pin_id; { /* Pin the program with loader. */ - R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), location, override_status)); + R_TRY(ldr::pm::AtmospherePinProgram(std::addressof(pin_id), fixed_location, override_status)); /* If we fail after now, unpin. */ ON_RESULT_FAILURE { ldr::pm::UnpinProgram(pin_id); }; @@ -263,29 +163,28 @@ namespace ams::pm::impl { ON_RESULT_FAILURE_2 { if (mitm_boost_size > 0 || is_application) { R_ABORT_UNLESS(BoostSystemMemoryResourceLimitForMitm(0)); } }; /* Ensure resources are available. */ - resource::WaitResourceAvailable(std::addressof(program_info)); + WaitResourceAvailable(std::addressof(program_info)); /* Actually create the process. */ - R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(args.flags), resource::GetResourceLimitHandle(std::addressof(program_info)))); + R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(flags), GetResourceLimitHandle(std::addressof(program_info)))); } /* Get the process id. */ os::ProcessId process_id = os::GetProcessId(process_handle); /* Make new process info. */ - ProcessInfo *process_info = g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status); + ProcessInfo *process_info = AllocateProcessInfo(process_handle, process_id, pin_id, fixed_location, override_status); AMS_ABORT_UNLESS(process_info != nullptr); - /* Link new process info. */ + /* Add the new process info to the process list. */ { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); list->push_back(*process_info); - process_info->LinkToMultiWait(multi_wait); } /* Prevent resource leakage if register fails. */ ON_RESULT_FAILURE { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); process_info->Cleanup(); CleanupProcessInfo(list, process_info); }; @@ -296,166 +195,73 @@ namespace ams::pm::impl { const u8 *aci_fah = acid_fac + program_info.acid_fac_size; /* Register with FS and SM. */ - R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(location.program_id), static_cast(location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size)); - R_TRY(sm::manager::RegisterProcess(process_id, location.program_id, override_status, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size)); + R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(fixed_location.program_id), static_cast(fixed_location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size)); + R_TRY(sm::manager::RegisterProcess(process_id, fixed_location.program_id, override_status, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size)); /* Set flags. */ if (is_application) { process_info->SetApplication(); } - if (ShouldSignalOnStart(args.flags) && allow_debug) { + if (ShouldSignalOnStart(flags) && allow_debug) { process_info->SetSignalOnStart(); } - if (ShouldSignalOnExit(args.flags)) { + if (ShouldSignalOnExit(flags)) { process_info->SetSignalOnExit(); } - if (ShouldSignalOnDebugEvent(args.flags) && allow_debug) { + if (ShouldSignalOnDebugEvent(flags) && allow_debug) { process_info->SetSignalOnDebugEvent(); } /* Process hooks/signaling. */ - if (location.program_id == g_program_id_hook) { + if (fixed_location.program_id == g_program_id_hook) { os::SignalSystemEvent(std::addressof(g_hook_to_create_process_event)); g_program_id_hook = ncm::InvalidProgramId; } else if (is_application && g_application_hook) { os::SignalSystemEvent(std::addressof(g_hook_to_create_application_process_event)); g_application_hook = false; - } else if (!ShouldStartSuspended(args.flags)) { + } else if (!ShouldStartSuspended(flags)) { R_TRY(StartProcess(process_info, std::addressof(program_info))); } - *args.out_process_id = process_id; + *out_process_id = process_id; + *out_process_info = process_info; R_SUCCEED(); } - void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info) { - /* Reset the process's signal. */ - svc::ResetSignal(process_info->GetHandle()); - - /* Update the process's state. */ - const svc::ProcessState old_state = process_info->GetState(); - { - s64 tmp = 0; - R_ABORT_UNLESS(svc::GetProcessInfo(std::addressof(tmp), process_info->GetHandle(), svc::ProcessInfoType_ProcessState)); - process_info->SetState(static_cast(tmp)); - } - const svc::ProcessState new_state = process_info->GetState(); - - /* If we're transitioning away from crashed, clear waiting attached. */ - if (old_state == svc::ProcessState_Crashed && new_state != svc::ProcessState_Crashed) { - process_info->ClearExceptionWaitingAttach(); - } - - switch (new_state) { - case svc::ProcessState_Created: - case svc::ProcessState_CreatedAttached: - case svc::ProcessState_Terminating: - break; - case svc::ProcessState_Running: - if (process_info->ShouldSignalOnDebugEvent()) { - process_info->ClearSuspended(); - process_info->SetSuspendedStateChanged(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } else if (hos::GetVersion() >= hos::Version_2_0_0 && process_info->ShouldSignalOnStart()) { - process_info->SetStartedStateChanged(); - process_info->ClearSignalOnStart(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - process_info->ClearUnhandledException(); - break; - case svc::ProcessState_Crashed: - if (!process_info->HasUnhandledException()) { - process_info->SetExceptionOccurred(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - process_info->SetExceptionWaitingAttach(); - break; - case svc::ProcessState_RunningAttached: - if (process_info->ShouldSignalOnDebugEvent()) { - process_info->ClearSuspended(); - process_info->SetSuspendedStateChanged(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - process_info->ClearUnhandledException(); - break; - case svc::ProcessState_Terminated: - /* Free process resources, unlink from multi wait. */ - process_info->Cleanup(); - - if (hos::GetVersion() < hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { - os::SignalSystemEvent(std::addressof(g_process_event)); - } else { - /* Handle the case where we need to keep the process alive some time longer. */ - if (hos::GetVersion() >= hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { - /* Remove from the living list. */ - list->Remove(process_info); - - /* Add the process to the list of dead processes. */ - { - ProcessListAccessor dead_list(g_dead_process_list); - dead_list->push_back(*process_info); - } - - /* Signal. */ - os::SignalSystemEvent(std::addressof(g_process_event)); - } else { - /* Actually delete process. */ - CleanupProcessInfo(list, process_info); - } - } - break; - case svc::ProcessState_DebugBreak: - if (process_info->ShouldSignalOnDebugEvent()) { - process_info->SetSuspended(); - process_info->SetSuspendedStateChanged(); - os::SignalSystemEvent(std::addressof(g_process_event)); - } - break; - } - } - } /* Initialization. */ Result InitializeProcessManager() { /* Create events. */ - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_process_event), os::EventClearMode_AutoClear, true)); - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_process_event), os::EventClearMode_AutoClear, true)); - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_application_process_event), os::EventClearMode_AutoClear, true)); - R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_boot_finished_event), os::EventClearMode_AutoClear, true)); + CreateProcessEvent(); + CreateDebuggerEvent(); + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_boot_finished_event), os::EventClearMode_AutoClear, true)); /* Initialize resource limits. */ - R_TRY(resource::InitializeResourceManager()); + R_TRY(InitializeSpec()); - /* Create thread. */ - R_ABORT_UNLESS(os::CreateThread(std::addressof(g_process_track_thread), ProcessTrackingMain, nullptr, g_process_track_thread_stack, sizeof(g_process_track_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(pm, ProcessTrack))); - os::SetThreadNamePointer(std::addressof(g_process_track_thread), AMS_GET_SYSTEM_THREAD_NAME(pm, ProcessTrack)); + /* Initialize the process tracker. */ + g_process_tracker.Initialize(g_process_track_thread_stack, sizeof(g_process_track_thread_stack)); - /* Start thread. */ - os::StartThread(std::addressof(g_process_track_thread)); + /* Start the process tracker thread. */ + g_process_tracker.StartThread(); R_SUCCEED(); } /* Process Management. */ Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags) { - /* Ensure we only try to launch one program at a time. */ - std::scoped_lock lk(g_launch_program_lock); + /* Launch the program. */ + ProcessInfo *process_info = nullptr; + R_TRY(LaunchProgramImpl(std::addressof(process_info), out_process_id, loc, flags)); - /* Set global arguments, signal, wait. */ - g_process_launch_args = { - .out_process_id = out_process_id, - .location = loc, - .flags = flags, - }; - g_process_launch_start_event.Signal(); - g_process_launch_finish_event.Wait(); - - R_RETURN(g_process_launch_result); + /* Register the process info with the tracker. */ + g_process_tracker.QueueEntry(process_info); + R_SUCCEED(); } Result StartProcess(os::ProcessId process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -467,7 +273,7 @@ namespace ams::pm::impl { } Result TerminateProcess(os::ProcessId process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -476,7 +282,7 @@ namespace ams::pm::impl { } Result TerminateProgram(ncm::ProgramId program_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(program_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -484,15 +290,10 @@ namespace ams::pm::impl { R_RETURN(svc::TerminateProcess(process_info->GetHandle())); } - Result GetProcessEventHandle(os::NativeHandle *out) { - *out = os::GetReadableHandleOfSystemEvent(std::addressof(g_process_event)); - R_SUCCEED(); - } - Result GetProcessEventInfo(ProcessEventInfo *out) { /* Check for event from current process. */ { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); for (auto &process : *list) { @@ -528,14 +329,14 @@ namespace ams::pm::impl { /* Check for event from exited process. */ if (hos::GetVersion() >= hos::Version_5_0_0) { - ProcessListAccessor dead_list(g_dead_process_list); + auto exit_list = GetExitList(); - if (!dead_list->empty()) { - auto &process_info = dead_list->front(); - out->event = GetProcessEventValue(ProcessEvent::Exited); + if (!exit_list->empty()) { + auto &process_info = exit_list->front(); + out->event = GetProcessEventValue(ProcessEvent::Exited); out->process_id = process_info.GetProcessId(); - CleanupProcessInfo(dead_list, std::addressof(process_info)); + CleanupProcessInfo(exit_list, std::addressof(process_info)); R_SUCCEED(); } } @@ -546,7 +347,7 @@ namespace ams::pm::impl { } Result CleanupProcess(os::ProcessId process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -557,7 +358,7 @@ namespace ams::pm::impl { } Result ClearExceptionOccurred(os::ProcessId process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -575,7 +376,7 @@ namespace ams::pm::impl { } Result GetExceptionProcessIdList(u32 *out_count, os::ProcessId *out_process_ids, size_t max_out_count) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); size_t count = 0; @@ -596,7 +397,7 @@ namespace ams::pm::impl { } Result GetProcessId(os::ProcessId *out, ncm::ProgramId program_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(program_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -606,7 +407,7 @@ namespace ams::pm::impl { } Result GetProgramId(ncm::ProgramId *out, os::ProcessId process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -616,7 +417,7 @@ namespace ams::pm::impl { } Result GetApplicationProcessId(os::ProcessId *out_process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); for (auto &process : *list) { if (process.IsApplication()) { @@ -629,7 +430,7 @@ namespace ams::pm::impl { } Result AtmosphereGetProcessInfo(os::NativeHandle *out_process_handle, ncm::ProgramLocation *out_loc, cfg::OverrideStatus *out_status, os::ProcessId process_id) { - ProcessListAccessor list(g_process_list); + auto list = GetProcessList(); auto process_info = list->Find(process_id); R_UNLESS(process_info != nullptr, pm::ResultProcessNotFound()); @@ -706,33 +507,4 @@ namespace ams::pm::impl { R_SUCCEED(); } - /* Resource Limit API. */ - Result BoostSystemMemoryResourceLimit(u64 boost_size) { - R_RETURN(resource::BoostSystemMemoryResourceLimit(boost_size)); - } - - Result BoostApplicationThreadResourceLimit() { - R_RETURN(resource::BoostApplicationThreadResourceLimit()); - } - - Result BoostSystemThreadResourceLimit() { - R_RETURN(resource::BoostSystemThreadResourceLimit()); - } - - Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out) { - R_RETURN(resource::GetResourceLimitCurrentValue(ResourceLimitGroup_Applet, out)); - } - - Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out) { - R_RETURN(resource::GetResourceLimitPeakValue(ResourceLimitGroup_Applet, out)); - } - - Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource) { - R_RETURN(resource::GetResourceLimitValues(out_cur_val, out_lim_val, static_cast(group), static_cast(resource))); - } - - Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size) { - R_RETURN(resource::BoostSystemMemoryResourceLimitForMitm(boost_size)); - } - } diff --git a/stratosphere/pm/source/impl/pm_process_manager.hpp b/stratosphere/pm/source/impl/pm_process_manager.hpp index b12e91651..61acbe1b0 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.hpp +++ b/stratosphere/pm/source/impl/pm_process_manager.hpp @@ -48,13 +48,4 @@ namespace ams::pm::impl { Result NotifyBootFinished(); Result GetBootFinishedEventHandle(os::NativeHandle *out); - /* Resource Limit API. */ - Result BoostSystemMemoryResourceLimit(u64 boost_size); - Result BoostApplicationThreadResourceLimit(); - Result BoostSystemThreadResourceLimit(); - Result GetAppletResourceLimitCurrentValue(pm::ResourceLimitValue *out); - Result GetAppletResourceLimitPeakValue(pm::ResourceLimitValue *out); - Result AtmosphereGetCurrentLimitInfo(s64 *out_cur_val, s64 *out_lim_val, u32 group, u32 resource); - Result BoostSystemMemoryResourceLimitForMitm(u64 boost_size); - } diff --git a/stratosphere/pm/source/impl/pm_process_tracker.cpp b/stratosphere/pm/source/impl/pm_process_tracker.cpp new file mode 100644 index 000000000..5d1c3b418 --- /dev/null +++ b/stratosphere/pm/source/impl/pm_process_tracker.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "pm_process_tracker.hpp" +#include "pm_process_info.hpp" +#include "pm_spec.hpp" + +namespace ams::pm::impl { + + namespace { + + /* Global process event. */ + constinit os::SystemEventType g_process_event; + + } + + void ProcessTracker::Initialize(void *stack, size_t stack_size) { + /* Initialize our events. */ + os::InitializeEvent(std::addressof(m_request_event), false, os::EventClearMode_AutoClear); + os::InitializeEvent(std::addressof(m_reply_event), false, os::EventClearMode_AutoClear); + + /* Our process count should initially be zero. */ + m_process_count = 0; + + /* Create the process tracking thread. */ + R_ABORT_UNLESS(os::CreateThread(std::addressof(m_thread), ProcessTracker::ThreadFunction, this, stack, stack_size, AMS_GET_SYSTEM_THREAD_PRIORITY(pm, ProcessTrack))); + os::SetThreadNamePointer(std::addressof(m_thread), AMS_GET_SYSTEM_THREAD_NAME(pm, ProcessTrack)); + } + + void ProcessTracker::StartThread() { + /* Start thread. */ + os::StartThread(std::addressof(m_thread)); + } + + void ProcessTracker::ThreadBody() { + /* This is the main loop of the process tracking thread. */ + + /* Setup multi wait/holders. */ + os::MultiWaitType process_multi_wait; + os::MultiWaitHolderType enqueue_event_holder; + os::InitializeMultiWait(std::addressof(process_multi_wait)); + os::InitializeMultiWaitHolder(std::addressof(enqueue_event_holder), std::addressof(m_request_event)); + os::LinkMultiWaitHolder(std::addressof(process_multi_wait), std::addressof(enqueue_event_holder)); + + while (true) { + auto signaled_holder = os::WaitAny(std::addressof(process_multi_wait)); + if (signaled_holder == std::addressof(enqueue_event_holder)) { + /* TryWait will clear signaled, preventing duplicate notifications. */ + if (os::TryWaitEvent(std::addressof(m_request_event))) { + /* Link the process to our multi-wait. */ + os::LinkMultiWaitHolder(std::addressof(process_multi_wait), m_queued_process_info->GetMultiWaitHolder()); + m_queued_process_info = nullptr; + + /* Increment our process count. */ + ++m_process_count; + + /* Reply. */ + os::SignalEvent(std::addressof(m_reply_event)); + } + } else { + /* Some process was signaled. */ + this->OnProcessSignaled(reinterpret_cast(os::GetMultiWaitHolderUserData(signaled_holder))); + } + } + } + + void ProcessTracker::QueueEntry(ProcessInfo *process_info) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + /* Request to enqueue the process info. */ + m_queued_process_info = process_info; + os::SignalEvent(std::addressof(m_request_event)); + + /* Wait for acknowledgement. */ + os::WaitEvent(std::addressof(m_reply_event)); + } + + void ProcessTracker::OnProcessSignaled(ProcessInfo *process_info) { + /* Get the process list. */ + auto list = GetProcessList(); + + /* Reset the process's signal. */ + svc::ResetSignal(process_info->GetHandle()); + + /* Update the process's state. */ + const svc::ProcessState old_state = process_info->GetState(); + { + s64 tmp = 0; + R_ABORT_UNLESS(svc::GetProcessInfo(std::addressof(tmp), process_info->GetHandle(), svc::ProcessInfoType_ProcessState)); + process_info->SetState(static_cast(tmp)); + } + const svc::ProcessState new_state = process_info->GetState(); + + /* If we're transitioning away from crashed, clear waiting attached. */ + if (old_state == svc::ProcessState_Crashed && new_state != svc::ProcessState_Crashed) { + process_info->ClearExceptionWaitingAttach(); + } + + switch (new_state) { + case svc::ProcessState_Created: + case svc::ProcessState_CreatedAttached: + case svc::ProcessState_Terminating: + break; + case svc::ProcessState_Running: + if (process_info->ShouldSignalOnDebugEvent()) { + process_info->ClearSuspended(); + process_info->SetSuspendedStateChanged(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } else if (hos::GetVersion() >= hos::Version_2_0_0 && process_info->ShouldSignalOnStart()) { + process_info->SetStartedStateChanged(); + process_info->ClearSignalOnStart(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->ClearUnhandledException(); + break; + case svc::ProcessState_Crashed: + if (!process_info->HasUnhandledException()) { + process_info->SetExceptionOccurred(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->SetExceptionWaitingAttach(); + break; + case svc::ProcessState_RunningAttached: + if (process_info->ShouldSignalOnDebugEvent()) { + process_info->ClearSuspended(); + process_info->SetSuspendedStateChanged(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + process_info->ClearUnhandledException(); + break; + case svc::ProcessState_Terminated: + /* Unlink from multi wait. */ + os::UnlinkMultiWaitHolder(process_info->GetMultiWaitHolder()); + + /* Free process resources. */ + process_info->Cleanup(); + + if (hos::GetVersion() < hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { + os::SignalSystemEvent(std::addressof(g_process_event)); + } else { + /* Handle the case where we need to keep the process alive some time longer. */ + if (hos::GetVersion() >= hos::Version_5_0_0 && process_info->ShouldSignalOnExit()) { + /* Remove from the living list. */ + list->Remove(process_info); + + /* Add the process to the list of dead processes. */ + { + GetExitList()->push_back(*process_info); + } + + /* Signal. */ + os::SignalSystemEvent(std::addressof(g_process_event)); + } else { + /* Actually delete process. */ + CleanupProcessInfo(list, process_info); + } + } + break; + case svc::ProcessState_DebugBreak: + if (process_info->ShouldSignalOnDebugEvent()) { + process_info->SetSuspended(); + process_info->SetSuspendedStateChanged(); + os::SignalSystemEvent(std::addressof(g_process_event)); + } + break; + } + } + + void CreateProcessEvent() { + /* Create process event. */ + R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_process_event), os::EventClearMode_AutoClear, true)); + } + + Result GetProcessEventHandle(os::NativeHandle *out) { + *out = os::GetReadableHandleOfSystemEvent(std::addressof(g_process_event)); + R_SUCCEED(); + } + +} diff --git a/stratosphere/pm/source/impl/pm_process_tracker.hpp b/stratosphere/pm/source/impl/pm_process_tracker.hpp new file mode 100644 index 000000000..c1de7c2aa --- /dev/null +++ b/stratosphere/pm/source/impl/pm_process_tracker.hpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include "pm_process_info.hpp" + +namespace ams::pm::impl { + + class ProcessTracker { + NON_COPYABLE(ProcessTracker); + NON_MOVEABLE(ProcessTracker); + private: + os::ThreadType m_thread; + os::EventType m_request_event; + os::EventType m_reply_event; + os::SdkMutex m_mutex; + ProcessInfo *m_queued_process_info; + util::Atomic m_process_count; + public: + constexpr ProcessTracker() : m_thread(), m_request_event(), m_reply_event(), m_mutex(), m_queued_process_info(nullptr), m_process_count(0) { + /* ... */ + } + + void Initialize(void *stack, size_t stack_size); + void StartThread(); + + void QueueEntry(ProcessInfo *process_info); + + u32 GetProcessCount() const { + return m_process_count; + } + private: + void OnProcessSignaled(ProcessInfo *process_info); + private: + static void ThreadFunction(void *_this) { + static_cast(_this)->ThreadBody(); + } + + void ThreadBody(); + }; + + void CreateProcessEvent(); + +} diff --git a/stratosphere/pm/source/impl/pm_resource_manager.cpp b/stratosphere/pm/source/impl/pm_spec.cpp similarity index 93% rename from stratosphere/pm/source/impl/pm_resource_manager.cpp rename to stratosphere/pm/source/impl/pm_spec.cpp index f11a72dca..a395b0255 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.cpp +++ b/stratosphere/pm/source/impl/pm_spec.cpp @@ -14,9 +14,9 @@ * along with this program. If not, see . */ #include -#include "pm_resource_manager.hpp" +#include "pm_spec.hpp" -namespace ams::pm::resource { +namespace ams::pm::impl { namespace { @@ -209,8 +209,8 @@ namespace ams::pm::resource { R_SUCCEED(); } - template - ALWAYS_INLINE Result GetResourceLimitValuesImpl(ResourceLimitGroup group, pm::ResourceLimitValue *out) { + template + ALWAYS_INLINE Result GetResourceLimitValueImpl(pm::ResourceLimitValue *out, ResourceLimitGroup group) { /* Sanity check group. */ AMS_ABORT_UNLESS(group < ResourceLimitGroup_Count); @@ -219,11 +219,11 @@ namespace ams::pm::resource { /* Get values. */ int64_t values[svc::LimitableResource_Count]; - R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_PhysicalMemoryMax]), handle, svc::LimitableResource_PhysicalMemoryMax)); - R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_ThreadCountMax]), handle, svc::LimitableResource_ThreadCountMax)); - R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_EventCountMax]), handle, svc::LimitableResource_EventCountMax)); - R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_TransferMemoryCountMax]), handle, svc::LimitableResource_TransferMemoryCountMax)); - R_ABORT_UNLESS(GetResourceLimitValueImpl(std::addressof(values[svc::LimitableResource_SessionCountMax]), handle, svc::LimitableResource_SessionCountMax)); + R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_PhysicalMemoryMax]), handle, svc::LimitableResource_PhysicalMemoryMax)); + R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_ThreadCountMax]), handle, svc::LimitableResource_ThreadCountMax)); + R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_EventCountMax]), handle, svc::LimitableResource_EventCountMax)); + R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_TransferMemoryCountMax]), handle, svc::LimitableResource_TransferMemoryCountMax)); + R_ABORT_UNLESS(ImplFunction(std::addressof(values[svc::LimitableResource_SessionCountMax]), handle, svc::LimitableResource_SessionCountMax)); /* Set to output. */ out->physical_memory = values[svc::LimitableResource_PhysicalMemoryMax]; @@ -278,8 +278,7 @@ namespace ams::pm::resource { } - /* Resource API. */ - Result InitializeResourceManager() { + Result InitializeSpec() { /* Create resource limit handles. */ for (size_t i = 0; i < ResourceLimitGroup_Count; i++) { if (i == ResourceLimitGroup_System) { @@ -459,16 +458,16 @@ namespace ams::pm::resource { } } - Result GetResourceLimitCurrentValue(ResourceLimitGroup group, pm::ResourceLimitValue *out) { - R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitCurrentValue>(group, out)); + Result GetResourceLimitCurrentValue(pm::ResourceLimitValue *out, ResourceLimitGroup group) { + R_RETURN(GetResourceLimitValueImpl<::ams::svc::GetResourceLimitCurrentValue>(out, group)); } - Result GetResourceLimitPeakValue(ResourceLimitGroup group, pm::ResourceLimitValue *out) { - R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitPeakValue>(group, out)); + Result GetResourceLimitPeakValue(pm::ResourceLimitValue *out, ResourceLimitGroup group) { + R_RETURN(GetResourceLimitValueImpl<::ams::svc::GetResourceLimitPeakValue>(out, group)); } - Result GetResourceLimitLimitValue(ResourceLimitGroup group, pm::ResourceLimitValue *out) { - R_RETURN(GetResourceLimitValuesImpl<::ams::svc::GetResourceLimitLimitValue>(group, out)); + Result GetResourceLimitLimitValue(pm::ResourceLimitValue *out, ResourceLimitGroup group) { + R_RETURN(GetResourceLimitValueImpl<::ams::svc::GetResourceLimitLimitValue>(out, group)); } Result GetResourceLimitValues(s64 *out_cur, s64 *out_lim, ResourceLimitGroup group, svc::LimitableResource resource) { diff --git a/stratosphere/pm/source/impl/pm_resource_manager.hpp b/stratosphere/pm/source/impl/pm_spec.hpp similarity index 76% rename from stratosphere/pm/source/impl/pm_resource_manager.hpp rename to stratosphere/pm/source/impl/pm_spec.hpp index b6f5605af..1f49282f4 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.hpp +++ b/stratosphere/pm/source/impl/pm_spec.hpp @@ -16,10 +16,10 @@ #pragma once #include -namespace ams::pm::resource { +namespace ams::pm::impl { + + Result InitializeSpec(); - /* Resource API. */ - Result InitializeResourceManager(); Result BoostSystemMemoryResourceLimit(u64 boost_size); Result BoostApplicationThreadResourceLimit(); Result BoostSystemThreadResourceLimit(); @@ -31,9 +31,9 @@ namespace ams::pm::resource { void WaitResourceAvailable(const ldr::ProgramInfo *info); - Result GetResourceLimitCurrentValue(ResourceLimitGroup group, pm::ResourceLimitValue *out); - Result GetResourceLimitPeakValue(ResourceLimitGroup group, pm::ResourceLimitValue *out); - Result GetResourceLimitLimitValue(ResourceLimitGroup group, pm::ResourceLimitValue *out); + Result GetResourceLimitCurrentValue(pm::ResourceLimitValue *out, ResourceLimitGroup group); + Result GetResourceLimitPeakValue(pm::ResourceLimitValue *outm, ResourceLimitGroup group); + Result GetResourceLimitLimitValue(pm::ResourceLimitValue *out, ResourceLimitGroup group); Result GetResourceLimitValues(s64 *out_cur, s64 *out_lim, ResourceLimitGroup group, svc::LimitableResource resource); diff --git a/stratosphere/pm/source/pm_boot_mode_service.cpp b/stratosphere/pm/source/pm_boot_mode_service.cpp index 719fff51f..ff389fe75 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.cpp +++ b/stratosphere/pm/source/pm_boot_mode_service.cpp @@ -21,7 +21,7 @@ namespace ams::pm { namespace { /* Global bootmode. */ - BootMode g_boot_mode = BootMode::Normal; + constinit BootMode g_boot_mode = BootMode::Normal; } diff --git a/stratosphere/pm/source/pm_debug_monitor_service.cpp b/stratosphere/pm/source/pm_debug_monitor_service.cpp index dd5433c78..d9c3b1621 100644 --- a/stratosphere/pm/source/pm_debug_monitor_service.cpp +++ b/stratosphere/pm/source/pm_debug_monitor_service.cpp @@ -16,6 +16,7 @@ #include #include "pm_debug_monitor_service.hpp" #include "impl/pm_process_manager.hpp" +#include "impl/pm_spec.hpp" namespace ams::pm { @@ -76,7 +77,7 @@ namespace ams::pm { } Result DebugMonitorService::AtmosphereGetCurrentLimitInfo(sf::Out out_cur_val, sf::Out out_lim_val, u32 group, u32 resource) { - R_RETURN(impl::AtmosphereGetCurrentLimitInfo(out_cur_val.GetPointer(), out_lim_val.GetPointer(), group, resource)); + R_RETURN(impl::GetResourceLimitValues(out_cur_val.GetPointer(), out_lim_val.GetPointer(), static_cast(group), static_cast(resource))); } } diff --git a/stratosphere/pm/source/pm_info_service.cpp b/stratosphere/pm/source/pm_info_service.cpp index 55b308fce..29ae868cb 100644 --- a/stratosphere/pm/source/pm_info_service.cpp +++ b/stratosphere/pm/source/pm_info_service.cpp @@ -16,6 +16,7 @@ #include #include "pm_info_service.hpp" #include "impl/pm_process_manager.hpp" +#include "impl/pm_spec.hpp" namespace ams::pm { @@ -34,11 +35,11 @@ namespace ams::pm { } Result InformationService::GetAppletResourceLimitCurrentValue(sf::Out out) { - R_RETURN(impl::GetAppletResourceLimitCurrentValue(out.GetPointer())); + R_RETURN(impl::GetResourceLimitCurrentValue(out.GetPointer(), ResourceLimitGroup_Applet)); } Result InformationService::GetAppletResourceLimitPeakValue(sf::Out out) { - R_RETURN(impl::GetAppletResourceLimitPeakValue(out.GetPointer())); + R_RETURN(impl::GetResourceLimitPeakValue(out.GetPointer(), ResourceLimitGroup_Applet)); } /* Atmosphere extension commands. */ diff --git a/stratosphere/pm/source/pm_shell_service.cpp b/stratosphere/pm/source/pm_shell_service.cpp index 7248bc0e2..db69c6f12 100644 --- a/stratosphere/pm/source/pm_shell_service.cpp +++ b/stratosphere/pm/source/pm_shell_service.cpp @@ -16,6 +16,7 @@ #include #include "pm_shell_service.hpp" #include "impl/pm_process_manager.hpp" +#include "impl/pm_spec.hpp" namespace ams::pm { From 1b057d48c6825d5d59da8a71aaa4ac2ebf241c63 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 26 Oct 2023 14:44:45 -0700 Subject: [PATCH 068/238] sm: fix compat with new service macros --- stratosphere/sm/source/impl/sm_service_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stratosphere/sm/source/impl/sm_service_manager.cpp b/stratosphere/sm/source/impl/sm_service_manager.cpp index 2007ac740..a645d5340 100644 --- a/stratosphere/sm/source/impl/sm_service_manager.cpp +++ b/stratosphere/sm/source/impl/sm_service_manager.cpp @@ -437,7 +437,7 @@ namespace ams::sm::impl { { /* TODO: Convert mitm internal messaging to use tipc? */ ::Service srv { .session = mitm_info->query_h }; - R_ABORT_UNLESS(::serviceDispatchInOut(std::addressof(srv), 65000, client_info, should_mitm)); + R_ABORT_UNLESS((serviceDispatchInOut(std::addressof(srv), 65000, client_info, should_mitm))); } /* If we shouldn't mitm, give normal session. */ From 9f26419b1a669762d995ebf21ff83b6e1cf56153 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 27 Oct 2023 16:21:57 -0700 Subject: [PATCH 069/238] ams: bump version to 1.6.2, add changelog --- docs/changelog.md | 6 ++++++ libraries/libvapours/include/vapours/ams/ams_api_version.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index d379849ff..6a49e1901 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,10 @@ # Changelog +## 1.6.2 ++ Support was finished for 17.0.0. + + `erpt` was updated to support the latest official behavior. + + `jpegdec` was updated to support the latest official behavior. + + `pm` was updated to support the latest official behavior. ++ General system stability improvements to enhance the user's experience. ## 1.6.1 + An improved solution to [the problem that would cause consoles which had previously re-built their SYSTEM partition to brick on update-to-17.0.0](https://gist.github.com/SciresM/2ddb708c812ed585c4d99f54e25205ff) was added. + In particular, booting atmosphère will now automatically detect the problem and unbrick any consoles which have fallen into this state. diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 243e0df39..1808fff84 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -17,7 +17,7 @@ #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #define ATMOSPHERE_RELEASE_VERSION_MINOR 6 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 2 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO From f7bf379cfede4a4d8cf1403b59be0364f1c3b6f1 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 27 Oct 2023 16:22:45 -0700 Subject: [PATCH 070/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "80bf6aeee" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "80bf6aeee" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index d2c6e746a..cd0997b93 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 965e05b3cc5ea74de7e3071c3554135e828ce42e - parent = 183f3e0d7e0c620d213be53c66d9156f55389be2 + commit = 80bf6aeeed03df0871329e1ec32da073a62bf102 + parent = 9f26419b1a669762d995ebf21ff83b6e1cf56153 method = merge cmdver = 0.4.1 From afc0e14556efe767ec3aa3869bab245e140cb8b7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 1 Nov 2023 10:24:13 -0700 Subject: [PATCH 071/238] kern/svc: fix query/insecure names --- .../arch/arm64/kern_k_process_page_table.hpp | 8 +++---- .../mesosphere/kern_k_page_table_base.hpp | 4 ++-- .../source/arch/arm64/svc/kern_svc_tables.cpp | 6 ++--- .../source/kern_k_page_table_base.cpp | 4 ++-- .../svc/kern_svc_address_translation.cpp | 14 +++++------ .../source/svc/kern_svc_insecure_memory.cpp | 24 +++++++++---------- .../svc/svc_stratosphere_shims.hpp | 12 +++++----- .../os_insecure_memory_impl.os.horizon.cpp | 4 ++-- .../vapours/svc/svc_definition_macro.hpp | 6 ++--- .../source/dd/dd_io_mapping.os.horizon.cpp | 2 +- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 297d30b52..7209dbfa1 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -110,12 +110,12 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.MapRegion(region_type, perm)); } - Result MapInsecureMemory(KProcessAddress address, size_t size) { - R_RETURN(m_page_table.MapInsecureMemory(address, size)); + Result MapInsecurePhysicalMemory(KProcessAddress address, size_t size) { + R_RETURN(m_page_table.MapInsecurePhysicalMemory(address, size)); } - Result UnmapInsecureMemory(KProcessAddress address, size_t size) { - R_RETURN(m_page_table.UnmapInsecureMemory(address, size)); + Result UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size) { + R_RETURN(m_page_table.UnmapInsecurePhysicalMemory(address, size)); } Result MapPageGroup(KProcessAddress addr, const KPageGroup &pg, KMemoryState state, KMemoryPermission perm) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 530b68dea..51e4c4075 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -387,8 +387,8 @@ namespace ams::kern { Result UnmapIoRegion(KProcessAddress dst_address, KPhysicalAddress phys_addr, size_t size, ams::svc::MemoryMapping mapping); Result MapStatic(KPhysicalAddress phys_addr, size_t size, KMemoryPermission perm); Result MapRegion(KMemoryRegionType region_type, KMemoryPermission perm); - Result MapInsecureMemory(KProcessAddress address, size_t size); - Result UnmapInsecureMemory(KProcessAddress address, size_t size); + Result MapInsecurePhysicalMemory(KProcessAddress address, size_t size); + Result UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size); Result MapPages(KProcessAddress *out_addr, size_t num_pages, size_t alignment, KPhysicalAddress phys_addr, KProcessAddress region_start, size_t region_num_pages, KMemoryState state, KMemoryPermission perm) { R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true, region_start, region_num_pages, state, perm)); diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp index aec27c4ba..cb9151823 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp @@ -142,10 +142,10 @@ namespace ams::kern::svc { /* Get the target firmware. */ const auto target_fw = kern::GetTargetFirmware(); - /* 10.0.0 broke the ABI for QueryIoMapping. */ + /* 10.0.0 broke the ABI for QueryIoMapping, and renamed it to QueryMemoryMapping. */ if (target_fw < TargetFirmware_10_0_0) { - if (table_64) { ::ams::kern::svc::PatchSvcTableEntry(table_64, svc::SvcId_QueryIoMapping, LegacyQueryIoMapping::Call64); } - if (table_64_from_32) { ::ams::kern::svc::PatchSvcTableEntry(table_64_from_32, svc::SvcId_QueryIoMapping, LegacyQueryIoMapping::Call64From32); } + if (table_64) { ::ams::kern::svc::PatchSvcTableEntry(table_64, svc::SvcId_QueryMemoryMapping, LegacyQueryIoMapping::Call64); } + if (table_64_from_32) { ::ams::kern::svc::PatchSvcTableEntry(table_64_from_32, svc::SvcId_QueryMemoryMapping, LegacyQueryIoMapping::Call64From32); } } /* 6.0.0 broke the ABI for GetFutureThreadInfo, and renamed it to GetDebugFutureThreadInfo. */ diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index bfa687aed..d1ee43054 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1072,7 +1072,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::MapInsecureMemory(KProcessAddress address, size_t size) { + Result KPageTableBase::MapInsecurePhysicalMemory(KProcessAddress address, size_t size) { /* Get the insecure memory resource limit and pool. */ auto * const insecure_resource_limit = KSystemControl::GetInsecureMemoryResourceLimit(); const auto insecure_pool = static_cast(KSystemControl::GetInsecureMemoryPool()); @@ -1128,7 +1128,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KPageTableBase::UnmapInsecureMemory(KProcessAddress address, size_t size) { + Result KPageTableBase::UnmapInsecurePhysicalMemory(KProcessAddress address, size_t size) { /* Lock the table. */ KScopedLightLock lk(m_general_lock); diff --git a/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp b/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp index 746eed6bb..e93fbfd55 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_address_translation.cpp @@ -37,7 +37,7 @@ namespace ams::kern::svc { R_SUCCEED(); } - Result QueryIoMapping(uintptr_t *out_address, size_t *out_size, uint64_t phys_addr, size_t size) { + Result QueryMemoryMapping(uintptr_t *out_address, size_t *out_size, uint64_t phys_addr, size_t size) { /* Declare variables we'll populate. */ KProcessAddress found_address = Null; size_t found_size = 0; @@ -125,15 +125,15 @@ namespace ams::kern::svc { R_RETURN(QueryPhysicalAddress(out_info, address)); } - Result QueryIoMapping64(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { + Result QueryMemoryMapping64(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); static_assert(sizeof(*out_size) == sizeof(size_t)); - R_RETURN(QueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); + R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); } Result LegacyQueryIoMapping64(ams::svc::Address *out_address, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); - R_RETURN(QueryIoMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); + R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); } /* ============================= 64From32 ABI ============================= */ @@ -150,15 +150,15 @@ namespace ams::kern::svc { R_SUCCEED(); } - Result QueryIoMapping64From32(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { + Result QueryMemoryMapping64From32(ams::svc::Address *out_address, ams::svc::Size *out_size, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); static_assert(sizeof(*out_size) == sizeof(size_t)); - R_RETURN(QueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); + R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); } Result LegacyQueryIoMapping64From32(ams::svc::Address *out_address, ams::svc::PhysicalAddress physical_address, ams::svc::Size size) { static_assert(sizeof(*out_address) == sizeof(uintptr_t)); - R_RETURN(QueryIoMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); + R_RETURN(QueryMemoryMapping(reinterpret_cast(out_address), nullptr, physical_address, size)); } } diff --git a/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp index c358bff2d..c0262b5c1 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_insecure_memory.cpp @@ -21,7 +21,7 @@ namespace ams::kern::svc { namespace { - Result MapInsecureMemory(uintptr_t address, size_t size) { + Result MapInsecurePhysicalMemory(uintptr_t address, size_t size) { /* Validate the address/size. */ R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); R_UNLESS(size > 0, svc::ResultInvalidSize()); @@ -33,10 +33,10 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Insecure), svc::ResultInvalidMemoryRegion()); /* Map the insecure memory. */ - R_RETURN(pt.MapInsecureMemory(address, size)); + R_RETURN(pt.MapInsecurePhysicalMemory(address, size)); } - Result UnmapInsecureMemory(uintptr_t address, size_t size) { + Result UnmapInsecurePhysicalMemory(uintptr_t address, size_t size) { /* Validate the address/size. */ R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); R_UNLESS(size > 0, svc::ResultInvalidSize()); @@ -48,29 +48,29 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().CanContain(address, size, KMemoryState_Insecure), svc::ResultInvalidMemoryRegion()); /* Map the insecure memory. */ - R_RETURN(pt.UnmapInsecureMemory(address, size)); + R_RETURN(pt.UnmapInsecurePhysicalMemory(address, size)); } } /* ============================= 64 ABI ============================= */ - Result MapInsecureMemory64(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(MapInsecureMemory(address, size)); + Result MapInsecurePhysicalMemory64(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(MapInsecurePhysicalMemory(address, size)); } - Result UnmapInsecureMemory64(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(UnmapInsecureMemory(address, size)); + Result UnmapInsecurePhysicalMemory64(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(UnmapInsecurePhysicalMemory(address, size)); } /* ============================= 64From32 ABI ============================= */ - Result MapInsecureMemory64From32(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(MapInsecureMemory(address, size)); + Result MapInsecurePhysicalMemory64From32(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(MapInsecurePhysicalMemory(address, size)); } - Result UnmapInsecureMemory64From32(ams::svc::Address address, ams::svc::Size size) { - R_RETURN(UnmapInsecureMemory(address, size)); + Result UnmapInsecurePhysicalMemory64From32(ams::svc::Address address, ams::svc::Size size) { + R_RETURN(UnmapInsecurePhysicalMemory(address, size)); } } diff --git a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp index 8e34756de..b724ce5f1 100644 --- a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp +++ b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp @@ -331,8 +331,8 @@ R_RETURN(::svcQueryPhysicalAddress(reinterpret_cast<::PhysicalMemoryInfo *>(out_info), address)); } - ALWAYS_INLINE Result QueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { - R_RETURN(::svcQueryIoMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); + ALWAYS_INLINE Result QueryMemoryMapping(::ams::svc::Address *out_address, ::ams::svc::Size *out_size, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { + R_RETURN(::svcQueryMemoryMapping(reinterpret_cast(out_address), reinterpret_cast(out_size), physical_address, size)); } ALWAYS_INLINE Result LegacyQueryIoMapping(::ams::svc::Address *out_address, ::ams::svc::PhysicalAddress physical_address, ::ams::svc::Size size) { @@ -503,12 +503,12 @@ ::svcCallSecureMonitor(reinterpret_cast<::SecmonArgs *>(args)); } - ALWAYS_INLINE Result MapInsecureMemory(::ams::svc::Address address, ::ams::svc::Size size) { - R_RETURN(::svcMapInsecureMemory(reinterpret_cast(static_cast(address)), size)); + ALWAYS_INLINE Result MapInsecurePhysicalMemory(::ams::svc::Address address, ::ams::svc::Size size) { + R_RETURN(::svcMapInsecurePhysicalMemory(reinterpret_cast(static_cast(address)), size)); } - ALWAYS_INLINE Result UnmapInsecureMemory(::ams::svc::Address address, ::ams::svc::Size size) { - R_RETURN(::svcUnmapInsecureMemory(reinterpret_cast(static_cast(address)), size)); + ALWAYS_INLINE Result UnmapInsecurePhysicalMemory(::ams::svc::Address address, ::ams::svc::Size size) { + R_RETURN(::svcUnmapInsecurePhysicalMemory(reinterpret_cast(static_cast(address)), size)); } } diff --git a/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp index fd8e78f9f..27ffab700 100644 --- a/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_insecure_memory_impl.os.horizon.cpp @@ -23,7 +23,7 @@ namespace ams::os::impl { /* Map at a random address. */ R_RETURN(impl::GetAslrSpaceManager().MapAtRandomAddress(out_address, [](uintptr_t map_address, size_t map_size) -> Result { - R_TRY_CATCH(svc::MapInsecureMemory(map_address, map_size)) { + R_TRY_CATCH(svc::MapInsecurePhysicalMemory(map_address, map_size)) { R_CONVERT(svc::ResultOutOfMemory, os::ResultOutOfMemory()) R_CONVERT(svc::ResultInvalidCurrentMemory, os::ResultInvalidCurrentMemoryState()) } R_END_TRY_CATCH_WITH_ABORT_UNLESS; @@ -39,7 +39,7 @@ namespace ams::os::impl { } void InsecureMemoryImpl::FreeInsecureMemoryImpl(uintptr_t address, size_t size) { - R_ABORT_UNLESS(svc::UnmapInsecureMemory(address, size)); + R_ABORT_UNLESS(svc::UnmapInsecurePhysicalMemory(address, size)); } } diff --git a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp index d4668e445..0f1c57783 100644 --- a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp @@ -99,7 +99,7 @@ HANDLER(0x52, Result, UnmapTransferMemory, INPUT(::ams::svc::Handle, trmem_handle), INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ HANDLER(0x53, Result, CreateInterruptEvent, OUTPUT(::ams::svc::Handle, out_read_handle), INPUT(int32_t, interrupt_id), INPUT(::ams::svc::InterruptType, interrupt_type)) \ HANDLER(0x54, Result, QueryPhysicalAddress, OUTPUT(::ams::svc::NAMESPACE::PhysicalMemoryInfo, out_info), INPUT(::ams::svc::Address, address)) \ - HANDLER(0x55, Result, QueryIoMapping, OUTPUT(::ams::svc::Address, out_address), OUTPUT(::ams::svc::Size, out_size), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x55, Result, QueryMemoryMapping, OUTPUT(::ams::svc::Address, out_address), OUTPUT(::ams::svc::Size, out_size), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ HANDLER(0x56, Result, CreateDeviceAddressSpace, OUTPUT(::ams::svc::Handle, out_handle), INPUT(uint64_t, das_address), INPUT(uint64_t, das_size)) \ HANDLER(0x57, Result, AttachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ HANDLER(0x58, Result, DetachDeviceAddressSpace, INPUT(::ams::svc::DeviceName, device_name), INPUT(::ams::svc::Handle, das_handle)) \ @@ -142,8 +142,8 @@ HANDLER(0x7E, Result, SetResourceLimitLimitValue, INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which), INPUT(int64_t, limit_value)) \ HANDLER(0x7F, void, CallSecureMonitor, OUTPUT(::ams::svc::NAMESPACE::SecureMonitorArguments, args)) \ \ - HANDLER(0x90, Result, MapInsecureMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ - HANDLER(0x91, Result, UnmapInsecureMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x90, Result, MapInsecurePhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ + HANDLER(0x91, Result, UnmapInsecurePhysicalMemory, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::Size, size)) \ \ HANDLER(0x2E, Result, LegacyGetFutureThreadInfo, OUTPUT(::ams::svc::NAMESPACE::LastThreadContext, out_context), OUTPUT(::ams::svc::Address, out_tls_address), OUTPUT(uint32_t, out_flags), INPUT(int64_t, ns)) \ HANDLER(0x55, Result, LegacyQueryIoMapping, OUTPUT(::ams::svc::Address, out_address), INPUT(::ams::svc::PhysicalAddress, physical_address), INPUT(::ams::svc::Size, size)) \ diff --git a/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp b/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp index b549b99a4..11d7c4971 100644 --- a/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp +++ b/libraries/libvapours/source/dd/dd_io_mapping.os.horizon.cpp @@ -68,7 +68,7 @@ namespace ams::dd { if (hos::GetVersion() >= hos::Version_10_0_0) { svc::Size region_size = 0; - R_TRY_CATCH(svc::QueryIoMapping(std::addressof(virt_addr), std::addressof(region_size), aligned_addr, aligned_size)) { + R_TRY_CATCH(svc::QueryMemoryMapping(std::addressof(virt_addr), std::addressof(region_size), aligned_addr, aligned_size)) { /* Official software handles this by returning 0. */ R_CATCH(svc::ResultNotFound) { return 0; } } R_END_TRY_CATCH_WITH_ABORT_UNLESS; From 872c18c501cdad9866524d7be6e038cd9c332232 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 1 Nov 2023 10:25:31 -0700 Subject: [PATCH 072/238] kern: fix some comment typos --- .../libmesosphere/include/mesosphere/kern_k_auto_object.hpp | 2 +- libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp | 2 +- libraries/libmesosphere/source/kern_k_process.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp index 1b7b433b8..dc99f5ceb 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp @@ -358,7 +358,7 @@ namespace ams::kern { void Detach() { /* Close our object, if we have one. */ if (T * const object = m_object; AMS_LIKELY(object != nullptr)) { - /* Set our object to a debug sentinel value, which will cause crash if accessed. */ + /* Set our object to a debug sentinel value, which will cause a crash if accessed. */ m_object = reinterpret_cast(1); /* Close reference to our object. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index 3addd8da1..eb04243cf 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -365,7 +365,7 @@ namespace ams::kern::arch::arm64 { value = 0; } - /* Set the watchkpoint. */ + /* Set the watchpoint. */ switch (name) { case ams::svc::HardwareBreakPointRegisterName_D0: MESOSPHERE_SET_HW_WATCH_POINT( 0, flags, value); break; case ams::svc::HardwareBreakPointRegisterName_D1: MESOSPHERE_SET_HW_WATCH_POINT( 1, flags, value); break; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 07d122280..a82d94bec 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -51,7 +51,7 @@ namespace ams::kern { } } - /* Wait for all children threads to terminate.*/ + /* Wait for all children threads to terminate. */ while (true) { /* Get the next child. */ KThread *cur_child = nullptr; @@ -467,7 +467,7 @@ namespace ams::kern { void KProcess::Exit() { MESOSPHERE_ASSERT_THIS(); - /* Determine whether we need to start terminating */ + /* Determine whether we need to start terminating. */ bool needs_terminate = false; { KScopedLightLock lk(m_state_lock); From 46a43578829163cd08b9ddcaaacc6febd1e71e0e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 13 Nov 2023 12:45:00 -0700 Subject: [PATCH 073/238] fusee: remove ips patch parsing from sd filesystem Parsing the SD fs is very slow. In addition, the only KIPs are either a) atmosphere modules, or b) FS. The IPS subsystem was originally designed to make nogc/etc patches work for FS, but these are now internal, and it appears that the literal only kip patches that exist are for piracy. It just doesn't make sense to slow down boot for every normal user for a feature that has no actual usecase, and especially when fusee is already so minimal. --- fusee/program/source/fusee_stratosphere.cpp | 181 -------------------- 1 file changed, 181 deletions(-) diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index e9ad72e80..bcaff0395 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -385,15 +385,6 @@ namespace ams::nxboot { return nullptr; } - InitialProcessMeta *FindInitialProcess(const se::Sha256Hash &hash) { - for (InitialProcessMeta *cur = std::addressof(g_initial_process_meta); cur != nullptr; cur = cur->next) { - if (std::memcmp(std::addressof(cur->kip_hash), std::addressof(hash), sizeof(hash)) == 0) { - return cur; - } - } - return nullptr; - } - u32 GetPatchSegments(const InitialProcessHeader *kip, u32 offset, size_t size) { /* Create segment mask. */ u32 segments = 0; @@ -474,78 +465,6 @@ namespace ams::nxboot { meta->patches_tail = new_patch; } - void AddIps24PatchToKip(InitialProcessMeta *meta, const u8 *ips, s32 size) { - while (size > 0) { - /* Read offset, stopping at EOF */ - const u32 offset = (static_cast(ips[0]) << 16) | (static_cast(ips[1]) << 8) | (static_cast(ips[2]) << 0); - if (offset == 0x454F46) { - break; - } - - /* Read size. */ - const u16 cur_size = (static_cast(ips[3]) << 8) | (static_cast(ips[4]) << 0); - - if (cur_size > 0) { - /* Add patch. */ - AddPatch(meta, offset, ips + 5, cur_size, false); - - /* Advance. */ - ips += (5 + cur_size); - size -= (5 + cur_size); - } else { - /* Read RLE size */ - const u16 rle_size = (static_cast(ips[5]) << 8) | (static_cast(ips[6]) << 0); - - /* Add patch. */ - AddPatch(meta, offset, ips + 7, rle_size, true); - - /* Advance. */ - ips += 8; - size -= 8; - } - } - } - - void AddIps32PatchToKip(InitialProcessMeta *meta, const u8 *ips, s32 size) { - while (size > 0) { - /* Read offset, stopping at EOF */ - const u32 offset = (static_cast(ips[0]) << 24) | (static_cast(ips[1]) << 16) | (static_cast(ips[2]) << 8) | (static_cast(ips[3]) << 0); - if (offset == 0x45454F46) { - break; - } - - /* Read size. */ - const u16 cur_size = (static_cast(ips[4]) << 8) | (static_cast(ips[5]) << 0); - - if (cur_size > 0) { - /* Add patch. */ - AddPatch(meta, offset, ips + 6, cur_size, false); - - /* Advance. */ - ips += (6 + cur_size); - size -= (6 + cur_size); - } else { - /* Read RLE size */ - const u16 rle_size = (static_cast(ips[6]) << 8) | (static_cast(ips[7]) << 0); - - /* Add patch. */ - AddPatch(meta, offset, ips + 8, rle_size, true); - - /* Advance. */ - ips += 9; - size -= 9; - } - } - } - - void AddIpsPatchToKip(InitialProcessMeta *meta, const u8 *ips, s32 size) { - if (std::memcmp(ips, "PATCH", 5) == 0) { - AddIps24PatchToKip(meta, ips + 5, size - 5); - } else if (std::memcmp(ips, "IPS32", 5) == 0) { - AddIps32PatchToKip(meta, ips + 5, size - 5); - } - } - constexpr const u8 NogcPatch0[] = { 0x80 }; @@ -891,106 +810,6 @@ namespace ams::nxboot { } /* TODO ams.tma2: add mount_host patches. */ - - /* Add generic patches. */ - { - /* Create patch path. */ - char patch_path[0x220]; - std::memcpy(patch_path, "sdmc:/atmosphere/kip_patches", 0x1D); - - fs::DirectoryHandle patch_root_dir; - if (R_SUCCEEDED(fs::OpenDirectory(std::addressof(patch_root_dir), patch_path))) { - ON_SCOPE_EXIT { fs::CloseDirectory(patch_root_dir); }; - - s64 count; - fs::DirectoryEntry entries[1]; - while (R_SUCCEEDED(fs::ReadDirectory(std::addressof(count), entries, patch_root_dir, util::size(entries))) && count > 0) { - /* Check that dir is a dir. */ - if (fs::GetEntryType(entries[0]) != fs::DirectoryEntryType_Directory) { - continue; - } - - /* For compatibility, ignore the old "default_nogc" patches. */ - if (std::strcmp(entries[0].file_name, "default_nogc") == 0) { - continue; - } - - /* Get filename length. */ - const int dir_len = std::strlen(entries[0].file_name); - - /* Adjust patch path. */ - patch_path[0x1C] = '/'; - std::memcpy(patch_path + 0x1D, entries[0].file_name, dir_len + 1); - - /* Try to open the patch subdirectory. */ - fs::DirectoryHandle patch_dir; - if (R_SUCCEEDED(fs::OpenDirectory(std::addressof(patch_dir), patch_path))) { - ON_SCOPE_EXIT { fs::CloseDirectory(patch_dir); }; - - /* Read patches. */ - while (R_SUCCEEDED(fs::ReadDirectory(std::addressof(count), entries, patch_dir, util::size(entries))) && count > 0) { - /* Check that file is a file. */ - if (fs::GetEntryType(entries[0]) != fs::DirectoryEntryType_File) { - continue; - } - - /* Get filename length. */ - const int name_len = std::strlen(entries[0].file_name); - - /* Adjust patch path. */ - patch_path[0x1D + dir_len] = '/'; - std::memcpy(patch_path + 0x1D + dir_len + 1, entries[0].file_name, name_len + 1); - - /* Check that file is "{hex}.ips" file. */ - const int path_len = 0x1D + dir_len + 1 + name_len; - if (name_len != 0x44 || std::memcmp(patch_path + path_len - 4, ".ips", 5) != 0) { - continue; - } - - /* Check that the filename is hex. */ - bool valid_name = true; - se::Sha256Hash patch_name = {}; - u32 shift = 4; - for (int i = 0; i < name_len - 4; ++i) { - const char c = entries[0].file_name[i]; - - u8 val; - if ('0' <= c && c <= '9') { - val = (c - '0'); - } else if ('a' <= c && c <= 'f') { - val = (c - 'a') + 10; - } else if ('A' <= c && c <= 'F') { - val = (c - 'A') + 10; - } else { - valid_name = false; - break; - } - - patch_name.bytes[i >> 1] |= val << shift; - shift ^= 4; - } - - /* Ignore invalid patches. */ - if (!valid_name) { - continue; - } - - /* Find kip for the patch. */ - auto *kip_meta = FindInitialProcess(patch_name); - if (kip_meta == nullptr) { - continue; - } - - /* Read the ips patch. */ - s64 file_size; - if (u8 *ips = static_cast(ReadFile(std::addressof(file_size), patch_path)); ips != nullptr) { - AddIpsPatchToKip(kip_meta, ips, static_cast(file_size)); - } - } - } - } - } - } } /* Return the fs version we're using. */ From 812b2aeb4c61cd12e923f6a7adcfeb6465066574 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 16 Nov 2023 16:25:52 -0700 Subject: [PATCH 074/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "d7a02b6ca" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "d7a02b6ca" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index cd0997b93..03f628503 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 80bf6aeeed03df0871329e1ec32da073a62bf102 - parent = 9f26419b1a669762d995ebf21ff83b6e1cf56153 + commit = d7a02b6ca1c6c2f00f25c44a8f6585a79f95f515 + parent = 46a43578829163cd08b9ddcaaacc6febd1e71e0e method = merge cmdver = 0.4.1 From 742fd16080bce8cd664d6244304a771f82e8aa04 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 28 Nov 2023 12:54:00 -0700 Subject: [PATCH 075/238] sf: fix ipc serialization bug (out object id offsets) --- .../sf/cmif/sf_cmif_domain_service_object.hpp | 14 +++++++------- .../sf/cmif/sf_cmif_server_message_processor.hpp | 8 ++++++-- .../sf/impl/sf_impl_command_serialization.hpp | 13 +++++++------ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp index d13934320..e73a6642c 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_domain_service_object.hpp @@ -62,7 +62,7 @@ namespace ams::sf::cmif { } constexpr size_t GetImplOutDataTotalSize() const { - return m_impl_metadata.GetOutDataSize() + m_impl_metadata.GetOutHeadersSize(); + return m_impl_metadata.GetUnalignedOutDataSize() + m_impl_metadata.GetOutHeadersSize(); } public: /* Used to enabled templated message processors. */ @@ -80,12 +80,12 @@ namespace ams::sf::cmif { const auto runtime_metadata = m_impl_processor->GetRuntimeMetadata(); return ServerMessageRuntimeMetadata { - .in_data_size = static_cast(runtime_metadata.GetInDataSize() + runtime_metadata.GetInObjectCount() * sizeof(DomainObjectId)), - .out_data_size = static_cast(runtime_metadata.GetOutDataSize() + runtime_metadata.GetOutObjectCount() * sizeof(DomainObjectId)), - .in_headers_size = static_cast(runtime_metadata.GetInHeadersSize() + sizeof(CmifDomainInHeader)), - .out_headers_size = static_cast(runtime_metadata.GetOutHeadersSize() + sizeof(CmifDomainOutHeader)), - .in_object_count = 0, - .out_object_count = 0, + .in_data_size = static_cast(runtime_metadata.GetInDataSize() + runtime_metadata.GetInObjectCount() * sizeof(DomainObjectId)), + .unaligned_out_data_size = static_cast(runtime_metadata.GetOutDataSize() + runtime_metadata.GetOutObjectCount() * sizeof(DomainObjectId)), + .in_headers_size = static_cast(runtime_metadata.GetInHeadersSize() + sizeof(CmifDomainInHeader)), + .out_headers_size = static_cast(runtime_metadata.GetOutHeadersSize() + sizeof(CmifDomainOutHeader)), + .in_object_count = 0, + .out_object_count = 0, }; } diff --git a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp index ca90235e6..ef454e091 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_server_message_processor.hpp @@ -28,7 +28,7 @@ namespace ams::sf::cmif { /* This is needed for non-templated domain message processing. */ struct ServerMessageRuntimeMetadata { u16 in_data_size; - u16 out_data_size; + u16 unaligned_out_data_size; u8 in_headers_size; u8 out_headers_size; u8 in_object_count; @@ -39,7 +39,11 @@ namespace ams::sf::cmif { } constexpr size_t GetOutDataSize() const { - return static_cast(this->out_data_size); + return static_cast(util::AlignUp(this->unaligned_out_data_size, sizeof(u32))); + } + + constexpr size_t GetUnalignedOutDataSize() const { + return static_cast(this->unaligned_out_data_size); } constexpr size_t GetInHeadersSize() const { diff --git a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index 83024df40..c91d4480f 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -472,6 +472,7 @@ namespace ams::sf::impl { static constexpr size_t InDataSize = util::AlignUp(InDataOffsets[NumInDatas], alignof(u16)); static constexpr std::array OutDataOffsets = RawDataOffsetCalculator::Offsets; + static constexpr size_t UnalignedOutDataSize = OutDataOffsets[NumOutDatas]; static constexpr size_t OutDataSize = util::AlignUp(OutDataOffsets[NumOutDatas], alignof(u32)); static constexpr size_t OutDataAlign = [] { if constexpr (std::tuple_size::value) { @@ -492,12 +493,12 @@ namespace ams::sf::impl { /* Used by server message processor at runtime. */ static constexpr inline const cmif::ServerMessageRuntimeMetadata RuntimeMetadata = cmif::ServerMessageRuntimeMetadata{ - .in_data_size = InDataSize, - .out_data_size = OutDataSize, - .in_headers_size = sizeof(CmifInHeader), - .out_headers_size = sizeof(CmifOutHeader), - .in_object_count = NumInObjects, - .out_object_count = NumOutObjects, + .in_data_size = InDataSize, + .unaligned_out_data_size = UnalignedOutDataSize, + .in_headers_size = sizeof(CmifInHeader), + .out_headers_size = sizeof(CmifOutHeader), + .in_object_count = NumInObjects, + .out_object_count = NumOutObjects, }; /* Construction of argument serialization structs. */ From db3dc4ebd2a7ae40ac305dbd9ca1aad266715107 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 28 Nov 2023 13:02:32 -0700 Subject: [PATCH 076/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "bfc558348" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "bfc558348" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 03f628503..67a7451a7 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = d7a02b6ca1c6c2f00f25c44a8f6585a79f95f515 - parent = 46a43578829163cd08b9ddcaaacc6febd1e71e0e + commit = bfc55834869fe24f8d94550bc6909a65ae7d35c2 + parent = 742fd16080bce8cd664d6244304a771f82e8aa04 method = merge cmdver = 0.4.1 From 1fa41c3e2ade86a44e658a08a069cc233782e280 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 27 Dec 2023 23:05:10 -0700 Subject: [PATCH 077/238] loader/ro: abort if patching would go out of bounds --- libraries/libstratosphere/source/patcher/patcher_api.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/libstratosphere/source/patcher/patcher_api.cpp b/libraries/libstratosphere/source/patcher/patcher_api.cpp index f74259bd0..5d493b3ec 100644 --- a/libraries/libstratosphere/source/patcher/patcher_api.cpp +++ b/libraries/libstratosphere/source/patcher/patcher_api.cpp @@ -167,6 +167,7 @@ namespace ams::patcher { /* Apply patch. */ if (patch_offset + rle_size > mapped_size) { + AMS_ABORT_UNLESS(patch_offset <= mapped_size); rle_size = mapped_size - patch_offset; } std::memset(mapped_module + patch_offset, buffer[0], rle_size); @@ -190,6 +191,7 @@ namespace ams::patcher { /* Apply patch. */ u32 read_size = patch_size; if (patch_offset + read_size > mapped_size) { + AMS_ABORT_UNLESS(patch_offset <= mapped_size); read_size = mapped_size - patch_offset; } { From 3217df147ed6489a53015fc6813964e5fd346554 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 27 Dec 2023 23:17:52 -0700 Subject: [PATCH 078/238] kern: allow ktrace map capability when ktrace is disabled --- libraries/libmesosphere/source/kern_k_capabilities.cpp | 5 +++++ stratosphere/loader/source/ldr_capabilities.cpp | 10 +--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libraries/libmesosphere/source/kern_k_capabilities.cpp b/libraries/libmesosphere/source/kern_k_capabilities.cpp index 6b2c6f4b4..feb245eda 100644 --- a/libraries/libmesosphere/source/kern_k_capabilities.cpp +++ b/libraries/libmesosphere/source/kern_k_capabilities.cpp @@ -184,6 +184,11 @@ namespace ams::kern { case RegionType::NoMapping: break; case RegionType::KernelTraceBuffer: + /* NOTE: This does not match official, but is used to make pre-processing hbl capabilities in userland unnecessary. */ + /* If ktrace isn't enabled, allow ktrace to succeed without mapping anything. */ + if constexpr (!ams::kern::IsKTraceEnabled) { + break; + } case RegionType::OnMemoryBootImage: case RegionType::DTB: R_TRY(f(MemoryRegions[static_cast(type)], perm)); diff --git a/stratosphere/loader/source/ldr_capabilities.cpp b/stratosphere/loader/source/ldr_capabilities.cpp index c1693c7b4..6835267b3 100644 --- a/stratosphere/loader/source/ldr_capabilities.cpp +++ b/stratosphere/loader/source/ldr_capabilities.cpp @@ -418,15 +418,7 @@ namespace ams::ldr { for (size_t i = 0; i < count; ++i) { const auto cap = kac[i]; switch (GetCapabilityId(cap)) { - case CapabilityId::MapRegion: - { - /* MapRegion was added in 8.0.0+, and is only allowed under kernels which have the relevant mappings. */ - /* However, we allow it under all firmwares on mesosphere, to facilitate KTrace usage by hbl. */ - if (!svc::IsKTraceEnabled()) { - kac[i] = EmptyCapability; - } - } - break; + /* NOTE: Currently, there is no pre-processing necessary. */ default: break; } From e09ba765a128e8bd7203f8bcd2abd70ecfcb9332 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 27 Dec 2023 23:24:35 -0700 Subject: [PATCH 079/238] kern: fix various comment/style hygiene issues (thanks @liamwhite) --- fusee/loader_stub/source/fusee_loader_uncompress.cpp | 2 +- libraries/libmesosphere/source/kern_k_client_port.cpp | 2 -- libraries/libmesosphere/source/kern_k_page_table_base.cpp | 6 +++--- libraries/libmesosphere/source/kern_k_server_port.cpp | 4 ++-- libraries/libmesosphere/source/kern_k_server_session.cpp | 6 +++--- libraries/libmesosphere/source/svc/kern_svc_ipc.cpp | 8 ++++---- libraries/libmesosphere/source/svc/kern_svc_port.cpp | 2 +- 7 files changed, 14 insertions(+), 16 deletions(-) diff --git a/fusee/loader_stub/source/fusee_loader_uncompress.cpp b/fusee/loader_stub/source/fusee_loader_uncompress.cpp index ace64588f..94ed4ff73 100644 --- a/fusee/loader_stub/source/fusee_loader_uncompress.cpp +++ b/fusee/loader_stub/source/fusee_loader_uncompress.cpp @@ -96,7 +96,7 @@ namespace ams::nxboot::loader { } void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) { - /* Create an execute a decompressor. */ + /* Create and execute a decompressor. */ Lz4Uncompressor(dst, dst_size, src, src_size).Uncompress(); } diff --git a/libraries/libmesosphere/source/kern_k_client_port.cpp b/libraries/libmesosphere/source/kern_k_client_port.cpp index 11977334f..71ca3d7dd 100644 --- a/libraries/libmesosphere/source/kern_k_client_port.cpp +++ b/libraries/libmesosphere/source/kern_k_client_port.cpp @@ -107,7 +107,6 @@ namespace ams::kern { R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions()); new_sessions = cur_sessions + 1; } while (!m_num_sessions.CompareExchangeWeak(cur_sessions, new_sessions)); - } /* Atomically update the peak session tracking. */ @@ -182,7 +181,6 @@ namespace ams::kern { R_UNLESS(cur_sessions < max, svc::ResultOutOfSessions()); new_sessions = cur_sessions + 1; } while (!m_num_sessions.CompareExchangeWeak(cur_sessions, new_sessions)); - } /* Atomically update the peak session tracking. */ diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index d1ee43054..4ec5834be 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -3624,7 +3624,7 @@ namespace ams::kern { R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); /* Get the source permission. */ - const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped : KMemoryPermission_UserRead); + const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? (KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped) : KMemoryPermission_UserRead); /* Get aligned extents. */ const KProcessAddress aligned_src_start = util::AlignDown(GetInteger(address), PageSize); @@ -3953,7 +3953,7 @@ namespace ams::kern { const size_t src_map_size = src_map_end - src_map_start; /* Ensure that we clean up appropriately if we fail after this. */ - const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped : KMemoryPermission_UserRead); + const auto src_perm = static_cast((test_perm == KMemoryPermission_UserReadWrite) ? (KMemoryPermission_KernelReadWrite | KMemoryPermission_NotMapped) : KMemoryPermission_UserRead); ON_RESULT_FAILURE { if (src_map_end > src_map_start) { src_page_table.CleanupForIpcClientOnServerSetupFailure(updater.GetPageList(), src_map_start, src_map_size, src_perm); @@ -4488,7 +4488,7 @@ namespace ams::kern { } } - /* Map the papges. */ + /* Map the pages. */ R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages, cur_pg, map_properties, OperationType_MapFirstGroup, false)); } } diff --git a/libraries/libmesosphere/source/kern_k_server_port.cpp b/libraries/libmesosphere/source/kern_k_server_port.cpp index 765b14391..82223bfe3 100644 --- a/libraries/libmesosphere/source/kern_k_server_port.cpp +++ b/libraries/libmesosphere/source/kern_k_server_port.cpp @@ -36,7 +36,7 @@ namespace ams::kern { /* Cleanup the session list. */ while (true) { - /* Get the last session in the list */ + /* Get the last session in the list. */ KServerSession *session = nullptr; { KScopedSchedulerLock sl; @@ -56,7 +56,7 @@ namespace ams::kern { /* Cleanup the light session list. */ while (true) { - /* Get the last session in the list */ + /* Get the last session in the list. */ KLightServerSession *session = nullptr; { KScopedSchedulerLock sl; diff --git a/libraries/libmesosphere/source/kern_k_server_session.cpp b/libraries/libmesosphere/source/kern_k_server_session.cpp index 035aa3980..7c8c4e91c 100644 --- a/libraries/libmesosphere/source/kern_k_server_session.cpp +++ b/libraries/libmesosphere/source/kern_k_server_session.cpp @@ -650,7 +650,7 @@ namespace ams::kern { const auto src_state = src_user ? KMemoryState_FlagReferenceCounted : KMemoryState_FlagLinearMapped; /* Determine the source permission. User buffer should be unmapped + read, TLS should be user readable. */ - const KMemoryPermission src_perm = static_cast(src_user ? KMemoryPermission_NotMapped | KMemoryPermission_KernelRead : KMemoryPermission_UserRead); + const KMemoryPermission src_perm = static_cast(src_user ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelRead) : KMemoryPermission_UserRead); /* Perform the fast part of the copy. */ R_TRY(src_page_table.CopyMemoryFromLinearToKernel(reinterpret_cast(dst_msg_ptr) + offset_words, fast_size, src_message_buffer + offset_words, @@ -753,7 +753,7 @@ namespace ams::kern { /* Perform the pointer data copy. */ const bool dst_heap = dst_user && dst_recv_list.IsToMessageBuffer(); const auto dst_state = dst_heap ? KMemoryState_FlagReferenceCounted : KMemoryState_FlagLinearMapped; - const KMemoryPermission dst_perm = static_cast(dst_heap ? KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite : KMemoryPermission_UserReadWrite); + const KMemoryPermission dst_perm = static_cast(dst_heap ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite) : KMemoryPermission_UserReadWrite); R_TRY(dst_page_table.CopyMemoryFromUserToLinear(recv_pointer, recv_size, dst_state, dst_state, dst_perm, @@ -911,7 +911,7 @@ namespace ams::kern { const auto dst_state = dst_user ? KMemoryState_FlagReferenceCounted : KMemoryState_FlagLinearMapped; /* Determine the dst permission. User buffer should be unmapped + read, TLS should be user readable. */ - const KMemoryPermission dst_perm = static_cast(dst_user ? KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite : KMemoryPermission_UserReadWrite); + const KMemoryPermission dst_perm = static_cast(dst_user ? (KMemoryPermission_NotMapped | KMemoryPermission_KernelReadWrite) : KMemoryPermission_UserReadWrite); /* Perform the fast part of the copy. */ R_TRY(dst_page_table.CopyMemoryFromKernelToLinear(dst_message_buffer + offset_words, fast_size, diff --git a/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp b/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp index 06393a3f7..a67b581cb 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_ipc.cpp @@ -143,7 +143,7 @@ namespace ams::kern::svc { /* Get the process page table. */ auto &page_table = GetCurrentProcess().GetPageTable(); - /* Lock the mesage buffer. */ + /* Lock the message buffer. */ R_TRY(page_table.LockForIpcUserBuffer(nullptr, message, buffer_size)); { @@ -186,7 +186,7 @@ namespace ams::kern::svc { /* Commit our reservation. */ event_reservation.Commit(); - /* At end of scope, kill the standing references to the sub events. */ + /* At end of scope, kill the standing event references. */ ON_SCOPE_EXIT { event->GetReadableEvent().Close(); event->Close(); @@ -215,7 +215,7 @@ namespace ams::kern::svc { /* Get the process page table. */ auto &page_table = GetCurrentProcess().GetPageTable(); - /* Lock the mesage buffer. */ + /* Lock the message buffer. */ R_TRY(page_table.LockForIpcUserBuffer(nullptr, message, buffer_size)); /* Ensure that if we fail and aren't terminating that we unlock the user buffer. */ @@ -242,7 +242,7 @@ namespace ams::kern::svc { /* Get the process page table. */ auto &page_table = GetCurrentProcess().GetPageTable(); - /* Lock the mesage buffer, getting its physical address. */ + /* Lock the message buffer, getting its physical address. */ KPhysicalAddress message_paddr; R_TRY(page_table.LockForIpcUserBuffer(std::addressof(message_paddr), message, buffer_size)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_port.cpp b/libraries/libmesosphere/source/svc/kern_svc_port.cpp index d4520d287..1ac5803d2 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_port.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_port.cpp @@ -96,7 +96,7 @@ namespace ams::kern::svc { /* Add the client to the handle table. */ R_TRY(handle_table.Add(out_client, std::addressof(port->GetClientPort()))); - /* Ensure that we maintaing a clean handle state on exit. */ + /* Ensure that we maintain a clean handle state on exit. */ ON_RESULT_FAILURE { handle_table.Remove(*out_client); }; /* Add the server to the handle table. */ From fc16f28d0c4814249d76783e5e7b604a11c17a9e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 8 Jan 2024 12:20:53 -0700 Subject: [PATCH 080/238] settings: support PortugueseBr (closes #2264) --- .../stratosphere/settings/settings_types.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp b/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp index 410bad5eb..4290a0eba 100644 --- a/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/settings/settings_types.hpp @@ -53,7 +53,8 @@ namespace ams::settings { /* 4.0.0+ */ Language_SimplifiedChinese, Language_TraditionalChinese, - + /* 10.1.0+ */ + Language_PortugueseBr, Language_Count, }; @@ -92,6 +93,8 @@ namespace ams::settings { /* 4.0.0+ */ AMS_MATCH_LANGUAGE(SimplifiedChinese, "zh-Hans") AMS_MATCH_LANGUAGE(TraditionalChinese, "zh-Hant") + /* 10.1.0+ */ + AMS_MATCH_LANGUAGE(PortugueseBr, "pt-BR") #undef AMS_MATCH_LANGUAGE else { static_assert(Lang != Language_Japanese); } } @@ -116,6 +119,8 @@ namespace ams::settings { /* 4.0.0+ */ EncodeLanguage(), EncodeLanguage(), + /* 10.1.0+ */ + EncodeLanguage(), }; return EncodedLanguages[language]; } @@ -156,7 +161,11 @@ namespace ams::settings { } constexpr inline bool IsValidLanguageCodeDeprecated(const LanguageCode &lc) { - return impl::IsValidLanguageCode(lc, std::make_index_sequence{}); + return impl::IsValidLanguageCode(lc, std::make_index_sequence{}); + } + + constexpr inline bool IsValidLanguageCodeDeprecated2(const LanguageCode &lc) { + return impl::IsValidLanguageCode(lc, std::make_index_sequence{}); } constexpr inline bool IsValidLanguageCode(const LanguageCode &lc) { From e919b80fa29c4427ba778e10059b82271c939cd8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 20 Jan 2024 13:09:04 -0700 Subject: [PATCH 081/238] pm: improve resource limit management accuracy This change was made for #2255, but the issue creator never confirmed if it resolved the issue. This *does* better reflect what Nintendo's pm does, though, so I'm going to commit it regardless. --- stratosphere/pm/source/impl/pm_spec.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/stratosphere/pm/source/impl/pm_spec.cpp b/stratosphere/pm/source/impl/pm_spec.cpp index a395b0255..9127d2e6a 100644 --- a/stratosphere/pm/source/impl/pm_spec.cpp +++ b/stratosphere/pm/source/impl/pm_spec.cpp @@ -243,29 +243,35 @@ namespace ams::pm::impl { const u64 boost_size = normal_boost + mitm_boost; /* Don't allow all application memory to be taken away. */ - R_UNLESS(boost_size <= g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application], pm::ResultInvalidSize()); + R_UNLESS(boost_size < g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application], pm::ResultInvalidSize()); const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size; { std::scoped_lock lk(g_resource_limit_lock); + const auto cur_boost_size = GetCurrentSystemMemoryBoostSize(); + if (hos::GetVersion() >= hos::Version_5_0_0) { /* Starting in 5.0.0, PM does not allow for only one of the sets to fail. */ - if (boost_size < GetCurrentSystemMemoryBoostSize()) { + if (boost_size < cur_boost_size) { R_TRY(svc::SetUnsafeLimit(boost_size)); R_ABORT_UNLESS(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); - } else { + } else if (boost_size > cur_boost_size) { R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); R_ABORT_UNLESS(svc::SetUnsafeLimit(boost_size)); + } else { + /* If the boost size is equal, there's nothing to do. */ } } else { const u64 new_sys_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_System] + boost_size; - if (boost_size < GetCurrentSystemMemoryBoostSize()) { + if (boost_size < cur_boost_size) { R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size)); R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); + } else if (boost_size > cur_boost_size) { + R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); + R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size)); } else { - R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_Application, new_app_size)); - R_TRY(SetMemoryResourceLimitLimitValue(ResourceLimitGroup_System, new_sys_size)); + /* If the boost size is equal, there's nothing to do. */ } } From 72b0fe6c1c5c1211371eb17a61df17b4ee18a025 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 20 Jan 2024 13:31:12 -0700 Subject: [PATCH 082/238] strat: fix nx_debug build target --- .../source/fs/fs_romfs_filesystem.cpp | 2 +- .../source/htc/server/rpc/htc_rpc_client.cpp | 2 +- .../source/htcs/impl/htcs_manager.cpp | 44 +++++++++---------- .../dns_mitm/dnsmitm_host_redirection.cpp | 4 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp b/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp index 0fbeefa1e..02845fdfe 100644 --- a/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp +++ b/libraries/libstratosphere/source/fs/fs_romfs_filesystem.cpp @@ -500,7 +500,7 @@ namespace ams::fs { R_UNLESS((mode & fs::OpenMode_All) == fs::OpenMode_Read, fs::ResultInvalidOpenMode()); - RomFileTable::FileInfo file_info; + RomFileTable::FileInfo file_info{}; R_TRY(this->GetFileInfo(std::addressof(file_info), path.GetString())); auto file = std::make_unique(this, m_entry_size + file_info.offset.Get(), m_entry_size + file_info.offset.Get() + file_info.size.Get()); diff --git a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp index 19d29b03b..df5f84d5d 100644 --- a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp +++ b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_client.cpp @@ -288,7 +288,7 @@ namespace ams::htc::server::rpc { /* Get a task. */ Task *task; u32 task_id{}; - PacketCategory category; + PacketCategory category{}; do { /* Dequeue a task. */ R_TRY(m_task_queue.Take(std::addressof(task_id), std::addressof(category))); diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp b/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp index 1900c90cf..aac4c7195 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp @@ -39,7 +39,7 @@ namespace ams::htcs::impl { void HtcsManager::Socket(s32 *out_err, s32 *out_desc, bool enable_disconnection_emulation) { /* Invoke our implementation. */ - s32 err, desc; + s32 err = -1, desc = -1; const Result result = m_impl->CreateSocket(std::addressof(err), std::addressof(desc), enable_disconnection_emulation); /* Set output. */ @@ -71,7 +71,7 @@ namespace ams::htcs::impl { void HtcsManager::Connect(s32 *out_err, s32 *out_res, const SockAddrHtcs &address, s32 desc) { /* Invoke our implementation. */ - s32 err; + s32 err = -1; const Result result = m_impl->Connect(std::addressof(err), desc, address); /* Set output. */ @@ -90,7 +90,7 @@ namespace ams::htcs::impl { void HtcsManager::Bind(s32 *out_err, s32 *out_res, const SockAddrHtcs &address, s32 desc) { /* Invoke our implementation. */ - s32 err; + s32 err = -1; const Result result = m_impl->Bind(std::addressof(err), desc, address); /* Set output. */ @@ -109,7 +109,7 @@ namespace ams::htcs::impl { void HtcsManager::Listen(s32 *out_err, s32 *out_res, s32 backlog_count, s32 desc) { /* Invoke our implementation. */ - s32 err; + s32 err = -1; const Result result = m_impl->Listen(std::addressof(err), desc, backlog_count); /* Set output. */ @@ -128,8 +128,8 @@ namespace ams::htcs::impl { void HtcsManager::Recv(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 flags, s32 desc) { /* Invoke our implementation. */ - s32 err; - s64 recv_size; + s32 err = -1; + s64 recv_size = -1; const Result result = m_impl->Receive(std::addressof(err), std::addressof(recv_size), buffer, size, desc, flags); /* Set output. */ @@ -148,8 +148,8 @@ namespace ams::htcs::impl { void HtcsManager::Send(s32 *out_err, s64 *out_size, const char *buffer, size_t size, s32 flags, s32 desc) { /* Invoke our implementation. */ - s32 err; - s64 send_size; + s32 err = -1; + s64 send_size = -1; const Result result = m_impl->Send(std::addressof(err), std::addressof(send_size), buffer, size, desc, flags); /* Set output. */ @@ -168,7 +168,7 @@ namespace ams::htcs::impl { void HtcsManager::Shutdown(s32 *out_err, s32 *out_res, s32 how, s32 desc) { /* Invoke our implementation. */ - s32 err; + s32 err = -1; const Result result = m_impl->Shutdown(std::addressof(err), desc, how); /* Set output. */ @@ -191,7 +191,7 @@ namespace ams::htcs::impl { void HtcsManager::Fcntl(s32 *out_err, s32 *out_res, s32 command, s32 value, s32 desc) { /* Invoke our implementation. */ - s32 err, res; + s32 err = -1, res = -1; const Result result = m_impl->Fcntl(std::addressof(err), std::addressof(res), desc, command, value); /* Set output. */ @@ -210,7 +210,7 @@ namespace ams::htcs::impl { void HtcsManager::AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err; + s32 err = -1; const Result result = m_impl->AcceptResults(std::addressof(err), out_desc, out_address, task_id, desc); /* Set output. */ @@ -233,8 +233,8 @@ namespace ams::htcs::impl { void HtcsManager::RecvResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err; - s64 size; + s32 err = -1; + s64 size = -1; const Result result = m_impl->RecvResults(std::addressof(err), std::addressof(size), buffer, buffer_size, task_id, desc); /* Set output. */ @@ -265,8 +265,8 @@ namespace ams::htcs::impl { void HtcsManager::SendResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err; - s64 size; + s32 err = -1; + s64 size = -1; const Result result = m_impl->SendResults(std::addressof(err), std::addressof(size), task_id, desc); /* Set output. */ @@ -293,7 +293,7 @@ namespace ams::htcs::impl { Result HtcsManager::ContinueSend(s64 *out_size, const char *buffer, s64 buffer_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s64 size; + s64 size = -1; R_TRY_CATCH(m_impl->ContinueSend(std::addressof(size), buffer, buffer_size, task_id, desc)) { R_CONVERT(htclow::ResultInvalidChannelState, tma::ResultUnknown()) R_CONVERT(htc::ResultTaskCancelled, tma::ResultUnknown()) @@ -306,8 +306,8 @@ namespace ams::htcs::impl { void HtcsManager::EndSend(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err; - s64 size; + s32 err = -1; + s64 size = -1; const Result result = m_impl->EndSend(std::addressof(err), std::addressof(size), task_id, desc); /* Set output. */ @@ -334,8 +334,8 @@ namespace ams::htcs::impl { void HtcsManager::EndRecv(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { /* Invoke our implementation. */ - s32 err; - s64 size; + s32 err = -1; + s64 size = -1; const Result result = m_impl->EndRecv(std::addressof(err), std::addressof(size), buffer, buffer_size, task_id, desc); /* Set output. */ @@ -367,8 +367,8 @@ namespace ams::htcs::impl { Result HtcsManager::EndSelect(s32 *out_err, s32 *out_count, Span read_handles, Span write_handles, Span exception_handles, u32 task_id) { /* Invoke our implementation. */ - s32 err; - bool empty; + s32 err = -1; + bool empty = false; const Result result = m_impl->EndSelect(std::addressof(err), std::addressof(empty), read_handles, write_handles, exception_handles, task_id); /* Set output. */ diff --git a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp index d837ada71..ea6f1eb09 100644 --- a/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp +++ b/stratosphere/ams_mitm/source/dns_mitm/dnsmitm_host_redirection.cpp @@ -107,9 +107,9 @@ namespace ams::mitm::socket::resolver { HostName, }; - ams::socket::InAddrT current_address; + ams::socket::InAddrT current_address{}; char current_hostname[0x200]; - u32 work; + u32 work{}; State state = State::BeginLine; for (const char *cur = file_data; *cur != '\x00'; ++cur) { From 3627356d4bce374396a5242f10c18b90fa3f7766 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 21 Jan 2024 14:10:59 -0500 Subject: [PATCH 083/238] dmnt.gen2: enable gdbserver QStartNoAckMode --- .../dmnt.gen2/source/dmnt2_gdb_server_impl.cpp | 11 +++++++++-- .../dmnt.gen2/source/dmnt2_gdb_server_impl.hpp | 4 +++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp index ddb0d8fbc..757a237a8 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.cpp @@ -1538,13 +1538,18 @@ namespace ams::dmnt { } void GdbServerImpl::Q() { - if (false) { - /* TODO: QStartNoAckMode? */ + if (ParsePrefix(m_receive_packet, "QStartNoAckMode")) { + this->QStartNoAckMode(); } else { AMS_DMNT2_GDB_LOG_DEBUG("Not Implemented Q: %s\n", m_receive_packet); } } + void GdbServerImpl::QStartNoAckMode() { + m_packet_io.SetNoAck(); + AppendReplyOk(m_reply_cur, m_reply_end); + } + void GdbServerImpl::T() { if (const char *dot = std::strchr(m_receive_packet, '.'); dot != nullptr) { const u64 thread_id = DecodeHex(dot + 1); @@ -1919,6 +1924,7 @@ namespace ams::dmnt { R_SUCCEED(); } + void GdbServerImpl::q() { if (ParsePrefix(m_receive_packet, "qAttached:")) { this->qAttached(); @@ -2145,6 +2151,7 @@ namespace ams::dmnt { AppendReplyFormat(m_reply_cur, m_reply_end, ";swbreak+"); AppendReplyFormat(m_reply_cur, m_reply_end, ";hwbreak+"); AppendReplyFormat(m_reply_cur, m_reply_end, ";vContSupported+"); + AppendReplyFormat(m_reply_cur, m_reply_end, ";QStartNoAckMode+"); } void GdbServerImpl::qXfer() { diff --git a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp index 5aca349e5..e0648cd1d 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_gdb_server_impl.hpp @@ -77,6 +77,8 @@ namespace ams::dmnt { void Q(); + void QStartNoAckMode(); + void T(); void Z(); @@ -115,4 +117,4 @@ namespace ams::dmnt { Result ParseVCont(char * const token, u64 *thread_ids, u8 *continue_modes, s32 num_threads, DebugProcess::ContinueMode &default_continue_mode); }; -} \ No newline at end of file +} From 000e382c4227e4de4197fe26faa0d76f9df3ef40 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 21 Jan 2024 15:32:06 -0500 Subject: [PATCH 084/238] dmnt.gen2: avoid data abort when too many breakpoints are created --- stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp index f13a59508..956226448 100644 --- a/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp +++ b/stratosphere/dmnt.gen2/source/dmnt2_breakpoint_manager.cpp @@ -45,7 +45,7 @@ namespace ams::dmnt { } if (R_FAILED(result)) { - AMS_DMNT2_GDB_LOG_DEBUG("BreakPointManager::SetBreakPoint %p 0x%lx !!! Fail 0x%08x !!!\n", bp, bp->m_address, result.GetValue()); + AMS_DMNT2_GDB_LOG_DEBUG("BreakPointManager::SetBreakPoint %p 0x%lx !!! Fail 0x%08x !!!\n", bp, address, result.GetValue()); } R_RETURN(result); From 615f8a3ef3dc06f84935763e1246ba1d9c70d4e9 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 4 Feb 2024 12:39:07 -0600 Subject: [PATCH 085/238] dmnt: Fix debug log for cheats --- stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index 2d56ab4c6..e553efd0b 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -46,8 +46,11 @@ namespace ams::dmnt::cheat::impl { void CheatVirtualMachine::OpenDebugLogFile() { #ifdef DMNT_CHEAT_VM_DEBUG_LOG CloseDebugLogFile(); - R_ABORT_UNLESS(fs::OpenFile(std::addressof(m_debug_log_file), "sdmc:/atmosphere/cheat_vm_logs/debug_log.txt")); + fs::EnsureDirectory("sdmc:/atmosphere/cheat_vm_logs"); + fs::CreateFile("sdmc:/atmosphere/cheat_vm_logs/debug_log.txt", 0); + R_ABORT_UNLESS(fs::OpenFile(std::addressof(m_debug_log_file), "sdmc:/atmosphere/cheat_vm_logs/debug_log.txt", fs::OpenMode_Write | fs::OpenMode_AllowAppend)); m_debug_log_file_offset = 0; + m_has_debug_log_file = true; #endif } @@ -80,7 +83,8 @@ namespace ams::dmnt::cheat::impl { fmt_len += 1; } - fs::WriteFile(m_debug_log_file, m_debug_log_offset, m_debug_log_format_buf, fmt_len, fs::WriteOption::Flush); + fs::WriteFile(m_debug_log_file, m_debug_log_file_offset, m_debug_log_format_buf, fmt_len, fs::WriteOption::Flush); + m_debug_log_file_offset += fmt_len; #else AMS_UNUSED(format); #endif From 0220f67085ea06306379f9545b4d911b68c30c51 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 23 Feb 2024 13:55:43 -0700 Subject: [PATCH 086/238] fssrv: fix dumb assert error --- .../source/fssrv/fssrv_program_registry_impl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp index 2029ce740..5de1482f1 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_program_registry_impl.cpp @@ -34,8 +34,8 @@ namespace ams::fssrv { void ProgramRegistryImpl::Initialize(ProgramRegistryServiceImpl *service) { /* Check pre-conditions. */ - AMS_ASSERT(g_impl != nullptr); - AMS_ASSERT(g_impl == nullptr); + AMS_ASSERT(service != nullptr); + AMS_ASSERT(g_impl == nullptr); /* Set the global service. */ g_impl = service; From c8c76bf8f8f6f9587de5d8ac1bd7090635353e9b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 4 Mar 2024 14:51:44 -0700 Subject: [PATCH 087/238] readme: I suppose we're living in 2024, then --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2e3f1a7fd..ca26e6a39 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ This software is licensed under the terms of the GPLv2, with exemptions for spec You can find a copy of the license in the [LICENSE file](LICENSE). Exemptions: -* The [yuzu Nintendo Switch emulator](https://github.com/yuzu-emu/yuzu) and the [Ryujinx Team and Contributors](https://github.com/orgs/Ryujinx) are exempt from GPLv2 licensing. They are permitted, each at their individual discretion, to instead license any source code authored for the Atmosphère project as either GPLv2 or later or the [MIT license](https://github.com/Atmosphere-NX/Atmosphere/blob/master/docs/licensing_exemptions/MIT_LICENSE). In doing so, they may alter, supplement, or entirely remove the copyright notice for each file they choose to relicense. Neither the Atmosphère project nor its individual contributors shall assert their moral rights against any of the aforementioned projects. * [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project under the Zero-Clause BSD license. Credits From 9701d5b2abb59021da112b1b5d739c4118515c47 Mon Sep 17 00:00:00 2001 From: JerryWn <2571290541qq@gmail.com> Date: Wed, 20 Mar 2024 15:56:08 +0800 Subject: [PATCH 088/238] readme: fix broken discord icon --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca26e6a39..bfae12a27 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ===== ![License](https://img.shields.io/badge/License-GPLv2-blue.svg) -[![Chat on Discord](https://camo.githubusercontent.com/b4175720ede4f2621aa066ffbabb70ae30044679/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636861742d446973636f72642d627269676874677265656e2e737667)](https://discordapp.com/invite/ZdqEhed) +[![Chat on Discord](https://img.shields.io/badge/Discord-5865f2?logo=discord&logoColor=white)](https://discordapp.com/invite/ZdqEhed) Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. From 1f37fbed1d0c16e6b9f821367d3c9f28a75c6e28 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 27 Mar 2024 18:48:49 -0700 Subject: [PATCH 089/238] fusee/exo/ams: update with new keydata/version enums --- .../program/source/boot/secmon_boot_key_data.s | 9 +++++++-- exosphere/program/source/boot/secmon_package2.cpp | 2 +- fusee/program/source/fusee_key_derivation.cpp | 11 ++++++++--- fusee/program/source/fusee_package2.cpp | 2 +- fusee/program/source/fusee_setup_horizon.cpp | 2 ++ fusee/program/source/fusee_stratosphere.cpp | 14 ++++++++++++++ .../include/exosphere/pkg1/pkg1_key_generation.hpp | 1 + libraries/libexosphere/include/exosphere/pkg2.hpp | 2 +- libraries/libexosphere/source/fuse/fuse_api.cpp | 1 + .../include/stratosphere/hos/hos_types.hpp | 2 ++ .../fs/impl/fs_id_string_impl.os.generic.cpp | 5 +++-- .../include/vapours/ams/ams_api_version.h | 6 +++--- .../include/vapours/ams/ams_target_firmware.h | 6 +++++- 13 files changed, 49 insertions(+), 14 deletions(-) diff --git a/exosphere/program/source/boot/secmon_boot_key_data.s b/exosphere/program/source/boot/secmon_boot_key_data.s index c8f390eb5..b745114f1 100644 --- a/exosphere/program/source/boot/secmon_boot_key_data.s +++ b/exosphere/program/source/boot/secmon_boot_key_data.s @@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* TODO: Update on next change of keys. */ /* Mariko Development Master Kek Source. */ -.byte 0x43, 0xDB, 0x9D, 0x88, 0xDB, 0x38, 0xE9, 0xBF, 0x3D, 0xD7, 0x83, 0x39, 0xEF, 0xB1, 0x4F, 0xA7 +.byte 0xE4, 0x45, 0xD0, 0x14, 0xA0, 0xE5, 0xE9, 0x4B, 0xFE, 0x76, 0xF4, 0x29, 0x41, 0xBB, 0x64, 0xED /* Mariko Production Master Kek Source. */ -.byte 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 +.byte 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 /* Development Master Key Vectors. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ @@ -108,6 +108,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xD6, 0x80, 0x98, 0xC0, 0xFA, 0xC7, 0x13, 0xCB, 0x93, 0xD2, 0x0B, 0x82, 0x4C, 0xA1, 0x7B, 0x8D /* Master key 0D encrypted with Master key 0E. */ .byte 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 /* Master key 0E encrypted with Master key 0F. */ .byte 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 /* Master key 0F encrypted with Master key 10. */ +.byte 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */ /* Production Master Key Vectors. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ @@ -127,6 +128,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 /* Master key 0D encrypted with Master key 0E. */ .byte 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 /* Master key 0E encrypted with Master key 0F. */ .byte 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD /* Master key 0F encrypted with Master key 10. */ +.byte 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */ /* Device Master Key Source Sources. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ @@ -143,6 +145,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 /* 15.0.0 Device Master Key Source Source. */ .byte 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C /* 16.0.0 Device Master Key Source Source. */ .byte 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 /* 17.0.0 Device Master Key Source Source. */ +.byte 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */ /* Development Device Master Kek Sources. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ @@ -159,6 +162,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xAE, 0x05, 0x48, 0x65, 0xAB, 0x17, 0x9D, 0x3D, 0x51, 0xB7, 0x56, 0xBD, 0x9B, 0x0B, 0x5B, 0x6E /* 15.0.0 Device Master Kek Source. */ .byte 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F /* 16.0.0 Device Master Kek Source. */ .byte 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 /* 17.0.0 Device Master Kek Source. */ +.byte 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */ /* Production Device Master Kek Sources. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ @@ -175,3 +179,4 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 /* 15.0.0 Device Master Kek Source. */ .byte 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F /* 16.0.0 Device Master Kek Source. */ .byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */ +.byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */ diff --git a/exosphere/program/source/boot/secmon_package2.cpp b/exosphere/program/source/boot/secmon_package2.cpp index a4ad690a9..a51e1a712 100644 --- a/exosphere/program/source/boot/secmon_package2.cpp +++ b/exosphere/program/source/boot/secmon_package2.cpp @@ -94,7 +94,7 @@ namespace ams::secmon::boot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 17); + static_assert(pkg1::KeyGeneration_Count == 18); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_key_derivation.cpp b/fusee/program/source/fusee_key_derivation.cpp index a77f07911..cad7ca589 100644 --- a/fusee/program/source/fusee_key_derivation.cpp +++ b/fusee/program/source/fusee_key_derivation.cpp @@ -23,17 +23,17 @@ namespace ams::nxboot { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 + 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x43, 0xDB, 0x9D, 0x88, 0xDB, 0x38, 0xE9, 0xBF, 0x3D, 0xD7, 0x83, 0x39, 0xEF, 0xB1, 0x4F, 0xA7 + 0xE4, 0x45, 0xD0, 0x14, 0xA0, 0xE5, 0xE9, 0x4B, 0xFE, 0x76, 0xF4, 0x29, 0x41, 0xBB, 0x64, 0xED }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x71, 0xB9, 0xA6, 0xC0, 0xFF, 0x97, 0x6B, 0x0C, 0xB4, 0x40, 0xB9, 0xD5, 0x81, 0x5D, 0x81, 0x90 + 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -71,6 +71,7 @@ namespace ams::nxboot { { 0x5E, 0xC9, 0xC5, 0x0A, 0xD0, 0x5F, 0x8B, 0x7B, 0xA7, 0x39, 0xEA, 0xBC, 0x60, 0x0F, 0x74, 0xE6 }, /* 15.0.0 Device Master Key Source Source. */ { 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, /* 16.0.0 Device Master Key Source Source. */ { 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, /* 17.0.0 Device Master Key Source Source. */ + { 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -88,6 +89,7 @@ namespace ams::nxboot { { 0x7C, 0x30, 0xED, 0x8B, 0x39, 0x25, 0x2C, 0x08, 0x8F, 0x48, 0xDC, 0x28, 0xE6, 0x1A, 0x6B, 0x49 }, /* 15.0.0 Device Master Kek Source. */ { 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, /* 16.0.0 Device Master Kek Source. */ { 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, /* 17.0.0 Device Master Kek Source. */ + { 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -105,6 +107,7 @@ namespace ams::nxboot { { 0xAE, 0x05, 0x48, 0x65, 0xAB, 0x17, 0x9D, 0x3D, 0x51, 0xB7, 0x56, 0xBD, 0x9B, 0x0B, 0x5B, 0x6E }, /* 15.0.0 Device Master Kek Source. */ { 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F }, /* 16.0.0 Device Master Kek Source. */ { 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 }, /* 17.0.0 Device Master Kek Source. */ + { 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -125,6 +128,7 @@ namespace ams::nxboot { { 0xB1, 0x81, 0xA6, 0x0D, 0x72, 0xC7, 0xEE, 0x15, 0x21, 0xF3, 0xC0, 0xB5, 0x6B, 0x61, 0x6D, 0xE7 }, /* Master key 0D encrypted with Master key 0E. */ { 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, /* Master key 0E encrypted with Master key 0F. */ { 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, /* Master key 0F encrypted with Master key 10. */ + { 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -145,6 +149,7 @@ namespace ams::nxboot { { 0xD6, 0x80, 0x98, 0xC0, 0xFA, 0xC7, 0x13, 0xCB, 0x93, 0xD2, 0x0B, 0x82, 0x4C, 0xA1, 0x7B, 0x8D }, /* Master key 0D encrypted with Master key 0E. */ { 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 }, /* Master key 0E encrypted with Master key 0F. */ { 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 }, /* Master key 0F encrypted with Master key 10. */ + { 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */ }; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; diff --git a/fusee/program/source/fusee_package2.cpp b/fusee/program/source/fusee_package2.cpp index 63aa2a37d..535f0f68d 100644 --- a/fusee/program/source/fusee_package2.cpp +++ b/fusee/program/source/fusee_package2.cpp @@ -80,7 +80,7 @@ namespace ams::nxboot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 17); + static_assert(pkg1::KeyGeneration_Count == 18); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 8de07bab4..78c40b216 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -259,6 +259,8 @@ namespace ams::nxboot { return ams::TargetFirmware_16_0_0; } else if (std::memcmp(package1 + 0x10, "20230906", 8) == 0) { return ams::TargetFirmware_17_0_0; + } else if (std::memcmp(package1 + 0x10, "20240207", 8) == 0) { + return ams::TargetFirmware_18_0_0; } break; default: diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index bcaff0395..add639c05 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -171,6 +171,9 @@ namespace ams::nxboot { FsVersion_17_0_0, FsVersion_17_0_0_Exfat, + FsVersion_18_0_0, + FsVersion_18_0_0_Exfat, + FsVersion_Count, }; @@ -254,6 +257,9 @@ namespace ams::nxboot { { 0x27, 0x07, 0x3B, 0xF0, 0xA1, 0xB8, 0xCE, 0x61 }, /* FsVersion_17_0_0 */ { 0xEE, 0x0F, 0x4B, 0xAC, 0x6D, 0x1F, 0xFC, 0x4B }, /* FsVersion_17_0_0_Exfat */ + + { 0x79, 0x5F, 0x5A, 0x5E, 0xB0, 0xC6, 0x77, 0x9E }, /* FsVersion_18_0_0 */ + { 0x1E, 0x2C, 0x64, 0xB1, 0xCC, 0xE2, 0x78, 0x24 }, /* FsVersion_18_0_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -617,6 +623,14 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x195FA9, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x170060, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_18_0_0: + AddPatch(fs_meta, 0x18AF49, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x164B50, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_18_0_0_Exfat: + AddPatch(fs_meta, 0x195FD9, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x16FBE0, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } diff --git a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp index 64330af7a..0cfc43633 100644 --- a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp +++ b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp @@ -37,6 +37,7 @@ namespace ams::pkg1 { KeyGeneration_15_0_0 = 0x0E, KeyGeneration_16_0_0 = 0x0F, KeyGeneration_17_0_0 = 0x10, + KeyGeneration_18_0_0 = 0x11, KeyGeneration_Count, diff --git a/libraries/libexosphere/include/exosphere/pkg2.hpp b/libraries/libexosphere/include/exosphere/pkg2.hpp index 81a3f664d..8775d2ed9 100644 --- a/libraries/libexosphere/include/exosphere/pkg2.hpp +++ b/libraries/libexosphere/include/exosphere/pkg2.hpp @@ -24,7 +24,7 @@ namespace ams::pkg2 { constexpr inline int PayloadCount = 3; constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */ - constexpr inline int CurrentBootloaderVersion = 0x14; + constexpr inline int CurrentBootloaderVersion = 0x15; struct Package2Meta { using Magic = util::FourCC<'P','K','2','1'>; diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 95c316d68..772e8ca9c 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,6 +177,7 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { + TargetFirmware_18_0_0, TargetFirmware_17_0_0, TargetFirmware_16_0_0, TargetFirmware_15_0_0, diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 303ff796e..ff8c36898 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -81,6 +81,8 @@ namespace ams::hos { Version_16_0_3 = ::ams::TargetFirmware_16_0_3, Version_16_1_0 = ::ams::TargetFirmware_16_1_0, Version_17_0_0 = ::ams::TargetFirmware_17_0_0, + Version_17_0_1 = ::ams::TargetFirmware_17_0_1, + Version_18_0_0 = ::ams::TargetFirmware_18_0_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp index 2922a2c1c..091b19d3a 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -21,7 +21,7 @@ namespace ams::fs::impl { #define ADD_ENUM_CASE(v) case v: return #v template<> const char *IdString::ToString(pkg1::KeyGeneration id) { - static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_17_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_18_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -40,7 +40,8 @@ namespace ams::fs::impl { case KeyGeneration_14_0_0: return "14.0.0-14.1.2"; case KeyGeneration_15_0_0: return "15.0.0-15.0.1"; case KeyGeneration_16_0_0: return "16.0.0-16.0.3"; - case KeyGeneration_17_0_0: return "17.0.0-"; + case KeyGeneration_17_0_0: return "17.0.0-17.0.1"; + case KeyGeneration_18_0_0: return "18.0.0-"; default: return "Unknown"; } } diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 1808fff84..2319e1895 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -16,11 +16,11 @@ #pragma once #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 -#define ATMOSPHERE_RELEASE_VERSION_MINOR 6 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 2 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 7 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 17 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 18 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 6288ab832..112bbd74f 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -79,8 +79,10 @@ #define ATMOSPHERE_TARGET_FIRMWARE_16_0_3 ATMOSPHERE_TARGET_FIRMWARE(16, 0, 3) #define ATMOSPHERE_TARGET_FIRMWARE_16_1_0 ATMOSPHERE_TARGET_FIRMWARE(16, 1, 0) #define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1) +#define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_17_0_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_0_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -152,6 +154,8 @@ namespace ams { TargetFirmware_16_0_3 = ATMOSPHERE_TARGET_FIRMWARE_16_0_3, TargetFirmware_16_1_0 = ATMOSPHERE_TARGET_FIRMWARE_16_1_0, TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0, + TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1, + TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From cf5895e04f66f3d3f25139768809420ef097ecf9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 00:18:31 -0700 Subject: [PATCH 090/238] kern: use userspace access instructions to read from tlr --- .../source/arch/arm64/svc/kern_svc_handlers_asm.s | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s index 6e6f07a30..a3ee735a2 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_handlers_asm.s @@ -68,7 +68,8 @@ _ZN3ams4kern4arch5arm6412SvcHandler64Ev: /* Check if our disable count allows us to call SVCs. */ mrs x10, tpidrro_el0 - ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)] + add x10, x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT) + ldtrh w10, [x10] cbz w10, 1f /* It might not, so check the stack params to see if we must not allow the SVC. */ @@ -352,7 +353,8 @@ _ZN3ams4kern4arch5arm6412SvcHandler32Ev: /* Check if our disable count allows us to call SVCs. */ mrs x10, tpidrro_el0 - ldrh w10, [x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT)] + add x10, x10, #(THREAD_LOCAL_REGION_DISABLE_COUNT) + ldtrh w10, [x10] cbz w10, 1f /* It might not, so check the stack params to see if we must not allow the SVC. */ From 7562f807fda98c47563650ee8439503c31791629 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 00:24:45 -0700 Subject: [PATCH 091/238] kern: pass kernel base from KernelLdr to Kernel --- .../include/mesosphere/kern_initial_process.hpp | 1 + .../include/mesosphere/kern_k_system_control_base.hpp | 2 +- .../libmesosphere/source/kern_k_system_control_base.cpp | 7 ++++--- .../kernel/source/arch/arm64/init/kern_init_core.cpp | 2 +- mesosphere/kernel_ldr/source/kern_init_loader.cpp | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp index 911298199..a7dfeab71 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_initial_process.hpp @@ -32,6 +32,7 @@ namespace ams::kern { struct InitialProcessBinaryLayout { uintptr_t address; uintptr_t _08; + uintptr_t kern_address; }; struct InitialProcessBinaryLayoutWithSize { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp index 095bff49a..bb1c1ff0f 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp @@ -53,7 +53,7 @@ namespace ams::kern { static size_t GetRealMemorySize(); static size_t GetIntendedMemorySize(); static KPhysicalAddress GetKernelPhysicalBaseAddress(KPhysicalAddress base_address); - static void GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out); + static void GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out, KPhysicalAddress kern_base_address); static bool ShouldIncreaseThreadResourceLimit(); static void TurnOnCpu(u64 core_id, const ams::kern::init::KInitArguments *args); static size_t GetApplicationPoolSize(); diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index 77582203c..6764662d9 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -46,10 +46,11 @@ namespace ams::kern { } } - void KSystemControlBase::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out) { + void KSystemControlBase::Init::GetInitialProcessBinaryLayout(InitialProcessBinaryLayout *out, KPhysicalAddress kern_base_address) { *out = { - .address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax, - ._08 = 0, + .address = GetInteger(KSystemControl::Init::GetKernelPhysicalBaseAddress(ams::kern::MainMemoryAddress)) + KSystemControl::Init::GetIntendedMemorySize() - InitialProcessBinarySizeMax, + ._08 = 0, + .kern_address = GetInteger(kern_base_address), }; } diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index 484a2426c..f74cb050c 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -345,7 +345,7 @@ namespace ams::kern::init { MESOSPHERE_INIT_ABORT_UNLESS(slab_region_size <= resource_region_size); /* Setup the slab region. */ - const KPhysicalAddress code_start_phys_addr = init_pt.GetPhysicalAddressOfRandomizedRange(code_start_virt_addr, code_region_size); + const KPhysicalAddress code_start_phys_addr = g_phase2_initial_process_binary_meta.layout.kern_address; const KPhysicalAddress code_end_phys_addr = code_start_phys_addr + code_region_size; const KPhysicalAddress slab_start_phys_addr = code_end_phys_addr; const KPhysicalAddress slab_end_phys_addr = slab_start_phys_addr + slab_region_size; diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index ce531cf1f..8b991d943 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -195,7 +195,7 @@ namespace ams::kern::init::loader { /* Setup the INI1 header in memory for the kernel. */ { /* Get the kernel layout. */ - KSystemControl::Init::GetInitialProcessBinaryLayout(std::addressof(g_initial_process_binary_meta.layout)); + KSystemControl::Init::GetInitialProcessBinaryLayout(std::addressof(g_initial_process_binary_meta.layout), base_address); /* If there's no desired base address, use the ini in place. */ if (g_initial_process_binary_meta.layout.address == 0) { From 900913fe3b77ff5e740a99a42cdc9a2869ab4bb6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 00:25:48 -0700 Subject: [PATCH 092/238] kern: fix longstanding bug in ConvertToKMemoryPermission --- .../libmesosphere/include/mesosphere/kern_k_memory_block.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index 9d0a97738..f021391e0 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -177,7 +177,7 @@ namespace ams::kern { }; constexpr KMemoryPermission ConvertToKMemoryPermission(ams::svc::MemoryPermission perm) { - return static_cast((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & KMemoryPermission_UserWrite) << KMemoryPermission_KernelShift) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None)); + return static_cast((util::ToUnderlying(perm) & KMemoryPermission_UserMask) | KMemoryPermission_KernelRead | ((util::ToUnderlying(perm) & ams::svc::MemoryPermission_Write) ? KMemoryPermission_KernelWrite : KMemoryPermission_None) | (perm == ams::svc::MemoryPermission_None ? KMemoryPermission_NotMapped : KMemoryPermission_None)); } enum KMemoryAttribute : u8 { From 25bae14064f385230079521bdc3a87b775caf920 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 01:47:36 -0700 Subject: [PATCH 093/238] kern: revise KPageTableBase region layout logic to match 18.0.0 changes --- .../mesosphere/kern_k_page_table_base.hpp | 53 +- .../source/kern_k_page_table_base.cpp | 496 ++++++++++++------ 2 files changed, 363 insertions(+), 186 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 51e4c4075..f53ccfea3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -86,6 +86,15 @@ namespace ams::kern { MemoryFillValue_Heap = 'Z', }; + enum RegionType { + RegionType_KernelMap = 0, + RegionType_Stack = 1, + RegionType_Alias = 2, + RegionType_Heap = 3, + + RegionType_Count, + }; + enum OperationType { OperationType_Map = 0, OperationType_MapGroup = 1, @@ -165,15 +174,9 @@ namespace ams::kern { private: KProcessAddress m_address_space_start; KProcessAddress m_address_space_end; - KProcessAddress m_heap_region_start; - KProcessAddress m_heap_region_end; + KProcessAddress m_region_starts[RegionType_Count]; + KProcessAddress m_region_ends[RegionType_Count]; KProcessAddress m_current_heap_end; - KProcessAddress m_alias_region_start; - KProcessAddress m_alias_region_end; - KProcessAddress m_stack_region_start; - KProcessAddress m_stack_region_end; - KProcessAddress m_kernel_map_region_start; - KProcessAddress m_kernel_map_region_end; KProcessAddress m_alias_code_region_start; KProcessAddress m_alias_code_region_end; KProcessAddress m_code_region_start; @@ -203,10 +206,10 @@ namespace ams::kern { MemoryFillValue m_stack_fill_value; public: constexpr explicit KPageTableBase(util::ConstantInitializeTag) - : m_address_space_start(Null), m_address_space_end(Null), m_heap_region_start(Null), - m_heap_region_end(Null), m_current_heap_end(Null), m_alias_region_start(Null), - m_alias_region_end(Null), m_stack_region_start(Null), m_stack_region_end(Null), - m_kernel_map_region_start(Null), m_kernel_map_region_end(Null), m_alias_code_region_start(Null), + : m_address_space_start(Null), m_address_space_end(Null), + m_region_starts{Null, Null, Null, Null}, + m_region_ends{Null, Null, Null, Null}, + m_current_heap_end(Null), m_alias_code_region_start(Null), m_alias_code_region_end(Null), m_code_region_start(Null), m_code_region_end(Null), m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_general_lock(), m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), @@ -236,7 +239,7 @@ namespace ams::kern { } constexpr bool IsInAliasRegion(KProcessAddress addr, size_t size) const { - return this->Contains(addr, size) && m_alias_region_start <= addr && addr + size - 1 <= m_alias_region_end - 1; + return this->Contains(addr, size) && m_region_starts[RegionType_Alias] <= addr && addr + size - 1 <= m_region_ends[RegionType_Alias] - 1; } bool IsInUnsafeAliasRegion(KProcessAddress addr, size_t size) const { @@ -479,24 +482,28 @@ namespace ams::kern { } public: KProcessAddress GetAddressSpaceStart() const { return m_address_space_start; } - KProcessAddress GetHeapRegionStart() const { return m_heap_region_start; } - KProcessAddress GetAliasRegionStart() const { return m_alias_region_start; } - KProcessAddress GetStackRegionStart() const { return m_stack_region_start; } - KProcessAddress GetKernelMapRegionStart() const { return m_kernel_map_region_start; } + + KProcessAddress GetHeapRegionStart() const { return m_region_starts[RegionType_Heap]; } + KProcessAddress GetAliasRegionStart() const { return m_region_starts[RegionType_Alias]; } + KProcessAddress GetStackRegionStart() const { return m_region_starts[RegionType_Stack]; } + KProcessAddress GetKernelMapRegionStart() const { return m_region_starts[RegionType_KernelMap]; } + KProcessAddress GetAliasCodeRegionStart() const { return m_alias_code_region_start; } - size_t GetAddressSpaceSize() const { return m_address_space_end - m_address_space_start; } - size_t GetHeapRegionSize() const { return m_heap_region_end - m_heap_region_start; } - size_t GetAliasRegionSize() const { return m_alias_region_end - m_alias_region_start; } - size_t GetStackRegionSize() const { return m_stack_region_end - m_stack_region_start; } - size_t GetKernelMapRegionSize() const { return m_kernel_map_region_end - m_kernel_map_region_start; } + size_t GetAddressSpaceSize() const { return m_address_space_end - m_address_space_start; } + + size_t GetHeapRegionSize() const { return m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]; } + size_t GetAliasRegionSize() const { return m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; } + size_t GetStackRegionSize() const { return m_region_ends[RegionType_Stack] - m_region_starts[RegionType_Stack]; } + size_t GetKernelMapRegionSize() const { return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; } + size_t GetAliasCodeRegionSize() const { return m_alias_code_region_end - m_alias_code_region_start; } size_t GetNormalMemorySize() const { /* Lock the table. */ KScopedLightLock lk(m_general_lock); - return (m_current_heap_end - m_heap_region_start) + m_mapped_physical_memory_size; + return (m_current_heap_end - m_region_starts[RegionType_Heap]) + m_mapped_physical_memory_size; } size_t GetCodeSize() const; diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 4ec5834be..647949121 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -97,15 +97,12 @@ namespace ams::kern { m_enable_aslr = true; m_enable_device_address_space_merge = false; - m_heap_region_start = 0; - m_heap_region_end = 0; + for (auto i = 0; i < RegionType_Count; ++i) { + m_region_starts[i] = 0; + m_region_ends[i] = 0; + } + m_current_heap_end = 0; - m_alias_region_start = 0; - m_alias_region_end = 0; - m_stack_region_start = 0; - m_stack_region_end = 0; - m_kernel_map_region_start = 0; - m_kernel_map_region_end = 0; m_alias_code_region_start = 0; m_alias_code_region_end = 0; m_code_region_start = 0; @@ -165,30 +162,44 @@ namespace ams::kern { KProcessAddress process_code_end; size_t stack_region_size; size_t kernel_map_region_size; + KProcessAddress before_process_code_start, after_process_code_start; + size_t before_process_code_size, after_process_code_size; if (m_address_space_width == 39) { - alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); - heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); - stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Stack); - kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); - m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_Map39Bit); - m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_Map39Bit); - m_alias_code_region_start = m_code_region_start; - m_alias_code_region_end = m_code_region_end; - process_code_start = util::AlignDown(GetInteger(code_address), RegionAlignment); - process_code_end = util::AlignUp(GetInteger(code_address) + code_size, RegionAlignment); + stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Stack); + kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); + + m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_Map39Bit); + m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_Map39Bit); + m_alias_code_region_start = m_code_region_start; + m_alias_code_region_end = m_code_region_end; + + process_code_start = util::AlignDown(GetInteger(code_address), RegionAlignment); + process_code_end = util::AlignUp(GetInteger(code_address) + code_size, RegionAlignment); + + before_process_code_start = m_code_region_start; + before_process_code_size = process_code_start - before_process_code_start; + after_process_code_start = process_code_end; + after_process_code_size = m_code_region_end - process_code_end; } else { - stack_region_size = 0; - kernel_map_region_size = 0; - m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_MapSmall); - m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); - m_stack_region_start = m_code_region_start; - m_alias_code_region_start = m_code_region_start; - m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type_MapLarge) + GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); - m_stack_region_end = m_code_region_end; - m_kernel_map_region_start = m_code_region_start; - m_kernel_map_region_end = m_code_region_end; - process_code_start = m_code_region_start; - process_code_end = m_code_region_end; + stack_region_size = 0; + kernel_map_region_size = 0; + + m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type_MapSmall); + m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type_MapSmall); + m_alias_code_region_start = m_code_region_start; + m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type_MapLarge) + GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); + m_region_starts[RegionType_Stack] = m_code_region_start; + m_region_ends[RegionType_Stack] = m_code_region_end; + m_region_starts[RegionType_KernelMap] = m_code_region_start; + m_region_ends[RegionType_KernelMap] = m_code_region_end; + + process_code_start = m_code_region_start; + process_code_end = m_code_region_end; + + before_process_code_start = m_code_region_start; + before_process_code_size = 0; + after_process_code_start = GetSpaceStart(KAddressSpaceInfo::Type_MapLarge); + after_process_code_size = GetSpaceSize(KAddressSpaceInfo::Type_MapLarge); } /* Set other basic fields. */ @@ -201,100 +212,285 @@ namespace ams::kern { m_block_info_manager = system_resource->GetBlockInfoManagerPointer(); m_resource_limit = resource_limit; - /* Determine the region we can place our undetermineds in. */ - KProcessAddress alloc_start; - size_t alloc_size; - if ((GetInteger(process_code_start) - GetInteger(m_code_region_start)) >= (GetInteger(end) - GetInteger(process_code_end))) { - alloc_start = m_code_region_start; - alloc_size = GetInteger(process_code_start) - GetInteger(m_code_region_start); - } else { - alloc_start = process_code_end; - alloc_size = GetInteger(end) - GetInteger(process_code_end); - } - const size_t needed_size = (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size); - R_UNLESS(alloc_size >= needed_size, svc::ResultOutOfMemory()); + /* Set up our undetermined regions. */ + { + /* Declare helper structure for layout process. */ + struct RegionLayoutInfo { + size_t size; + RegionType type; + s32 alloc_index; /* 0 for before process code, 1 for after process code */ + }; - const size_t remaining_size = alloc_size - needed_size; + /* Create region layout info array, and add regions to it. */ + RegionLayoutInfo region_layouts[RegionType_Count] = {}; + size_t num_regions = 0; - /* Determine random placements for each region. */ - size_t alias_rnd = 0, heap_rnd = 0, stack_rnd = 0, kmap_rnd = 0; - if (enable_aslr) { - alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; - heap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; - stack_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; - kmap_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) * RegionAlignment; - } + if (kernel_map_region_size > 0) { region_layouts[num_regions++] = { .size = kernel_map_region_size, .type = RegionType_KernelMap, .alloc_index = 0, }; } + if (stack_region_size > 0) { region_layouts[num_regions++] = { .size = stack_region_size, .type = RegionType_Stack, .alloc_index = 0, }; } - /* Setup heap and alias regions. */ - m_alias_region_start = alloc_start + alias_rnd; - m_alias_region_end = m_alias_region_start + alias_region_size; - m_heap_region_start = alloc_start + heap_rnd; - m_heap_region_end = m_heap_region_start + heap_region_size; + region_layouts[num_regions++] = { .size = alias_region_size, .type = RegionType_Alias, .alloc_index = 0, }; + region_layouts[num_regions++] = { .size = heap_region_size, .type = RegionType_Heap, .alloc_index = 0, }; - if (alias_rnd <= heap_rnd) { - m_heap_region_start += alias_region_size; - m_heap_region_end += alias_region_size; - } else { - m_alias_region_start += heap_region_size; - m_alias_region_end += heap_region_size; - } - - /* Setup stack region. */ - if (stack_region_size) { - m_stack_region_start = alloc_start + stack_rnd; - m_stack_region_end = m_stack_region_start + stack_region_size; - - if (alias_rnd < stack_rnd) { - m_stack_region_start += alias_region_size; - m_stack_region_end += alias_region_size; - } else { - m_alias_region_start += stack_region_size; - m_alias_region_end += stack_region_size; + /* Selection-sort the regions by size largest-to-smallest. */ + for (size_t i = 0; i < num_regions - 1; ++i) { + for (size_t j = i + 1; j < num_regions; ++j) { + if (region_layouts[i].size < region_layouts[j].size) { + std::swap(region_layouts[i], region_layouts[j]); + } + } } - if (heap_rnd < stack_rnd) { - m_stack_region_start += heap_region_size; - m_stack_region_end += heap_region_size; - } else { - m_heap_region_start += stack_region_size; - m_heap_region_end += stack_region_size; - } - } + /* Layout the regions. */ + constexpr auto AllocIndexCount = 2; + KProcessAddress alloc_starts[AllocIndexCount] = { before_process_code_start, after_process_code_start }; + size_t alloc_sizes[AllocIndexCount] = { before_process_code_size, after_process_code_size }; + size_t alloc_counts[AllocIndexCount] = {}; + for (size_t i = 0; i < num_regions; ++i) { + /* Get reference to the current region. */ + auto &cur_region = region_layouts[i]; - /* Setup kernel map region. */ - if (kernel_map_region_size) { - m_kernel_map_region_start = alloc_start + kmap_rnd; - m_kernel_map_region_end = m_kernel_map_region_start + kernel_map_region_size; + /* Determine where the current region should go. */ + cur_region.alloc_index = alloc_sizes[1] >= alloc_sizes[0] ? 1 : 0; + ++alloc_counts[cur_region.alloc_index]; - if (alias_rnd < kmap_rnd) { - m_kernel_map_region_start += alias_region_size; - m_kernel_map_region_end += alias_region_size; - } else { - m_alias_region_start += kernel_map_region_size; - m_alias_region_end += kernel_map_region_size; + /* Check that the current region can fit. */ + R_UNLESS(alloc_sizes[cur_region.alloc_index] >= cur_region.size, svc::ResultOutOfMemory()); + + /* Update our remaining size tracking. */ + alloc_sizes[cur_region.alloc_index] -= cur_region.size; } - if (heap_rnd < kmap_rnd) { - m_kernel_map_region_start += heap_region_size; - m_kernel_map_region_end += heap_region_size; - } else { - m_heap_region_start += kernel_map_region_size; - m_heap_region_end += kernel_map_region_size; + /* Selection sort the regions to coalesce them by alloc index. */ + for (size_t i = 0; i < num_regions - 1; ++i) { + for (size_t j = i + 1; j < num_regions; ++j) { + if (region_layouts[i].alloc_index > region_layouts[j].alloc_index) { + std::swap(region_layouts[i], region_layouts[j]); + } + } } - if (stack_region_size) { - if (stack_rnd < kmap_rnd) { - m_kernel_map_region_start += stack_region_size; - m_kernel_map_region_end += stack_region_size; + /* Layout the regions for each alloc index. */ + for (auto cur_alloc_index = 0; cur_alloc_index < AllocIndexCount; ++cur_alloc_index) { + /* If there are no regions to place, continue. */ + const size_t cur_alloc_count = alloc_counts[cur_alloc_index]; + if (cur_alloc_count == 0) { + continue; + } + + /* Determine the starting region index for the current alloc index. */ + size_t cur_region_index = 0; + for (size_t i = 0; i < num_regions; ++i) { + if (region_layouts[i].alloc_index == cur_alloc_index) { + cur_region_index = i; + break; + } + } + + /* If aslr is enabled, randomize the current region order. Otherwise, sort by type. */ + if (m_enable_aslr) { + for (size_t i = 0; i < cur_alloc_count - 1; ++i) { + std::swap(region_layouts[i], region_layouts[KSystemControl::GenerateRandomRange(i, cur_alloc_count - 1)]); + } } else { - m_stack_region_start += kernel_map_region_size; - m_stack_region_end += kernel_map_region_size; + for (size_t i = 0; i < cur_alloc_count - 1; ++i) { + for (size_t j = i + 1; j < cur_alloc_count; ++j) { + if (region_layouts[cur_region_index + i].type > region_layouts[cur_region_index + j].type) { + std::swap(region_layouts[cur_region_index + i], region_layouts[cur_region_index + j]); + } + } + } + } + + /* Determine aslr offsets for the current space. */ + size_t aslr_offsets[RegionType_Count] = {}; + if (m_enable_aslr) { + /* Generate the aslr offsets. */ + for (size_t i = 0; i < cur_alloc_count; ++i) { + aslr_offsets[i] = KSystemControl::GenerateRandomRange(0, alloc_sizes[cur_alloc_index] / RegionAlignment) * RegionAlignment; + } + + /* Sort the aslr offsets. */ + for (size_t i = 0; i < cur_alloc_count - 1; ++i) { + for (size_t j = i + 1; j < cur_alloc_count; ++j) { + if (aslr_offsets[i] > aslr_offsets[j]) { + std::swap(aslr_offsets[i], aslr_offsets[j]); + } + } + } + } + + /* Calculate final region positions. */ + KProcessAddress prev_region_end = alloc_starts[cur_alloc_index]; + size_t prev_aslr_offset = 0; + for (size_t i = 0; i < cur_alloc_count; ++i) { + /* Get the current region. */ + auto &cur_region = region_layouts[cur_region_index + i]; + + /* Set the current region start/end. */ + m_region_starts[cur_region.type] = (aslr_offsets[i] - prev_aslr_offset) + GetInteger(prev_region_end); + m_region_ends[cur_region.type] = m_region_starts[cur_region.type] + cur_region.size; + + /* Update tracking variables. */ + prev_region_end = m_region_ends[cur_region.type]; + prev_aslr_offset = aslr_offsets[i]; + } + } + + /* Declare helpers to check that regions are inside our address space. */ + const KProcessAddress process_code_last = process_code_end - 1; + auto IsInAddressSpace = [&](KProcessAddress addr) ALWAYS_INLINE_LAMBDA { return m_address_space_start <= addr && addr <= m_address_space_end; }; + + /* Ensure that the KernelMap region is valid. */ + for (size_t k = 0; k < num_regions; ++k) { + if (const auto &kmap_region = region_layouts[k]; kmap_region.type == RegionType_KernelMap) { + /* If there's no kmap region, we have nothing to check. */ + if (kmap_region.size == 0) { + break; + } + + /* Check that the kmap region is within our address space. */ + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_KernelMap])); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_KernelMap])); + + /* Check for overlap with process code. */ + const KProcessAddress kmap_start = m_region_starts[RegionType_KernelMap]; + const KProcessAddress kmap_last = m_region_ends[RegionType_KernelMap] - 1; + MESOSPHERE_ABORT_UNLESS(kernel_map_region_size == 0 || kmap_last < process_code_start || process_code_last < kmap_start); + + /* Check for overlap with stack. */ + for (size_t s = 0; s < num_regions; ++s) { + if (const auto &stack_region = region_layouts[s]; stack_region.type == RegionType_Stack) { + if (stack_region.size != 0) { + const KProcessAddress stack_start = m_region_starts[RegionType_Stack]; + const KProcessAddress stack_last = m_region_ends[RegionType_Stack] - 1; + MESOSPHERE_ABORT_UNLESS((kernel_map_region_size == 0 && stack_region_size == 0) || kmap_last < stack_start || stack_last < kmap_start); + } + break; + } + } + + /* Check for overlap with alias. */ + for (size_t a = 0; a < num_regions; ++a) { + if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { + if (alias_region.size != 0) { + const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; + const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; + MESOSPHERE_ABORT_UNLESS(kmap_last < alias_start || alias_last < kmap_start); + } + break; + } + } + + /* Check for overlap with heap. */ + for (size_t h = 0; h < num_regions; ++h) { + if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { + if (heap_region.size != 0) { + const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; + const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; + MESOSPHERE_ABORT_UNLESS(kmap_last < heap_start || heap_last < kmap_start); + } + break; + } + } + } + } + + /* Check that the Stack region is valid. */ + for (size_t s = 0; s < num_regions; ++s) { + if (const auto &stack_region = region_layouts[s]; stack_region.type == RegionType_Stack) { + /* If there's no stack region, we have nothing to check. */ + if (stack_region.size == 0) { + break; + } + + /* Check that the stack region is within our address space. */ + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Stack])); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Stack])); + + /* Check for overlap with process code. */ + const KProcessAddress stack_start = m_region_starts[RegionType_Stack]; + const KProcessAddress stack_last = m_region_ends[RegionType_Stack] - 1; + MESOSPHERE_ABORT_UNLESS(stack_region_size == 0 || stack_last < process_code_start || process_code_last < stack_start); + + /* Check for overlap with alias. */ + for (size_t a = 0; a < num_regions; ++a) { + if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { + if (alias_region.size != 0) { + const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; + const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; + MESOSPHERE_ABORT_UNLESS(stack_last < alias_start || alias_last < stack_start); + } + break; + } + } + + /* Check for overlap with heap. */ + for (size_t h = 0; h < num_regions; ++h) { + if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { + if (heap_region.size != 0) { + const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; + const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; + MESOSPHERE_ABORT_UNLESS(stack_last < heap_start || heap_last < stack_start); + } + break; + } + } + } + } + + /* Check that the Alias region is valid. */ + for (size_t a = 0; a < num_regions; ++a) { + if (const auto &alias_region = region_layouts[a]; alias_region.type == RegionType_Alias) { + /* If there's no alias region, we have nothing to check. */ + if (alias_region.size == 0) { + break; + } + + /* Check that the alias region is within our address space. */ + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Alias])); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Alias])); + + /* Check for overlap with process code. */ + const KProcessAddress alias_start = m_region_starts[RegionType_Alias]; + const KProcessAddress alias_last = m_region_ends[RegionType_Alias] - 1; + MESOSPHERE_ABORT_UNLESS(alias_last < process_code_start || process_code_last < alias_start); + + /* Check for overlap with heap. */ + for (size_t h = 0; h < num_regions; ++h) { + if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { + if (heap_region.size != 0) { + const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; + const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; + MESOSPHERE_ABORT_UNLESS(alias_last < heap_start || heap_last < alias_start); + } + break; + } + } + } + } + + /* Check that the Heap region is valid. */ + for (size_t h = 0; h < num_regions; ++h) { + if (const auto &heap_region = region_layouts[h]; heap_region.type == RegionType_Heap) { + /* If there's no heap region, we have nothing to check. */ + if (heap_region.size == 0) { + break; + } + + /* Check that the heap region is within our address space. */ + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_starts[RegionType_Heap])); + MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_region_ends[RegionType_Heap])); + + /* Check for overlap with process code. */ + const KProcessAddress heap_start = m_region_starts[RegionType_Heap]; + const KProcessAddress heap_last = m_region_ends[RegionType_Heap] - 1; + MESOSPHERE_ABORT_UNLESS(heap_last < process_code_start || process_code_last < heap_start); } } } /* Set heap and fill members. */ - m_current_heap_end = m_heap_region_start; + m_current_heap_end = m_region_starts[RegionType_Heap]; m_max_heap_size = 0; m_mapped_physical_memory_size = 0; m_mapped_unsafe_physical_memory = 0; @@ -309,32 +505,6 @@ namespace ams::kern { /* Set allocation option. */ m_allocate_option = KMemoryManager::EncodeOption(pool, from_back ? KMemoryManager::Direction_FromBack : KMemoryManager::Direction_FromFront); - /* Ensure that we regions inside our address space. */ - auto IsInAddressSpace = [&](KProcessAddress addr) ALWAYS_INLINE_LAMBDA { return m_address_space_start <= addr && addr <= m_address_space_end; }; - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_alias_region_start)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_alias_region_end)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_heap_region_start)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_heap_region_end)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_stack_region_start)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_stack_region_end)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_kernel_map_region_start)); - MESOSPHERE_ABORT_UNLESS(IsInAddressSpace(m_kernel_map_region_end)); - - /* Ensure that we selected regions that don't overlap. */ - const KProcessAddress alias_start = m_alias_region_start; - const KProcessAddress alias_last = m_alias_region_end - 1; - const KProcessAddress heap_start = m_heap_region_start; - const KProcessAddress heap_last = m_heap_region_end - 1; - const KProcessAddress stack_start = m_stack_region_start; - const KProcessAddress stack_last = m_stack_region_end - 1; - const KProcessAddress kmap_start = m_kernel_map_region_start; - const KProcessAddress kmap_last = m_kernel_map_region_end - 1; - MESOSPHERE_ABORT_UNLESS(alias_last < heap_start || heap_last < alias_start); - MESOSPHERE_ABORT_UNLESS(alias_last < stack_start || stack_last < alias_start); - MESOSPHERE_ABORT_UNLESS(alias_last < kmap_start || kmap_last < alias_start); - MESOSPHERE_ABORT_UNLESS(heap_last < stack_start || stack_last < heap_start); - MESOSPHERE_ABORT_UNLESS(heap_last < kmap_start || kmap_last < heap_start); - /* Initialize our implementation. */ m_impl.InitializeForProcess(table, GetInteger(start), GetInteger(end)); @@ -374,16 +544,16 @@ namespace ams::kern { case ams::svc::MemoryState_Kernel: return m_address_space_start; case ams::svc::MemoryState_Normal: - return m_heap_region_start; + return m_region_starts[RegionType_Heap]; case ams::svc::MemoryState_Ipc: case ams::svc::MemoryState_NonSecureIpc: case ams::svc::MemoryState_NonDeviceIpc: - return m_alias_region_start; + return m_region_starts[RegionType_Alias]; case ams::svc::MemoryState_Stack: - return m_stack_region_start; + return m_region_starts[RegionType_Stack]; case ams::svc::MemoryState_Static: case ams::svc::MemoryState_ThreadLocal: - return m_kernel_map_region_start; + return m_region_starts[RegionType_KernelMap]; case ams::svc::MemoryState_Io: case ams::svc::MemoryState_Shared: case ams::svc::MemoryState_AliasCode: @@ -409,16 +579,16 @@ namespace ams::kern { case ams::svc::MemoryState_Kernel: return m_address_space_end - m_address_space_start; case ams::svc::MemoryState_Normal: - return m_heap_region_end - m_heap_region_start; + return m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]; case ams::svc::MemoryState_Ipc: case ams::svc::MemoryState_NonSecureIpc: case ams::svc::MemoryState_NonDeviceIpc: - return m_alias_region_end - m_alias_region_start; + return m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; case ams::svc::MemoryState_Stack: - return m_stack_region_end - m_stack_region_start; + return m_region_ends[RegionType_Stack] - m_region_starts[RegionType_Stack]; case ams::svc::MemoryState_Static: case ams::svc::MemoryState_ThreadLocal: - return m_kernel_map_region_end - m_kernel_map_region_start; + return m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; case ams::svc::MemoryState_Io: case ams::svc::MemoryState_Shared: case ams::svc::MemoryState_AliasCode: @@ -446,8 +616,8 @@ namespace ams::kern { const size_t region_size = this->GetRegionSize(state); const bool is_in_region = region_start <= addr && addr < end && last <= region_start + region_size - 1; - const bool is_in_heap = !(end <= m_heap_region_start || m_heap_region_end <= addr || m_heap_region_start == m_heap_region_end); - const bool is_in_alias = !(end <= m_alias_region_start || m_alias_region_end <= addr || m_alias_region_start == m_alias_region_end); + const bool is_in_heap = !(end <= m_region_starts[RegionType_Heap] || m_region_ends[RegionType_Heap] <= addr || m_region_starts[RegionType_Heap] == m_region_ends[RegionType_Heap]); + const bool is_in_alias = !(end <= m_region_starts[RegionType_Alias] || m_region_ends[RegionType_Alias] <= addr || m_region_starts[RegionType_Alias] == m_region_ends[RegionType_Alias]); switch (state) { case ams::svc::MemoryState_Free: case ams::svc::MemoryState_Kernel: @@ -1692,17 +1862,17 @@ namespace ams::kern { KScopedLightLock lk(m_general_lock); /* Validate that setting heap size is possible at all. */ - R_UNLESS(!m_is_kernel, svc::ResultOutOfMemory()); - R_UNLESS(size <= static_cast(m_heap_region_end - m_heap_region_start), svc::ResultOutOfMemory()); - R_UNLESS(size <= m_max_heap_size, svc::ResultOutOfMemory()); + R_UNLESS(!m_is_kernel, svc::ResultOutOfMemory()); + R_UNLESS(size <= static_cast(m_region_ends[RegionType_Heap] - m_region_starts[RegionType_Heap]), svc::ResultOutOfMemory()); + R_UNLESS(size <= m_max_heap_size, svc::ResultOutOfMemory()); - if (size < static_cast(m_current_heap_end - m_heap_region_start)) { + if (size < static_cast(m_current_heap_end - m_region_starts[RegionType_Heap])) { /* The size being requested is less than the current size, so we need to free the end of the heap. */ /* Validate memory state. */ size_t num_allocator_blocks; R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), - m_heap_region_start + size, (m_current_heap_end - m_heap_region_start) - size, + m_region_starts[RegionType_Heap] + size, (m_current_heap_end - m_region_starts[RegionType_Heap]) - size, KMemoryState_All, KMemoryState_Normal, KMemoryPermission_All, KMemoryPermission_UserReadWrite, KMemoryAttribute_All, KMemoryAttribute_None)); @@ -1716,30 +1886,30 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Unmap the end of the heap. */ - const size_t num_pages = ((m_current_heap_end - m_heap_region_start) - size) / PageSize; + const size_t num_pages = ((m_current_heap_end - m_region_starts[RegionType_Heap]) - size) / PageSize; const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; - R_TRY(this->Operate(updater.GetPageList(), m_heap_region_start + size, num_pages, Null, false, unmap_properties, OperationType_Unmap, false)); + R_TRY(this->Operate(updater.GetPageList(), m_region_starts[RegionType_Heap] + size, num_pages, Null, false, unmap_properties, OperationType_Unmap, false)); /* Release the memory from the resource limit. */ m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, num_pages * PageSize); /* Apply the memory block update. */ - m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, size == 0 ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), m_region_starts[RegionType_Heap] + size, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, size == 0 ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None); /* Update the current heap end. */ - m_current_heap_end = m_heap_region_start + size; + m_current_heap_end = m_region_starts[RegionType_Heap] + size; /* Set the output. */ - *out = m_heap_region_start; + *out = m_region_starts[RegionType_Heap]; R_SUCCEED(); - } else if (size == static_cast(m_current_heap_end - m_heap_region_start)) { + } else if (size == static_cast(m_current_heap_end - m_region_starts[RegionType_Heap])) { /* The size requested is exactly the current size. */ - *out = m_heap_region_start; + *out = m_region_starts[RegionType_Heap]; R_SUCCEED(); } else { /* We have to allocate memory. Determine how much to allocate and where while the table is locked. */ cur_address = m_current_heap_end; - allocation_size = size - (m_current_heap_end - m_heap_region_start); + allocation_size = size - (m_current_heap_end - m_region_starts[RegionType_Heap]); } } @@ -1782,20 +1952,20 @@ namespace ams::kern { /* Map the pages. */ const size_t num_pages = allocation_size / PageSize; - const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, (m_current_heap_end == m_heap_region_start) ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; + const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, (m_current_heap_end == m_region_starts[RegionType_Heap]) ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; R_TRY(this->Operate(updater.GetPageList(), m_current_heap_end, num_pages, pg, map_properties, OperationType_MapGroup, false)); /* We succeeded, so commit our memory reservation. */ memory_reservation.Commit(); /* Apply the memory block update. */ - m_memory_block_manager.Update(std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, m_heap_region_start == m_current_heap_end ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); + m_memory_block_manager.Update(std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState_Normal, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, m_region_starts[RegionType_Heap] == m_current_heap_end ? KMemoryBlockDisableMergeAttribute_Normal : KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); /* Update the current heap end. */ - m_current_heap_end = m_heap_region_start + size; + m_current_heap_end = m_region_starts[RegionType_Heap] + size; /* Set the output. */ - *out = m_heap_region_start; + *out = m_region_starts[RegionType_Heap]; R_SUCCEED(); } } @@ -1927,8 +2097,8 @@ namespace ams::kern { const KPhysicalAddress last = phys_addr + size - 1; /* Get region extents. */ - const KProcessAddress region_start = m_kernel_map_region_start; - const size_t region_size = m_kernel_map_region_end - m_kernel_map_region_start; + const KProcessAddress region_start = m_region_starts[RegionType_KernelMap]; + const size_t region_size = m_region_ends[RegionType_KernelMap] - m_region_starts[RegionType_KernelMap]; const size_t region_num_pages = region_size / PageSize; MESOSPHERE_ASSERT(this->CanContain(region_start, region_size, state)); @@ -3720,8 +3890,8 @@ namespace ams::kern { MESOSPHERE_ASSERT(src_page_table.IsLockedByCurrentThread()); /* Check that we can theoretically map. */ - const KProcessAddress region_start = m_alias_region_start; - const size_t region_size = m_alias_region_end - m_alias_region_start; + const KProcessAddress region_start = m_region_starts[RegionType_Alias]; + const size_t region_size = m_region_ends[RegionType_Alias] - m_region_starts[RegionType_Alias]; R_UNLESS(size < region_size, svc::ResultOutOfAddressSpace()); /* Get aligned source extents. */ From 8aa62a54d866ad69f26926144843732f87d8a70a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:07:04 -0700 Subject: [PATCH 094/238] kern/os: support CreateProcessFlag_EnableAliasRegionExtraSize --- .../arch/arm64/kern_k_page_table.hpp | 2 +- .../arch/arm64/kern_k_process_page_table.hpp | 6 +++-- .../mesosphere/kern_k_page_table_base.hpp | 7 ++++-- .../source/arch/arm64/kern_k_page_table.cpp | 6 ++--- .../source/kern_k_page_table_base.cpp | 22 ++++++++++++++----- .../libmesosphere/source/kern_k_process.cpp | 12 ++++------ .../source/svc/kern_svc_info.cpp | 4 ++++ .../source/svc/kern_svc_process.cpp | 12 ++++++++++ .../impl/os_vamm_manager_impl.os.horizon.hpp | 9 ++++---- .../include/vapours/svc/svc_types_common.hpp | 21 +++++++++++------- 10 files changed, 68 insertions(+), 33 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index f8ab5e680..14aba9913 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -178,7 +178,7 @@ namespace ams::kern::arch::arm64 { } NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); Result Finalize(); private: Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 7209dbfa1..640b9e5e5 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -28,8 +28,8 @@ namespace ams::kern::arch::arm64 { m_page_table.Activate(id); } - Result Initialize(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - R_RETURN(m_page_table.InitializeForProcess(as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size, system_resource, resource_limit)); + Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit)); } void Finalize() { m_page_table.Finalize(); } @@ -316,6 +316,8 @@ namespace ams::kern::arch::arm64 { size_t GetKernelMapRegionSize() const { return m_page_table.GetKernelMapRegionSize(); } size_t GetAliasCodeRegionSize() const { return m_page_table.GetAliasCodeRegionSize(); } + size_t GetAliasRegionExtraSize() const { return m_page_table.GetAliasRegionExtraSize(); } + size_t GetNormalMemorySize() const { return m_page_table.GetNormalMemorySize(); } size_t GetCodeSize() const { return m_page_table.GetCodeSize(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index f53ccfea3..bc5623163 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -186,6 +186,7 @@ namespace ams::kern { size_t m_mapped_unsafe_physical_memory; size_t m_mapped_insecure_memory; size_t m_mapped_ipc_server_memory; + size_t m_alias_region_extra_size; mutable KLightLock m_general_lock; mutable KLightLock m_map_physical_memory_lock; KLightLock m_device_map_lock; @@ -211,7 +212,7 @@ namespace ams::kern { m_region_ends{Null, Null, Null, Null}, m_current_heap_end(Null), m_alias_code_region_start(Null), m_alias_code_region_end(Null), m_code_region_start(Null), m_code_region_end(Null), - m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), + m_max_heap_size(), m_mapped_physical_memory_size(), m_mapped_unsafe_physical_memory(), m_mapped_insecure_memory(), m_mapped_ipc_server_memory(), m_alias_region_extra_size(), m_general_lock(), m_map_physical_memory_lock(), m_device_map_lock(), m_impl(util::ConstantInitialize), m_memory_block_manager(util::ConstantInitialize), m_allocate_option(), m_address_space_width(), m_is_kernel(), m_enable_aslr(), m_enable_device_address_space_merge(), m_memory_block_slab_manager(), m_block_info_manager(), m_resource_limit(), m_cached_physical_linear_region(), m_cached_physical_heap_region(), @@ -223,7 +224,7 @@ namespace ams::kern { explicit KPageTableBase() { /* ... */ } NOINLINE Result InitializeForKernel(bool is_64_bit, void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_device_address_space_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); void Finalize(); @@ -499,6 +500,8 @@ namespace ams::kern { size_t GetAliasCodeRegionSize() const { return m_alias_code_region_end - m_alias_code_region_start; } + size_t GetAliasRegionExtraSize() const { return m_alias_region_extra_size; } + size_t GetNormalMemorySize() const { /* Lock the table. */ KScopedLightLock lk(m_general_lock); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 8ad4a5dd4..0558b5b34 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -207,7 +207,7 @@ namespace ams::kern::arch::arm64 { R_SUCCEED(); } - Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { /* Get an ASID */ m_asid = g_asid_manager.Reserve(); ON_RESULT_FAILURE { g_asid_manager.Release(m_asid); }; @@ -222,10 +222,10 @@ namespace ams::kern::arch::arm64 { ON_RESULT_FAILURE_2 { m_manager->Free(new_table); }; /* Initialize our base table. */ - const size_t as_width = GetAddressSpaceWidth(as_type); + const size_t as_width = GetAddressSpaceWidth(flags); const KProcessAddress as_start = 0; const KProcessAddress as_end = (1ul << as_width); - R_TRY(KPageTableBase::InitializeForProcess(as_type, enable_aslr, enable_das_merge, from_back, pool, GetVoidPointer(new_table), as_start, as_end, code_address, code_size, system_resource, resource_limit)); + R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(new_table), as_start, as_end, code_address, code_size, system_resource, resource_limit)); /* Note that we've updated the table (since we created it). */ this->NoteUpdated(); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 647949121..d58ceb717 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -112,6 +112,7 @@ namespace ams::kern { m_mapped_unsafe_physical_memory = 0; m_mapped_insecure_memory = 0; m_mapped_ipc_server_memory = 0; + m_alias_region_extra_size = 0; m_memory_block_slab_manager = Kernel::GetSystemSystemResource().GetMemoryBlockSlabManagerPointer(); m_block_info_manager = Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer(); @@ -132,7 +133,7 @@ namespace ams::kern { R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end, m_memory_block_slab_manager)); } - Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { + Result KPageTableBase::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, void *table, KProcessAddress start, KProcessAddress end, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { /* Validate the region. */ MESOSPHERE_ABORT_UNLESS(start <= code_address); MESOSPHERE_ABORT_UNLESS(code_address < code_address + code_size); @@ -146,13 +147,16 @@ namespace ams::kern { return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); }; + /* Default to zero alias region extra size. */ + m_alias_region_extra_size = 0; + /* Set our width and heap/alias sizes. */ - m_address_space_width = GetAddressSpaceWidth(as_type); + m_address_space_width = GetAddressSpaceWidth(flags); size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); /* Adjust heap/alias size if we don't have an alias region. */ - if ((as_type & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { + if ((flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { heap_region_size += alias_region_size; alias_region_size = 0; } @@ -180,6 +184,14 @@ namespace ams::kern { before_process_code_size = process_code_start - before_process_code_start; after_process_code_start = process_code_end; after_process_code_size = m_code_region_end - process_code_end; + + /* If we have a 39-bit address space and should, enable extra size to the alias region. */ + if (flags & ams::svc::CreateProcessFlag_EnableAliasRegionExtraSize) { + /* Extra size is 1/8th of the address space. */ + m_alias_region_extra_size = (static_cast(1) << m_address_space_width) / 8; + + alias_region_size += m_alias_region_extra_size; + } } else { stack_region_size = 0; kernel_map_region_size = 0; @@ -203,8 +215,8 @@ namespace ams::kern { } /* Set other basic fields. */ - m_enable_aslr = enable_aslr; - m_enable_device_address_space_merge = enable_das_merge; + m_enable_aslr = (flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; + m_enable_device_address_space_merge = (flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; m_address_space_start = start; m_address_space_end = end; m_is_kernel = false; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index a82d94bec..789bdbc09 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -298,10 +298,8 @@ namespace ams::kern { /* Setup page table. */ { - const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); - const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; - const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; - R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); + const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -379,10 +377,8 @@ namespace ams::kern { /* Setup page table. */ { - const auto as_type = static_cast(params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask); - const bool enable_aslr = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) != 0; - const bool enable_das_merge = (params.flags & ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge) == 0; - R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, params.code_address, code_size, m_system_resource, res_limit)); + const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit)); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; diff --git a/libraries/libmesosphere/source/svc/kern_svc_info.cpp b/libraries/libmesosphere/source/svc/kern_svc_info.cpp index 3c107b590..e9153edbb 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -106,6 +106,9 @@ namespace ams::kern::svc { *out = 0; } break; + case ams::svc::InfoType_AliasRegionExtraSize: + *out = process->GetPageTable().GetAliasRegionExtraSize(); + break; MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } @@ -134,6 +137,7 @@ namespace ams::kern::svc { case ams::svc::InfoType_UsedNonSystemMemorySize: case ams::svc::InfoType_IsApplication: case ams::svc::InfoType_FreeThreadCount: + case ams::svc::InfoType_AliasRegionExtraSize: { /* These info types don't support non-zero subtypes. */ R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index e73e5829c..76e36302b 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -162,6 +162,18 @@ namespace ams::kern::svc { /* Check that the number of extra resource pages is >= 0. */ R_UNLESS(params.system_resource_num_pages >= 0, svc::ResultInvalidSize()); + /* Validate that the alias region extra size is allowed, if enabled. */ + if (params.flags & ams::svc::CreateProcessFlag_EnableAliasRegionExtraSize) { + /* Check that we have a 64-bit address space. */ + R_UNLESS((params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace64Bit, svc::ResultInvalidState()); + + /* Check that the system resource page count is non-zero. */ + R_UNLESS(params.system_resource_num_pages > 0, svc::ResultInvalidState()); + + /* Check that debug mode is enabled. */ + R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultInvalidState()); + } + /* Convert to sizes. */ const size_t code_num_pages = params.code_num_pages; const size_t system_resource_num_pages = params.system_resource_num_pages; diff --git a/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp b/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp index dad8aee6f..fb1519f88 100644 --- a/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp +++ b/libraries/libstratosphere/source/os/impl/os_vamm_manager_impl.os.horizon.hpp @@ -21,11 +21,12 @@ namespace ams::os::impl { class VammManagerHorizonImpl { public: static void GetReservedRegionImpl(uintptr_t *out_start, uintptr_t *out_size) { - u64 start, size; - R_ABORT_UNLESS(svc::GetInfo(std::addressof(start), svc::InfoType_AliasRegionAddress, svc::PseudoHandle::CurrentProcess, 0)); - R_ABORT_UNLESS(svc::GetInfo(std::addressof(size), svc::InfoType_AliasRegionSize, svc::PseudoHandle::CurrentProcess, 0)); + u64 start, size, extra_size; + R_ABORT_UNLESS(svc::GetInfo(std::addressof(start), svc::InfoType_AliasRegionAddress, svc::PseudoHandle::CurrentProcess, 0)); + R_ABORT_UNLESS(svc::GetInfo(std::addressof(size), svc::InfoType_AliasRegionSize, svc::PseudoHandle::CurrentProcess, 0)); + R_ABORT_UNLESS(svc::GetInfo(std::addressof(extra_size), svc::InfoType_AliasRegionExtraSize, svc::PseudoHandle::CurrentProcess, 0)); *out_start = start; - *out_size = size; + *out_size = size - extra_size; } static Result AllocatePhysicalMemoryImpl(uintptr_t address, size_t size) { diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index f71d2c486..5668cd2dd 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -190,6 +190,7 @@ namespace ams::svc { InfoType_ThreadTickCount = 25, InfoType_IsSvcPermitted = 26, InfoType_IoRegionHint = 27, + InfoType_AliasRegionExtraSize = 28, InfoType_MesosphereMeta = 65000, InfoType_MesosphereCurrentProcess = 65001, @@ -436,15 +437,19 @@ namespace ams::svc { /* 11.x+ DisableDeviceAddressSpaceMerge. */ CreateProcessFlag_DisableDeviceAddressSpaceMerge = (1 << 12), + /* 18.x EnableAliasRegionExtraSize. */ + CreateProcessFlag_EnableAliasRegionExtraSize = (1 << 13), + /* Mask of all flags. */ - CreateProcessFlag_All = CreateProcessFlag_Is64Bit | - CreateProcessFlag_AddressSpaceMask | - CreateProcessFlag_EnableDebug | - CreateProcessFlag_EnableAslr | - CreateProcessFlag_IsApplication | - CreateProcessFlag_PoolPartitionMask | - CreateProcessFlag_OptimizeMemoryAllocation | - CreateProcessFlag_DisableDeviceAddressSpaceMerge, + CreateProcessFlag_All = CreateProcessFlag_Is64Bit | + CreateProcessFlag_AddressSpaceMask | + CreateProcessFlag_EnableDebug | + CreateProcessFlag_EnableAslr | + CreateProcessFlag_IsApplication | + CreateProcessFlag_PoolPartitionMask | + CreateProcessFlag_OptimizeMemoryAllocation | + CreateProcessFlag_DisableDeviceAddressSpaceMerge | + CreateProcessFlag_EnableAliasRegionExtraSize, }; /* Debug types. */ From 217dd1260a92a2ee8c20b1ca8f491ddc0746801f Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:17:38 -0700 Subject: [PATCH 095/238] kern: take alignment argument in KMemoryManager::AllocateAndOpen --- .../include/mesosphere/kern_k_memory_manager.hpp | 4 ++-- .../source/kern_initial_process.cpp | 4 ++-- .../source/kern_k_memory_manager.cpp | 16 +++++++++++----- .../source/kern_k_page_table_base.cpp | 8 ++++---- .../source/kern_k_shared_memory.cpp | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index ca23119bc..bd596dfd0 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -185,7 +185,7 @@ namespace ams::kern { } } - Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random); + Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index); public: KMemoryManager() : m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process() @@ -199,7 +199,7 @@ namespace ams::kern { NOINLINE void FinalizeOptimizedMemory(u64 process_id, Pool pool); NOINLINE KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); - NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option); + NOINLINE Result AllocateAndOpen(KPageGroup *out, size_t num_pages, size_t align_pages, u32 option); NOINLINE Result AllocateForProcess(KPageGroup *out, size_t num_pages, u32 option, u64 process_id, u8 fill_pattern); Pool GetPool(KPhysicalAddress address) const { diff --git a/libraries/libmesosphere/source/kern_initial_process.cpp b/libraries/libmesosphere/source/kern_initial_process.cpp index 282bba103..ab38d5774 100644 --- a/libraries/libmesosphere/source/kern_initial_process.cpp +++ b/libraries/libmesosphere/source/kern_initial_process.cpp @@ -136,7 +136,7 @@ namespace ams::kern { { /* Allocate the previously unreserved pages. */ KPageGroup unreserve_pg(Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer()); - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(unreserve_pg), unreserved_size / PageSize, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(unreserve_pg), unreserved_size / PageSize, 1, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); /* Add the previously reserved pages. */ if (src_pool == dst_pool && binary_pages != 0) { @@ -173,7 +173,7 @@ namespace ams::kern { /* If the pool is the same, we need to use the workaround page group. */ if (src_pool == dst_pool) { /* Allocate a new, usable group for the process. */ - MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(workaround_pg), static_cast(params.code_num_pages), KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); + MESOSPHERE_R_ABORT_UNLESS(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(workaround_pg), static_cast(params.code_num_pages), 1, KMemoryManager::EncodeOption(dst_pool, KMemoryManager::Direction_FromFront))); /* Copy data from the working page group to the usable one. */ auto work_it = pg.begin(); diff --git a/libraries/libmesosphere/source/kern_k_memory_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_manager.cpp index 01dcd565a..fa533387c 100644 --- a/libraries/libmesosphere/source/kern_k_memory_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_manager.cpp @@ -225,7 +225,7 @@ namespace ams::kern { return allocated_block; } - Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random) { + Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index) { /* Choose a heap based on our page size request. */ const s32 heap_index = KPageHeap::GetBlockIndex(num_pages); R_UNLESS(0 <= heap_index, svc::ResultOutOfMemory()); @@ -241,7 +241,7 @@ namespace ams::kern { }; /* Keep allocating until we've allocated all our pages. */ - for (s32 index = heap_index; index >= 0 && num_pages > 0; index--) { + for (s32 index = heap_index; index >= min_heap_index && num_pages > 0; index--) { const size_t pages_per_alloc = KPageHeap::GetBlockNumPages(index); for (Impl *cur_manager = this->GetFirstManager(pool, dir); cur_manager != nullptr; cur_manager = this->GetNextManager(cur_manager, dir)) { while (num_pages >= pages_per_alloc) { @@ -274,7 +274,7 @@ namespace ams::kern { R_SUCCEED(); } - Result KMemoryManager::AllocateAndOpen(KPageGroup *out, size_t num_pages, u32 option) { + Result KMemoryManager::AllocateAndOpen(KPageGroup *out, size_t num_pages, size_t align_pages, u32 option) { MESOSPHERE_ASSERT(out != nullptr); MESOSPHERE_ASSERT(out->GetNumPages() == 0); @@ -285,8 +285,11 @@ namespace ams::kern { const auto [pool, dir] = DecodeOption(option); KScopedLightLock lk(m_pool_locks[pool]); + /* Choose a heap based on our alignment size request. */ + const s32 heap_index = KPageHeap::GetAlignedBlockIndex(align_pages, align_pages); + /* Allocate the page group. */ - R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, m_has_optimized_process[pool], true)); + R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, m_has_optimized_process[pool], true, heap_index)); /* Open the first reference to the pages. */ for (const auto &block : *out) { @@ -326,8 +329,11 @@ namespace ams::kern { const bool has_optimized = m_has_optimized_process[pool]; const bool is_optimized = m_optimized_process_ids[pool] == process_id; + /* Always use the minimum alignment size. */ + const s32 heap_index = 0; + /* Allocate the page group. */ - R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, has_optimized && !is_optimized, false)); + R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, has_optimized && !is_optimized, false, heap_index)); /* Set whether we should optimize. */ optimized = has_optimized && is_optimized; diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index d58ceb717..136c92333 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1266,7 +1266,7 @@ namespace ams::kern { /* Allocate pages for the insecure memory. */ KPageGroup pg(m_block_info_manager); - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), size / PageSize, KMemoryManager::EncodeOption(insecure_pool, KMemoryManager::Direction_FromFront))); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), size / PageSize, 1, KMemoryManager::EncodeOption(insecure_pool, KMemoryManager::Direction_FromFront))); /* Close the opened pages when we're done with them. */ /* If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed automatically. */ @@ -1426,7 +1426,7 @@ namespace ams::kern { KPageGroup pg(m_block_info_manager); /* Allocate the pages. */ - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, m_allocate_option)); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, 1, m_allocate_option)); /* Ensure that the page group is closed when we're done working with it. */ ON_SCOPE_EXIT { pg.Close(); }; @@ -1931,7 +1931,7 @@ namespace ams::kern { /* Allocate pages for the heap extension. */ KPageGroup pg(m_block_info_manager); - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), allocation_size / PageSize, m_allocate_option)); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), allocation_size / PageSize, 1, m_allocate_option)); /* Close the opened pages when we're done with them. */ /* If the mapping succeeds, each page will gain an extra reference, otherwise they will be freed automatically. */ @@ -4844,7 +4844,7 @@ namespace ams::kern { /* Allocate the new memory. */ const size_t num_pages = size / PageSize; - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, KMemoryManager::EncodeOption(KMemoryManager::Pool_Unsafe, KMemoryManager::Direction_FromFront))); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(pg), num_pages, 1, KMemoryManager::EncodeOption(KMemoryManager::Pool_Unsafe, KMemoryManager::Direction_FromFront))); /* Close the page group when we're done with it. */ ON_SCOPE_EXIT { pg.Close(); }; diff --git a/libraries/libmesosphere/source/kern_k_shared_memory.cpp b/libraries/libmesosphere/source/kern_k_shared_memory.cpp index c7850fb1d..95d0dc401 100644 --- a/libraries/libmesosphere/source/kern_k_shared_memory.cpp +++ b/libraries/libmesosphere/source/kern_k_shared_memory.cpp @@ -37,7 +37,7 @@ namespace ams::kern { R_UNLESS(memory_reservation.Succeeded(), svc::ResultLimitReached()); /* Allocate the memory. */ - R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(m_page_group), num_pages, owner->GetAllocateOption())); + R_TRY(Kernel::GetMemoryManager().AllocateAndOpen(std::addressof(m_page_group), num_pages, 1, owner->GetAllocateOption())); /* Commit our reservation. */ memory_reservation.Commit(); From 0b04c89a84ebfab7fc044d515b6d0e7de09f7b1e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:19:45 -0700 Subject: [PATCH 096/238] kern: pass properties directly to KPageTableBase::AllocateAndMapPagesImpl --- .../include/mesosphere/kern_k_page_table_base.hpp | 2 +- .../libmesosphere/source/kern_k_page_table_base.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index bc5623163..2f3ad131a 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -332,7 +332,7 @@ namespace ams::kern { Result QueryMappingImpl(KProcessAddress *out, KPhysicalAddress address, size_t size, ams::svc::MemoryState state) const; - Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm); + Result AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, const KPageProperties &properties); Result MapPageGroupImpl(PageLinkedList *page_list, KProcessAddress address, const KPageGroup &pg, const KPageProperties properties, bool reuse_ll); void RemapPageGroup(PageLinkedList *page_list, KProcessAddress address, size_t size, const KPageGroup &pg); diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 136c92333..5ad8b274b 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1419,7 +1419,7 @@ namespace ams::kern { return this->GetSize(KMemoryState_AliasCodeData); } - Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, KMemoryPermission perm) { + Result KPageTableBase::AllocateAndMapPagesImpl(PageLinkedList *page_list, KProcessAddress address, size_t num_pages, const KPageProperties &properties) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* Create a page group to hold the pages we allocate. */ @@ -1437,7 +1437,6 @@ namespace ams::kern { } /* Map the pages. */ - const KPageProperties properties = { perm, false, false, DisableMergeAttribute_None }; R_RETURN(this->Operate(page_list, address, num_pages, pg, properties, OperationType_MapGroup, false)); } @@ -2419,11 +2418,11 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Perform mapping operation. */ + const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; if (is_pa_valid) { - const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, phys_addr, true, properties, OperationType_Map, false)); } else { - R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), addr, num_pages, perm)); + R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), addr, num_pages, properties)); } /* Update the blocks. */ @@ -2455,7 +2454,8 @@ namespace ams::kern { KScopedPageTableUpdater updater(this); /* Map the pages. */ - R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), address, num_pages, perm)); + const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; + R_TRY(this->AllocateAndMapPagesImpl(updater.GetPageList(), address, num_pages, properties)); /* Update the blocks. */ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, state, perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_Normal, KMemoryBlockDisableMergeAttribute_None); From c0a4fc30a8258711b9a21807afa245d31698846d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:22:19 -0700 Subject: [PATCH 097/238] kern: simplify size calculations in KPageTableBase::Read/WriteDebugIoMemory --- libraries/libmesosphere/source/kern_k_page_table_base.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 5ad8b274b..b96a6da3a 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -2994,7 +2994,7 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(src_page_table.GetPhysicalAddressLocked(std::addressof(phys_addr), address)); /* Determine the current read size. */ - const size_t cur_size = std::min(last_address - address + 1, util::AlignDown(GetInteger(address) + PageSize, PageSize) - GetInteger(address)); + const size_t cur_size = std::min(last_address - address + 1, PageSize - (GetInteger(address) & (PageSize - 1))); /* Read. */ R_TRY(dst_page_table.ReadIoMemoryImpl(dst, phys_addr, cur_size, state)); @@ -3030,7 +3030,7 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(src_page_table.GetPhysicalAddressLocked(std::addressof(phys_addr), address)); /* Determine the current read size. */ - const size_t cur_size = std::min(last_address - address + 1, util::AlignDown(GetInteger(address) + PageSize, PageSize) - GetInteger(address)); + const size_t cur_size = std::min(last_address - address + 1, PageSize - (GetInteger(address) & (PageSize - 1))); /* Read. */ R_TRY(dst_page_table.WriteIoMemoryImpl(phys_addr, src, cur_size, state)); From 952188fc731be328d5242e1fc4861f66b444329e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:30:24 -0700 Subject: [PATCH 098/238] kern: implement new attr tracking for memory range/traversal context --- .../mesosphere/arch/arm64/kern_k_page_table_impl.hpp | 1 + .../include/mesosphere/kern_k_page_table_base.hpp | 7 +++++-- .../source/arch/arm64/kern_k_page_table.cpp | 6 ++++-- .../source/arch/arm64/kern_k_page_table_impl.cpp | 9 +++++++++ .../libmesosphere/source/kern_k_page_table_base.cpp | 10 +++++++--- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index bdf461a0c..e5df6defb 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -30,6 +30,7 @@ namespace ams::kern::arch::arm64 { KPhysicalAddress phys_addr; size_t block_size; u8 sw_reserved_bits; + u8 attr; constexpr bool IsHeadMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHead) != 0; } constexpr bool IsHeadAndBodyMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadAndBody) != 0; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 2f3ad131a..99a27c6f9 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -62,18 +62,21 @@ namespace ams::kern { KPhysicalAddress m_address; size_t m_size; bool m_heap; + u8 m_attr; public: - constexpr MemoryRange() : m_address(Null), m_size(0), m_heap(false) { /* ... */ } + constexpr MemoryRange() : m_address(Null), m_size(0), m_heap(false), m_attr(0) { /* ... */ } - void Set(KPhysicalAddress address, size_t size, bool heap) { + void Set(KPhysicalAddress address, size_t size, bool heap, u8 attr) { m_address = address; m_size = size; m_heap = heap; + m_attr = attr; } constexpr KPhysicalAddress GetAddress() const { return m_address; } constexpr size_t GetSize() const { return m_size; } constexpr bool IsHeap() const { return m_heap; } + constexpr u8 GetAttribute() const { return m_attr; } void Open(); void Close(); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 0558b5b34..55e4fc52b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -258,7 +258,7 @@ namespace ams::kern::arch::arm64 { /* Begin the traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; bool cur_valid = false; TraversalEntry next_entry; bool next_valid; @@ -268,7 +268,9 @@ namespace ams::kern::arch::arm64 { /* Iterate over entries. */ while (true) { - if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size)) { + /* NOTE: Nintendo really does check next_entry.attr == (cur_entry.attr != 0)...but attr is always zero as of 18.0.0, and this is "probably" for the new console or debug-only anyway, */ + /* so we'll implement the weird logic verbatim even though it doesn't match the GetContiguousRange logic. */ + if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size && next_entry.attr == (cur_entry.attr ? 1 : 0))) { cur_entry.block_size += next_entry.block_size; } else { if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 95c7d7a64..280498f78 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -46,12 +46,14 @@ namespace ams::kern::arch::arm64 { out_entry->block_size = L3BlockSize; } out_entry->sw_reserved_bits = l3_entry->GetSoftwareReservedBits(); + out_entry->attr = 0; return true; } else { out_entry->phys_addr = Null; out_entry->block_size = L3BlockSize; out_entry->sw_reserved_bits = 0; + out_entry->attr = 0; return false; } } @@ -69,6 +71,7 @@ namespace ams::kern::arch::arm64 { out_entry->block_size = L2BlockSize; } out_entry->sw_reserved_bits = l2_entry->GetSoftwareReservedBits(); + out_entry->attr = 0; /* Set the output context. */ out_context->l3_entry = nullptr; @@ -79,6 +82,8 @@ namespace ams::kern::arch::arm64 { out_entry->phys_addr = Null; out_entry->block_size = L2BlockSize; out_entry->sw_reserved_bits = 0; + out_entry->attr = 0; + out_context->l3_entry = nullptr; return false; } @@ -108,6 +113,8 @@ namespace ams::kern::arch::arm64 { out_entry->phys_addr = Null; out_entry->block_size = L1BlockSize; out_entry->sw_reserved_bits = 0; + out_entry->attr = 0; + out_context->l2_entry = nullptr; out_context->l3_entry = nullptr; return false; @@ -119,6 +126,7 @@ namespace ams::kern::arch::arm64 { out_entry->phys_addr = Null; out_entry->block_size = L1BlockSize; out_entry->sw_reserved_bits = 0; + out_entry->attr = 0; out_context->l1_entry = m_table + m_num_entries; out_context->l2_entry = nullptr; out_context->l3_entry = nullptr; @@ -220,6 +228,7 @@ namespace ams::kern::arch::arm64 { out_entry->phys_addr = Null; out_entry->block_size = L1BlockSize; out_entry->sw_reserved_bits = 0; + out_entry->attr = 0; context->l1_entry = m_table + m_num_entries; context->l2_entry = nullptr; context->l3_entry = nullptr; diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index b96a6da3a..92aad904c 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -916,7 +916,7 @@ namespace ams::kern { /* Begin traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; bool cur_valid = false; TraversalEntry next_entry; bool next_valid; @@ -1687,11 +1687,12 @@ namespace ams::kern { /* Begin a traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0 }; + TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; R_UNLESS(impl.BeginTraversal(std::addressof(cur_entry), std::addressof(context), address), svc::ResultInvalidCurrentMemory()); /* Traverse until we have enough size or we aren't contiguous any more. */ const KPhysicalAddress phys_address = cur_entry.phys_addr; + const u8 entry_attr = cur_entry.attr; size_t contig_size; for (contig_size = cur_entry.block_size - (GetInteger(phys_address) & (cur_entry.block_size - 1)); contig_size < size; contig_size += cur_entry.block_size) { if (!impl.ContinueTraversal(std::addressof(cur_entry), std::addressof(context))) { @@ -1700,6 +1701,9 @@ namespace ams::kern { if (cur_entry.phys_addr != phys_address + contig_size) { break; } + if (cur_entry.attr != entry_attr) { + break; + } } /* Take the minimum size for our region. */ @@ -1713,7 +1717,7 @@ namespace ams::kern { } /* The memory is contiguous, so set the output range. */ - out->Set(phys_address, size, is_heap); + out->Set(phys_address, size, is_heap, attr); R_SUCCEED(); } From 6922eae3e786064bd68edea8b3db97757a75537b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:50:37 -0700 Subject: [PATCH 099/238] kern: add KPageGroup::CopyRangeTo --- .../include/mesosphere/kern_k_page_group.hpp | 2 + .../source/kern_k_initial_process_reader.cpp | 27 ++-------- .../source/kern_k_page_group.cpp | 52 +++++++++++++++++++ 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp index a0d150a08..2ab0a4670 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_group.hpp @@ -145,6 +145,8 @@ namespace ams::kern { bool IsEquivalentTo(const KPageGroup &rhs) const; + Result CopyRangeTo(KPageGroup &out, size_t offset, size_t size) const; + ALWAYS_INLINE bool operator==(const KPageGroup &rhs) const { return this->IsEquivalentTo(rhs); } diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index 727ddd476..c5ef13ac5 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -79,29 +79,7 @@ namespace ams::kern { /* Create a page group representing the segment. */ KPageGroup segment_pg(Kernel::GetSystemSystemResource().GetBlockInfoManagerPointer()); - if (size_t remaining_size = util::AlignUp(seg_size, PageSize); remaining_size != 0) { - /* Find the pages whose data corresponds to the segment. */ - size_t cur_offset = 0; - for (auto it = pg.begin(); it != pg.end() && remaining_size > 0; ++it) { - /* Get the current size. */ - const size_t cur_size = it->GetSize(); - - /* Determine if the offset is in range. */ - const size_t rel_diff = seg_offset - cur_offset; - const bool is_before = cur_offset <= seg_offset; - cur_offset += cur_size; - if (is_before && seg_offset < cur_offset) { - /* It is, so add the block. */ - const size_t block_size = std::min(cur_size - rel_diff, remaining_size); - MESOSPHERE_R_ABORT_UNLESS(segment_pg.AddBlock(it->GetAddress() + rel_diff, block_size / PageSize)); - - /* Advance. */ - cur_offset = seg_offset + block_size; - remaining_size -= block_size; - seg_offset += block_size; - } - } - } + MESOSPHERE_R_ABORT_UNLESS(pg.CopyRangeTo(segment_pg, seg_offset, util::AlignUp(seg_size, PageSize))); /* Setup the new page group's memory so that we can load the segment. */ { @@ -226,6 +204,9 @@ namespace ams::kern { const uintptr_t map_end = map_start + map_size; MESOSPHERE_ABORT_UNLESS(start_address == 0); + /* Default fields in parameter to zero. */ + *out = {}; + /* Set fields in parameter. */ out->code_address = map_start + start_address; out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize; diff --git a/libraries/libmesosphere/source/kern_k_page_group.cpp b/libraries/libmesosphere/source/kern_k_page_group.cpp index af363240f..a51e0a1ff 100644 --- a/libraries/libmesosphere/source/kern_k_page_group.cpp +++ b/libraries/libmesosphere/source/kern_k_page_group.cpp @@ -84,6 +84,58 @@ namespace ams::kern { R_SUCCEED(); } + Result KPageGroup::CopyRangeTo(KPageGroup &out, size_t range_offset, size_t range_size) const { + /* Get the previous last block for the group. */ + KBlockInfo * const out_last = out.m_last_block; + const auto out_last_addr = out_last != nullptr ? out_last->GetAddress() : Null; + const auto out_last_np = out_last != nullptr ? out_last->GetNumPages() : 0; + + /* Ensure we cleanup the group on failure. */ + ON_RESULT_FAILURE { + KBlockInfo *cur = out_last != nullptr ? out_last->GetNext() : out.m_first_block; + while (cur != nullptr) { + KBlockInfo *next = cur->GetNext(); + out.m_manager->Free(cur); + cur = next; + } + + if (out_last != nullptr) { + out_last->Initialize(out_last_addr, out_last_np); + out_last->SetNext(nullptr); + } else { + out.m_first_block = nullptr; + } + out.m_last_block = out_last; + }; + + /* Find the pages within the requested range. */ + size_t cur_offset = 0, remaining_size = range_size; + for (auto it = this->begin(); it != this->end() && remaining_size > 0; ++it) { + /* Get the current size. */ + const size_t cur_size = it->GetSize(); + + /* Determine if the offset is in range. */ + const size_t rel_diff = range_offset - cur_offset; + const bool is_before = cur_offset <= range_offset; + cur_offset += cur_size; + if (is_before && range_offset < cur_offset) { + /* It is, so add the block. */ + const size_t block_size = std::min(cur_size - rel_diff, remaining_size); + R_TRY(out.AddBlock(it->GetAddress() + rel_diff, block_size / PageSize)); + + /* Advance. */ + cur_offset = range_offset + block_size; + remaining_size -= block_size; + range_offset += block_size; + } + } + + /* Check that we successfully copied the range. */ + MESOSPHERE_ABORT_UNLESS(remaining_size == 0); + + R_SUCCEED(); + } + void KPageGroup::Open() const { auto &mm = Kernel::GetMemoryManager(); From 4fe139ea5287cf63bd575037ba1e1a70a2bb3b56 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 02:52:32 -0700 Subject: [PATCH 100/238] kern: return ExceptionType_UnalignedData on data abort caused by alignment fault --- .../source/arch/arm64/kern_exception_handlers.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index c5d319811..d55e217e3 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -223,6 +223,13 @@ namespace ams::kern::arch::arm64 { type = ams::svc::ExceptionType_InstructionAbort; break; case EsrEc_DataAbortEl0: + /* If esr.IFSC is "Alignment Fault", return UnalignedData instead of DataAbort. */ + if ((esr & 0x3F) == 0b100001) { + type = ams::svc::ExceptionType_UnalignedData; + } else { + type = ams::svc::ExceptionType_DataAbort; + } + break; default: type = ams::svc::ExceptionType_DataAbort; break; From ecbe5cd406ca67d7fa9dc96420ec6bfb023aa9f9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 03:42:37 -0700 Subject: [PATCH 101/238] kern: refactor smc helpers to share more common logic --- .../arch/arm64/kern_secure_monitor_base.hpp | 47 ++-- .../nintendo/nx/kern_k_system_control.cpp | 7 +- .../board/nintendo/nx/kern_secure_monitor.cpp | 201 ++++++++++++------ .../board/nintendo/nx/kern_secure_monitor.hpp | 4 +- .../source/kern_k_system_control_base.cpp | 2 +- 5 files changed, 155 insertions(+), 106 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp index 76ec13937..a3e8f080b 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_secure_monitor_base.hpp @@ -16,11 +16,10 @@ #pragma once #include #include -#include namespace ams::kern::arch::arm64::smc { - template + template void SecureMonitorCall(u64 *buf) { /* Load arguments into registers. */ register u64 x0 asm("x0") = buf[0]; @@ -32,34 +31,18 @@ namespace ams::kern::arch::arm64::smc { register u64 x6 asm("x6") = buf[6]; register u64 x7 asm("x7") = buf[7]; + /* Backup the current thread pointer. */ + const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue(); + /* Perform the call. */ - if constexpr (DisableInterrupt) { - KScopedInterruptDisable di; + __asm__ __volatile__("smc %c[smc_id]" + : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) + : [smc_id]"i"(SmcId) + : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" + ); - /* Backup the current thread pointer. */ - const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue(); - - __asm__ __volatile__("smc %c[smc_id]" - : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) - : [smc_id]"i"(SmcId) - : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" - ); - - /* Restore the current thread pointer into X18. */ - cpu::SetCurrentThreadPointerValue(current_thread_pointer_value); - } else { - /* Backup the current thread pointer. */ - const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue(); - - __asm__ __volatile__("smc %c[smc_id]" - : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7) - : [smc_id]"i"(SmcId) - : "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory" - ); - - /* Restore the current thread pointer into X18. */ - cpu::SetCurrentThreadPointerValue(current_thread_pointer_value); - } + /* Restore the current thread pointer into X18. */ + cpu::SetCurrentThreadPointerValue(current_thread_pointer_value); /* Store arguments to output. */ buf[0] = x0; @@ -78,18 +61,18 @@ namespace ams::kern::arch::arm64::smc { PsciFunction_CpuOn = 0xC4000003, }; - template + template u64 PsciCall(PsciFunction function, u64 x1 = 0, u64 x2 = 0, u64 x3 = 0, u64 x4 = 0, u64 x5 = 0, u64 x6 = 0, u64 x7 = 0) { ams::svc::lp64::SecureMonitorArguments args = { { function, x1, x2, x3, x4, x5, x6, x7 } }; - SecureMonitorCall(args.r); + SecureMonitorCall(args.r); return args.r[0]; } - template + template u64 CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { - return PsciCall(PsciFunction_CpuOn, core_id, entrypoint, arg); + return PsciCall(PsciFunction_CpuOn, core_id, entrypoint, arg); } } diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index e3ac52278..52a894d1c 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -296,7 +296,7 @@ namespace ams::kern::board::nintendo::nx { /* TODO: Move this into a header for the MC in general. */ constexpr u32 MemoryControllerConfigurationRegister = 0x70019050; u32 config_value; - MESOSPHERE_INIT_ABORT_UNLESS(smc::init::ReadWriteRegister(&config_value, MemoryControllerConfigurationRegister, 0, 0)); + smc::init::ReadWriteRegister(std::addressof(config_value), MemoryControllerConfigurationRegister, 0, 0); return static_cast(config_value & 0x3FFF) << 20; } @@ -387,7 +387,7 @@ namespace ams::kern::board::nintendo::nx { } void KSystemControl::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { - MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn(core_id, entrypoint, arg)) == 0); + MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn(core_id, entrypoint, arg)) == 0); } /* Randomness for Initialization. */ @@ -601,8 +601,9 @@ namespace ams::kern::board::nintendo::nx { if (g_call_smc_on_panic) { /* If we should, instruct the secure monitor to display a panic screen. */ - smc::Panic(0xF00); + smc::ShowError(0xF00); } + AMS_INFINITE_LOOP(); } diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp index 6b1e3923f..d55eb2c70 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.cpp @@ -43,7 +43,7 @@ namespace ams::kern::board::nintendo::nx::smc { enum FunctionId : u32 { FunctionId_GetConfig = 0xC3000004, FunctionId_GenerateRandomBytes = 0xC3000005, - FunctionId_Panic = 0xC3000006, + FunctionId_ShowError = 0xC3000006, FunctionId_ConfigureCarveout = 0xC3000007, FunctionId_ReadWriteRegister = 0xC3000008, @@ -51,122 +51,187 @@ namespace ams::kern::board::nintendo::nx::smc { FunctionId_SetConfig = 0xC3000409, }; + constexpr size_t GenerateRandomBytesSizeMax = sizeof(::ams::svc::lp64::SecureMonitorArguments) - sizeof(::ams::svc::lp64::SecureMonitorArguments{}.r[0]); + /* Global lock for generate random bytes. */ constinit KSpinLock g_generate_random_lock; + bool TryGetConfigImpl(u64 *out, size_t num_qwords, ConfigItem config_item) { + /* Create the arguments .*/ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast(config_item) } }; + + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + /* If successful, copy the output. */ + const bool success = static_cast(args.r[0]) == SmcResult::Success; + if (AMS_LIKELY(success)) { + for (size_t i = 0; i < num_qwords && i < 7; i++) { + out[i] = args.r[1 + i]; + } + } + + return success; + } + + bool SetConfigImpl(ConfigItem config_item, u64 value) { + /* Create the arguments .*/ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast(config_item), 0, value } }; + + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + /* Return whether the call was successful. */ + return static_cast(args.r[0]) == SmcResult::Success; + } + + bool ReadWriteRegisterImpl(u32 *out, u64 address, u32 mask, u32 value) { + /* Create the arguments .*/ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } }; + + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + /* Unconditionally write the output. */ + *out = static_cast(args.r[1]); + + /* Return whether the call was successful. */ + return static_cast(args.r[0]) == SmcResult::Success; + } + + bool GenerateRandomBytesImpl(void *dst, size_t size) { + /* Create the arguments. */ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } }; + + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + /* If successful, copy the output. */ + const bool success = static_cast(args.r[0]) == SmcResult::Success; + if (AMS_LIKELY(success)) { + std::memcpy(dst, std::addressof(args.r[1]), size); + } + + return success; + } + + bool ConfigureCarveoutImpl(size_t which, uintptr_t address, size_t size) { + /* Create the arguments .*/ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast(which), static_cast(address), static_cast(size) } }; + + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + /* Return whether the call was successful. */ + return static_cast(args.r[0]) == SmcResult::Success; + } + + bool ShowErrorImpl(u32 color) { + /* Create the arguments .*/ + ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ShowError, color } }; + + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); + + /* Return whether the call was successful. */ + return static_cast(args.r[0]) == SmcResult::Success; + } + + void CallSecureMonitorFromUserImpl(ams::svc::lp64::SecureMonitorArguments *args) { + /* Call into the secure monitor. */ + ::ams::kern::arch::arm64::smc::SecureMonitorCall(args->r); + } + } /* SMC functionality needed for init. */ namespace init { void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast(config_item) } }; - - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); - - for (size_t i = 0; i < num_qwords && i < 7; i++) { - out[i] = args.r[1 + i]; - } + /* Ensure we successfully get the config. */ + MESOSPHERE_INIT_ABORT_UNLESS(TryGetConfigImpl(out, num_qwords, config_item)); } void GenerateRandomBytes(void *dst, size_t size) { - /* Call SmcGenerateRandomBytes() */ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } }; - MESOSPHERE_INIT_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0])); + /* Check that the size is valid. */ + MESOSPHERE_INIT_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax); - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); - - /* Copy output. */ - std::memcpy(dst, std::addressof(args.r[1]), size); + /* Ensure we successfully generate the random bytes. */ + MESOSPHERE_INIT_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size)); } - bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } }; - - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - MESOSPHERE_INIT_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); - - *out = args.r[1]; - - return static_cast(args.r[0]) == SmcResult::Success; + void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value) { + /* Ensure we successfully access the register. */ + MESOSPHERE_INIT_ABORT_UNLESS(ReadWriteRegisterImpl(out, address, mask, value)); } } bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast(config_item) } }; + /* Disable interrupts. */ + KScopedInterruptDisable di; - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - if (AMS_UNLIKELY(static_cast(args.r[0]) != SmcResult::Success)) { - return false; - } - - for (size_t i = 0; i < num_qwords && i < 7; i++) { - out[i] = args.r[1 + i]; - } - - return true; + /* Get the config. */ + return TryGetConfigImpl(out, num_qwords, config_item); } void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) { + /* Ensure we successfully get the config. */ MESOSPHERE_ABORT_UNLESS(TryGetConfig(out, num_qwords, config_item)); } bool SetConfig(ConfigItem config_item, u64 value) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast(config_item), 0, value } }; + /* Disable interrupts. */ + KScopedInterruptDisable di; - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - return static_cast(args.r[0]) == SmcResult::Success; + /* Set the config. */ + return SetConfigImpl(config_item, value); } bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } }; + /* Disable interrupts. */ + KScopedInterruptDisable di; - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - *out = static_cast(args.r[1]); - return static_cast(args.r[0]) == SmcResult::Success; + /* Access the register. */ + return ReadWriteRegisterImpl(out, address, mask, value); } void ConfigureCarveout(size_t which, uintptr_t address, size_t size) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast(which), static_cast(address), static_cast(size) } }; + /* Disable interrupts. */ + KScopedInterruptDisable di; - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - MESOSPHERE_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); + /* Ensure that we successfully configure the carveout. */ + MESOSPHERE_ABORT_UNLESS(ConfigureCarveoutImpl(which, address, size)); } void GenerateRandomBytes(void *dst, size_t size) { - /* Setup for call. */ - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } }; - MESOSPHERE_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0])); + /* Check that the size is valid. */ + MESOSPHERE_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax); - /* Make call. */ - { - KScopedInterruptDisable intr_disable; - KScopedSpinLock lk(g_generate_random_lock); + /* Disable interrupts. */ + KScopedInterruptDisable di; - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - } - MESOSPHERE_ABORT_UNLESS((static_cast(args.r[0]) == SmcResult::Success)); + /* Acquire the exclusive right to generate random bytes. */ + KScopedSpinLock lk(g_generate_random_lock); - /* Copy output. */ - std::memcpy(dst, std::addressof(args.r[1]), size); + /* Ensure we successfully generate the random bytes. */ + MESOSPHERE_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size)); } - void NORETURN Panic(u32 color) { - ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_Panic, color } }; + void ShowError(u32 color) { + /* Disable interrupts. */ + KScopedInterruptDisable di; - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args.r); - - AMS_INFINITE_LOOP(); + /* Ensure we successfully show the error. */ + MESOSPHERE_ABORT_UNLESS(ShowErrorImpl(color)); } void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) { - ::ams::kern::arch::arm64::smc::SecureMonitorCall(args->r); + /* Disable interrupts. */ + KScopedInterruptDisable di; + + /* Perform the call. */ + CallSecureMonitorFromUserImpl(args); } } \ No newline at end of file diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp index b172fa540..1e64d11f9 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -111,7 +111,7 @@ namespace ams::kern::board::nintendo::nx::smc { bool SetConfig(ConfigItem config_item, u64 value); - void NORETURN Panic(u32 color); + void ShowError(u32 color); void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args); @@ -119,7 +119,7 @@ namespace ams::kern::board::nintendo::nx::smc { void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item); void GenerateRandomBytes(void *dst, size_t size); - bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value); + void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value); } diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index 6764662d9..8412fbf75 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -78,7 +78,7 @@ namespace ams::kern { void KSystemControlBase::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) { #if defined(ATMOSPHERE_ARCH_ARM64) - MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0, false>(core_id, entrypoint, arg)) == 0); + MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0>(core_id, entrypoint, arg)) == 0); #else AMS_INFINITE_LOOP(); #endif From c0487ad384ac593594857df06b34b5fd7edbcca8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 03:43:22 -0700 Subject: [PATCH 102/238] kern: fix whoops in new page table logic --- libraries/libmesosphere/source/kern_k_page_table_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 92aad904c..2e90d924e 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -301,7 +301,7 @@ namespace ams::kern { /* If aslr is enabled, randomize the current region order. Otherwise, sort by type. */ if (m_enable_aslr) { for (size_t i = 0; i < cur_alloc_count - 1; ++i) { - std::swap(region_layouts[i], region_layouts[KSystemControl::GenerateRandomRange(i, cur_alloc_count - 1)]); + std::swap(region_layouts[cur_region_index + i], region_layouts[cur_region_index + KSystemControl::GenerateRandomRange(i, cur_alloc_count - 1)]); } } else { for (size_t i = 0; i < cur_alloc_count - 1; ++i) { From 05090005b734f4e9ff610e183b7e43802ffb4fff Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 03:44:31 -0700 Subject: [PATCH 103/238] svc: advertise support for 18.3.0.0 --- libraries/libvapours/include/vapours/svc/svc_version.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index c7fb5341f..e7ece762b 100644 --- a/libraries/libvapours/include/vapours/svc/svc_version.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_version.hpp @@ -57,8 +57,8 @@ namespace ams::svc { /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ - constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(17); - constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 5); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(18); + constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); From 21c85c6a4f5a04fd8523f622c13ab6e538a0eec4 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 03:45:07 -0700 Subject: [PATCH 104/238] exo/fusee: apparently 18.0.0 did not burn a fuse --- libraries/libexosphere/source/fuse/fuse_api.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 772e8ca9c..95c316d68 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,7 +177,6 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { - TargetFirmware_18_0_0, TargetFirmware_17_0_0, TargetFirmware_16_0_0, TargetFirmware_15_0_0, From 4ff9278d1183b9ea8f8109357edde0e81586aa66 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 03:46:41 -0700 Subject: [PATCH 105/238] jpegdec: stop bundling (TODO post-prerelease) --- atmosphere.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atmosphere.mk b/atmosphere.mk index 706b5f320..cca6fc106 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -84,7 +84,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037 - mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c + #mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240 @@ -98,7 +98,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) cp stratosphere/fatal/$(ATMOSPHERE_OUT_DIR)/fatal.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000034/exefs.nsp cp stratosphere/creport/$(ATMOSPHERE_OUT_DIR)/creport.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000036/exefs.nsp cp stratosphere/ro/$(ATMOSPHERE_OUT_DIR)/ro.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000037/exefs.nsp - cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp + #cp stratosphere/jpegdec/$(ATMOSPHERE_OUT_DIR)/jpegdec.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c/exefs.nsp cp stratosphere/pgl/$(ATMOSPHERE_OUT_DIR)/pgl.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042/exefs.nsp cp stratosphere/LogManager/$(ATMOSPHERE_OUT_DIR)/LogManager.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420/exefs.nsp cp stratosphere/htc/$(ATMOSPHERE_OUT_DIR)/htc.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240/exefs.nsp From d2c2a94c5ea9b4ccd805194640efe7c3570fca79 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 03:51:10 -0700 Subject: [PATCH 106/238] erpt: add new IDs/categories --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 1661 +++++++++-------- utilities/erpt.py | 15 +- 2 files changed, 851 insertions(+), 825 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index 57630304d..cb3d3173a 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -38,829 +38,844 @@ HANDLER(FieldType_I8Array, 15) \ #define AMS_ERPT_FOREACH_CATEGORY(HANDLER) \ - HANDLER(Test, 0 ) \ - HANDLER(ErrorInfo, 1 ) \ - HANDLER(ConnectionStatusInfo, 2 ) \ - HANDLER(NetworkInfo, 3 ) \ - HANDLER(NXMacAddressInfo, 4 ) \ - HANDLER(StealthNetworkInfo, 5 ) \ - HANDLER(LimitHighCapacityInfo, 6 ) \ - HANDLER(NATTypeInfo, 7 ) \ - HANDLER(WirelessAPMacAddressInfo, 8 ) \ - HANDLER(GlobalIPAddressInfo, 9 ) \ - HANDLER(EnableWirelessInterfaceInfo, 10 ) \ - HANDLER(EnableWifiInfo, 11 ) \ - HANDLER(EnableBluetoothInfo, 12 ) \ - HANDLER(EnableNFCInfo, 13 ) \ - HANDLER(NintendoZoneSSIDListVersionInfo, 14 ) \ - HANDLER(LANAdapterMacAddressInfo, 15 ) \ - HANDLER(ApplicationInfo, 16 ) \ - HANDLER(OccurrenceInfo, 17 ) \ - HANDLER(ProductModelInfo, 18 ) \ - HANDLER(CurrentLanguageInfo, 19 ) \ - HANDLER(UseNetworkTimeProtocolInfo, 20 ) \ - HANDLER(TimeZoneInfo, 21 ) \ - HANDLER(ControllerFirmwareInfo, 22 ) \ - HANDLER(VideoOutputInfo, 23 ) \ - HANDLER(NANDFreeSpaceInfo, 24 ) \ - HANDLER(SDCardFreeSpaceInfo, 25 ) \ - HANDLER(ScreenBrightnessInfo, 26 ) \ - HANDLER(AudioFormatInfo, 27 ) \ - HANDLER(MuteOnHeadsetUnpluggedInfo, 28 ) \ - HANDLER(NumUserRegisteredInfo, 29 ) \ - HANDLER(DataDeletionInfo, 30 ) \ - HANDLER(ControllerVibrationInfo, 31 ) \ - HANDLER(LockScreenInfo, 32 ) \ - HANDLER(InternalBatteryLotNumberInfo, 33 ) \ - HANDLER(LeftControllerSerialNumberInfo, 34 ) \ - HANDLER(RightControllerSerialNumberInfo, 35 ) \ - HANDLER(NotificationInfo, 36 ) \ - HANDLER(TVInfo, 37 ) \ - HANDLER(SleepInfo, 38 ) \ - HANDLER(ConnectionInfo, 39 ) \ - HANDLER(NetworkErrorInfo, 40 ) \ - HANDLER(FileAccessPathInfo, 41 ) \ - HANDLER(GameCardCIDInfo, 42 ) \ - HANDLER(NANDCIDInfo, 43 ) \ - HANDLER(MicroSDCIDInfo, 44 ) \ - HANDLER(NANDSpeedModeInfo, 45 ) \ - HANDLER(MicroSDSpeedModeInfo, 46 ) \ - HANDLER(GameCardSpeedModeInfo, 47 ) \ - HANDLER(UserAccountInternalIDInfo, 48 ) \ - HANDLER(NetworkServiceAccountInternalIDInfo, 49 ) \ - HANDLER(NintendoAccountInternalIDInfo, 50 ) \ - HANDLER(USB3AvailableInfo, 51 ) \ - HANDLER(CallStackInfo, 52 ) \ - HANDLER(SystemStartupLogInfo, 53 ) \ - HANDLER(RegionSettingInfo, 54 ) \ - HANDLER(NintendoZoneConnectedInfo, 55 ) \ - HANDLER(ForceSleepInfo, 56 ) \ - HANDLER(ChargerInfo, 57 ) \ - HANDLER(RadioStrengthInfo, 58 ) \ - HANDLER(ErrorInfoAuto, 59 ) \ - HANDLER(AccessPointInfo, 60 ) \ - HANDLER(ErrorInfoDefaults, 61 ) \ - HANDLER(SystemPowerStateInfo, 62 ) \ - HANDLER(PerformanceInfo, 63 ) \ - HANDLER(ThrottlingInfo, 64 ) \ - HANDLER(GameCardErrorInfo, 65 ) \ - HANDLER(EdidInfo, 66 ) \ - HANDLER(ThermalInfo, 67 ) \ - HANDLER(CradleFirmwareInfo, 68 ) \ - HANDLER(RunningApplicationInfo, 69 ) \ - HANDLER(RunningAppletInfo, 70 ) \ - HANDLER(FocusedAppletHistoryInfo, 71 ) \ - HANDLER(CompositorInfo, 72 ) \ - HANDLER(BatteryChargeInfo, 73 ) \ - HANDLER(NANDExtendedCsd, 74 ) \ - HANDLER(NANDPatrolInfo, 75 ) \ - HANDLER(NANDErrorInfo, 76 ) \ - HANDLER(NANDDriverLog, 77 ) \ - HANDLER(SdCardSizeSpec, 78 ) \ - HANDLER(SdCardErrorInfo, 79 ) \ - HANDLER(SdCardDriverLog , 80 ) \ - HANDLER(FsProxyErrorInfo, 81 ) \ - HANDLER(SystemAppletSceneInfo, 82 ) \ - HANDLER(VideoInfo, 83 ) \ - HANDLER(GpuErrorInfo, 84 ) \ - HANDLER(PowerClockInfo, 85 ) \ - HANDLER(AdspErrorInfo, 86 ) \ - HANDLER(NvDispDeviceInfo, 87 ) \ - HANDLER(NvDispDcWindowInfo, 88 ) \ - HANDLER(NvDispDpModeInfo, 89 ) \ - HANDLER(NvDispDpLinkSpec, 90 ) \ - HANDLER(NvDispDpLinkStatus, 91 ) \ - HANDLER(NvDispDpHdcpInfo, 92 ) \ - HANDLER(NvDispDpAuxCecInfo, 93 ) \ - HANDLER(NvDispDcInfo, 94 ) \ - HANDLER(NvDispDsiInfo, 95 ) \ - HANDLER(NvDispErrIDInfo, 96 ) \ - HANDLER(SdCardMountInfo, 97 ) \ - HANDLER(RetailInteractiveDisplayInfo, 98 ) \ - HANDLER(CompositorStateInfo, 99 ) \ - HANDLER(CompositorLayerInfo, 100) \ - HANDLER(CompositorDisplayInfo, 101) \ - HANDLER(CompositorHWCInfo, 102) \ - HANDLER(MonitorCapability, 103) \ - HANDLER(ErrorReportSharePermissionInfo, 104) \ - HANDLER(MultimediaInfo, 105) \ - HANDLER(ConnectedControllerInfo, 106) \ - HANDLER(FsMemoryInfo, 107) \ - HANDLER(UserClockContextInfo, 108) \ - HANDLER(NetworkClockContextInfo, 109) \ - HANDLER(AcpGeneralSettingsInfo, 110) \ - HANDLER(AcpPlayLogSettingsInfo, 111) \ - HANDLER(AcpAocSettingsInfo, 112) \ - HANDLER(AcpBcatSettingsInfo, 113) \ - HANDLER(AcpStorageSettingsInfo, 114) \ - HANDLER(AcpRatingSettingsInfo, 115) \ - HANDLER(MonitorSettings, 116) \ - HANDLER(RebootlessSystemUpdateVersionInfo, 117) \ - HANDLER(NifmConnectionTestInfo, 118) \ - HANDLER(PcieLoggedStateInfo, 119) \ - HANDLER(NetworkSecurityCertificateInfo, 120) \ - HANDLER(AcpNeighborDetectionInfo, 121) \ - HANDLER(GpuCrashInfo, 122) \ - HANDLER(UsbStateInfo, 123) \ - HANDLER(NvHostErrInfo, 124) \ - HANDLER(RunningUlaInfo, 125) \ - HANDLER(InternalPanelInfo, 126) \ - HANDLER(ResourceLimitLimitInfo, 127) \ - HANDLER(ResourceLimitPeakInfo, 128) \ - HANDLER(TouchScreenInfo, 129) \ - HANDLER(AcpUserAccountSettingsInfo, 130) \ - HANDLER(AudioDeviceInfo, 131) \ - HANDLER(AbnormalWakeInfo, 132) \ - HANDLER(ServiceProfileInfo, 133) \ - HANDLER(BluetoothAudioInfo, 134) \ - HANDLER(BluetoothPairingCountInfo, 135) \ - HANDLER(FsProxyErrorInfo2, 136) \ - HANDLER(BuiltInWirelessOUIInfo, 137) \ - HANDLER(WirelessAPOUIInfo, 138) \ - HANDLER(EthernetAdapterOUIInfo, 139) \ - HANDLER(NANDTypeInfo, 140) \ - HANDLER(MicroSDTypeInfo, 141) \ + HANDLER(Test, 0 ) \ + HANDLER(ErrorInfo, 1 ) \ + HANDLER(ConnectionStatusInfo, 2 ) \ + HANDLER(NetworkInfo, 3 ) \ + HANDLER(NXMacAddressInfo, 4 ) \ + HANDLER(StealthNetworkInfo, 5 ) \ + HANDLER(LimitHighCapacityInfo, 6 ) \ + HANDLER(NATTypeInfo, 7 ) \ + HANDLER(WirelessAPMacAddressInfo, 8 ) \ + HANDLER(GlobalIPAddressInfo, 9 ) \ + HANDLER(EnableWirelessInterfaceInfo, 10 ) \ + HANDLER(EnableWifiInfo, 11 ) \ + HANDLER(EnableBluetoothInfo, 12 ) \ + HANDLER(EnableNFCInfo, 13 ) \ + HANDLER(NintendoZoneSSIDListVersionInfo, 14 ) \ + HANDLER(LANAdapterMacAddressInfo, 15 ) \ + HANDLER(ApplicationInfo, 16 ) \ + HANDLER(OccurrenceInfo, 17 ) \ + HANDLER(ProductModelInfo, 18 ) \ + HANDLER(CurrentLanguageInfo, 19 ) \ + HANDLER(UseNetworkTimeProtocolInfo, 20 ) \ + HANDLER(TimeZoneInfo, 21 ) \ + HANDLER(ControllerFirmwareInfo, 22 ) \ + HANDLER(VideoOutputInfo, 23 ) \ + HANDLER(NANDFreeSpaceInfo, 24 ) \ + HANDLER(SDCardFreeSpaceInfo, 25 ) \ + HANDLER(ScreenBrightnessInfo, 26 ) \ + HANDLER(AudioFormatInfo, 27 ) \ + HANDLER(MuteOnHeadsetUnpluggedInfo, 28 ) \ + HANDLER(NumUserRegisteredInfo, 29 ) \ + HANDLER(DataDeletionInfo, 30 ) \ + HANDLER(ControllerVibrationInfo, 31 ) \ + HANDLER(LockScreenInfo, 32 ) \ + HANDLER(InternalBatteryLotNumberInfo, 33 ) \ + HANDLER(LeftControllerSerialNumberInfo, 34 ) \ + HANDLER(RightControllerSerialNumberInfo, 35 ) \ + HANDLER(NotificationInfo, 36 ) \ + HANDLER(TVInfo, 37 ) \ + HANDLER(SleepInfo, 38 ) \ + HANDLER(ConnectionInfo, 39 ) \ + HANDLER(NetworkErrorInfo, 40 ) \ + HANDLER(FileAccessPathInfo, 41 ) \ + HANDLER(GameCardCIDInfo, 42 ) \ + HANDLER(NANDCIDInfo, 43 ) \ + HANDLER(MicroSDCIDInfo, 44 ) \ + HANDLER(NANDSpeedModeInfo, 45 ) \ + HANDLER(MicroSDSpeedModeInfo, 46 ) \ + HANDLER(GameCardSpeedModeInfo, 47 ) \ + HANDLER(UserAccountInternalIDInfo, 48 ) \ + HANDLER(NetworkServiceAccountInternalIDInfo, 49 ) \ + HANDLER(NintendoAccountInternalIDInfo, 50 ) \ + HANDLER(USB3AvailableInfo, 51 ) \ + HANDLER(CallStackInfo, 52 ) \ + HANDLER(SystemStartupLogInfo, 53 ) \ + HANDLER(RegionSettingInfo, 54 ) \ + HANDLER(NintendoZoneConnectedInfo, 55 ) \ + HANDLER(ForceSleepInfo, 56 ) \ + HANDLER(ChargerInfo, 57 ) \ + HANDLER(RadioStrengthInfo, 58 ) \ + HANDLER(ErrorInfoAuto, 59 ) \ + HANDLER(AccessPointInfo, 60 ) \ + HANDLER(ErrorInfoDefaults, 61 ) \ + HANDLER(SystemPowerStateInfo, 62 ) \ + HANDLER(PerformanceInfo, 63 ) \ + HANDLER(ThrottlingInfo, 64 ) \ + HANDLER(GameCardErrorInfo, 65 ) \ + HANDLER(EdidInfo, 66 ) \ + HANDLER(ThermalInfo, 67 ) \ + HANDLER(CradleFirmwareInfo, 68 ) \ + HANDLER(RunningApplicationInfo, 69 ) \ + HANDLER(RunningAppletInfo, 70 ) \ + HANDLER(FocusedAppletHistoryInfo, 71 ) \ + HANDLER(CompositorInfo, 72 ) \ + HANDLER(BatteryChargeInfo, 73 ) \ + HANDLER(NANDExtendedCsd, 74 ) \ + HANDLER(NANDPatrolInfo, 75 ) \ + HANDLER(NANDErrorInfo, 76 ) \ + HANDLER(NANDDriverLog, 77 ) \ + HANDLER(SdCardSizeSpec, 78 ) \ + HANDLER(SdCardErrorInfo, 79 ) \ + HANDLER(SdCardDriverLog , 80 ) \ + HANDLER(FsProxyErrorInfo, 81 ) \ + HANDLER(SystemAppletSceneInfo, 82 ) \ + HANDLER(VideoInfo, 83 ) \ + HANDLER(GpuErrorInfo, 84 ) \ + HANDLER(PowerClockInfo, 85 ) \ + HANDLER(AdspErrorInfo, 86 ) \ + HANDLER(NvDispDeviceInfo, 87 ) \ + HANDLER(NvDispDcWindowInfo, 88 ) \ + HANDLER(NvDispDpModeInfo, 89 ) \ + HANDLER(NvDispDpLinkSpec, 90 ) \ + HANDLER(NvDispDpLinkStatus, 91 ) \ + HANDLER(NvDispDpHdcpInfo, 92 ) \ + HANDLER(NvDispDpAuxCecInfo, 93 ) \ + HANDLER(NvDispDcInfo, 94 ) \ + HANDLER(NvDispDsiInfo, 95 ) \ + HANDLER(NvDispErrIDInfo, 96 ) \ + HANDLER(SdCardMountInfo, 97 ) \ + HANDLER(RetailInteractiveDisplayInfo, 98 ) \ + HANDLER(CompositorStateInfo, 99 ) \ + HANDLER(CompositorLayerInfo, 100 ) \ + HANDLER(CompositorDisplayInfo, 101 ) \ + HANDLER(CompositorHWCInfo, 102 ) \ + HANDLER(MonitorCapability, 103 ) \ + HANDLER(ErrorReportSharePermissionInfo, 104 ) \ + HANDLER(MultimediaInfo, 105 ) \ + HANDLER(ConnectedControllerInfo, 106 ) \ + HANDLER(FsMemoryInfo, 107 ) \ + HANDLER(UserClockContextInfo, 108 ) \ + HANDLER(NetworkClockContextInfo, 109 ) \ + HANDLER(AcpGeneralSettingsInfo, 110 ) \ + HANDLER(AcpPlayLogSettingsInfo, 111 ) \ + HANDLER(AcpAocSettingsInfo, 112 ) \ + HANDLER(AcpBcatSettingsInfo, 113 ) \ + HANDLER(AcpStorageSettingsInfo, 114 ) \ + HANDLER(AcpRatingSettingsInfo, 115 ) \ + HANDLER(MonitorSettings, 116 ) \ + HANDLER(RebootlessSystemUpdateVersionInfo, 117 ) \ + HANDLER(NifmConnectionTestInfo, 118 ) \ + HANDLER(PcieLoggedStateInfo, 119 ) \ + HANDLER(NetworkSecurityCertificateInfo, 120 ) \ + HANDLER(AcpNeighborDetectionInfo, 121 ) \ + HANDLER(GpuCrashInfo, 122 ) \ + HANDLER(UsbStateInfo, 123 ) \ + HANDLER(NvHostErrInfo, 124 ) \ + HANDLER(RunningUlaInfo, 125 ) \ + HANDLER(InternalPanelInfo, 126 ) \ + HANDLER(ResourceLimitLimitInfo, 127 ) \ + HANDLER(ResourceLimitPeakInfo, 128 ) \ + HANDLER(TouchScreenInfo, 129 ) \ + HANDLER(AcpUserAccountSettingsInfo, 130 ) \ + HANDLER(AudioDeviceInfo, 131 ) \ + HANDLER(AbnormalWakeInfo, 132 ) \ + HANDLER(ServiceProfileInfo, 133 ) \ + HANDLER(BluetoothAudioInfo, 134 ) \ + HANDLER(BluetoothPairingCountInfo, 135 ) \ + HANDLER(FsProxyErrorInfo2, 136 ) \ + HANDLER(BuiltInWirelessOUIInfo, 137 ) \ + HANDLER(WirelessAPOUIInfo, 138 ) \ + HANDLER(EthernetAdapterOUIInfo, 139 ) \ + HANDLER(NANDTypeInfo, 140 ) \ + HANDLER(MicroSDTypeInfo, 141 ) \ + HANDLER(TestNx, 1000) \ #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ - HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ - HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ - HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ - HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ - HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ - HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ - HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ - HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ - HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ - HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ - HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ - HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ - HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ - HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ - HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ - HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ - HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ - HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatSafeControlResult, 670, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatErrorNumber, 671, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisSystemFatSafeErrorNumber, 672, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatSafeControlResult, 673, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatErrorNumber, 674, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FatFsBisUserFatSafeErrorNumber, 675, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(GpuCrashDump2, 676, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDType, 677, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDType, 678, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(GameCardLastDeactivateReasonResult, 679, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(GameCardLastDeactivateReason, 680, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TestU32, 1, Test, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestI64, 2, Test, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(TestI32, 3, Test, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TestString, 4, Test, FieldType_String, FieldFlag_None ) \ + HANDLER(TestU8Array, 5, Test, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TestU32Array, 6, Test, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(TestU64Array, 7, Test, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(TestI32Array, 8, Test, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(TestI64Array, 9, Test, FieldType_I64Array, FieldFlag_None ) \ + HANDLER(ErrorCode, 10, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ErrorDescription, 11, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(OccurrenceTimestamp, 12, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ReportIdentifier, 13, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ConnectionStatus, 14, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSSID, 15, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AccessPointSecurityType, 16, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RadioStrength, 17, RadioStrengthInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NXMacAddress, 18, NXMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(IPAddressAcquisitionMethod, 19, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CurrentIPAddress, 20, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SubnetMask, 21, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GatewayIPAddress, 22, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DNSType, 23, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PriorityDNSIPAddress, 24, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AlternateDNSIPAddress, 25, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseProxyFlag, 26, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProxyIPAddress, 27, NetworkInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProxyPort, 28, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProxyAutoAuthenticateFlag, 29, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(MTU, 30, NetworkInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ConnectAutomaticallyFlag, 31, NetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(UseStealthNetworkFlag, 32, StealthNetworkInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LimitHighCapacityFlag, 33, LimitHighCapacityInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NATType, 34, NATTypeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPMacAddress, 35, WirelessAPMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GlobalIPAddress, 36, GlobalIPAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EnableWirelessInterfaceFlag, 37, EnableWirelessInterfaceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableWifiFlag, 38, EnableWifiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableBluetoothFlag, 39, EnableBluetoothInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(EnableNFCFlag, 40, EnableNFCInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NintendoZoneSSIDListVersion, 41, NintendoZoneSSIDListVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LANAdapterMacAddress, 42, LANAdapterMacAddressInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationID, 43, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationTitle, 44, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationVersion, 45, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationStorageLocation, 46, ApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(DownloadContentType, 47, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InstallContentType, 48, OccurrenceInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleStartingUpFlag, 49, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SystemStartingUpFlag, 50, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConsoleFirstInitFlag, 51, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HomeMenuScreenDisplayedFlag, 52, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataManagementScreenDisplayedFlag, 53, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ConnectionTestingFlag, 54, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationRunningFlag, 55, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(DataCorruptionDetectedFlag, 56, OccurrenceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ProductModel, 57, ProductModelInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentLanguage, 58, CurrentLanguageInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UseNetworkTimeProtocolFlag, 59, UseNetworkTimeProtocolInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TimeZone, 60, TimeZoneInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ControllerFirmware, 61, ControllerFirmwareInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(VideoOutputSetting, 62, VideoOutputInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDFreeSpace, 63, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SDCardFreeSpace, 64, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SerialNumber, 65, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(OsVersion, 66, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(ScreenBrightnessAutoAdjustFlag, 67, ScreenBrightnessInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HdmiAudioOutputMode, 68, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SpeakerAudioOutputMode, 69, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HeadphoneAudioOutputMode, 70, AudioFormatInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MuteOnHeadsetUnpluggedFlag, 71, MuteOnHeadsetUnpluggedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NumUserRegistered, 72, NumUserRegisteredInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(StorageAutoOrganizeFlag, 73, DataDeletionInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerVibrationVolume, 74, ControllerVibrationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LockScreenFlag, 75, LockScreenInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(InternalBatteryLotNumber, 76, InternalBatteryLotNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LeftControllerSerialNumber, 77, LeftControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RightControllerSerialNumber, 78, RightControllerSerialNumberInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NotifyInGameDownloadCompletionFlag, 79, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NotificationSoundFlag, 80, NotificationInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVResolutionSetting, 81, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RGBRangeSetting, 82, TVInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ReduceScreenBurnFlag, 83, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TVAllowsCecFlag, 84, TVInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(HandheldModeTimeToScreenSleep, 85, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ConsoleModeTimeToScreenSleep, 86, SleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(StopAutoSleepDuringContentPlayFlag, 87, SleepInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed, 88, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed, 89, ConnectionInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DEPRECATED_ServerFQDN, 90, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestContents, 91, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(HTTPRequestResponseContents, 92, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EdgeServerIPAddress, 93, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(UserAccountInternalID, 102, UserAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NetworkServiceAccountInternalID, 103, NetworkServiceAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoAccountInternalID, 104, NintendoAccountInternalIDInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(USB3AvailableFlag, 105, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(CallStack, 106, CallStackInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SystemStartupLog, 107, SystemStartupLogInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RegionSetting, 108, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NintendoZoneConnectedFlag, 109, NintendoZoneConnectedInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ForcedSleepHighTemperatureReading, 110, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepFanSpeedReading, 111, ForceSleepInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ForcedSleepHWInfo, 112, ForceSleepInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbnormalPowerStateInfo, 113, ChargerInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ScreenBrightnessLevel, 114, ScreenBrightnessInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ProgramId, 115, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AbortFlag, 116, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ReportVisibilityFlag, 117, ErrorInfoAuto, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatalFlag, 118, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OccurrenceTimestampNet, 119, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ResultBacktrace, 120, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch32, 121, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(StackBacktrace32, 122, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch32, 123, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GeneralRegisterAarch64, 124, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ExceptionInfoAarch64, 125, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(StackBacktrace64, 126, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(RegisterSetFlag32, 127, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RegisterSetFlag64, 128, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr32, 129, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ProgramMappedAddr64, 130, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AbortType, 131, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PrivateOsVersion, 132, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(CurrentSystemPowerState, 133, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PreviousSystemPowerState, 134, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DestinationSystemPowerState, 135, SystemPowerStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionCurrentState, 136, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscTransitionPreviousState, 137, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PscInitializedList, 138, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PscCurrentPmStateList, 139, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PscNextPmStateList, 140, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PerformanceMode, 141, PerformanceInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PerformanceConfiguration, 142, PerformanceInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(Throttled, 143, ThrottlingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ThrottlingDuration, 144, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ThrottlingTimestamp, 145, ThrottlingInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardCrcErrorCount, 146, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicCrcErrorCount, 147, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRefreshCount, 148, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadRetryCount, 149, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidBlock, 150, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock, 151, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(CreateProcessFailureFlag, 152, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CradleDp2HdmiFwVersion, 160, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningApplicationId, 161, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationTitle, 162, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersion, 163, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationStorageLocation, 164, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningAppletList, 165, RunningAppletInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(FocusedAppletHistory, 166, FocusedAppletHistoryInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(CompositorState, 167, CompositorStateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorLayerState, 168, CompositorLayerInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BatteryAge, 182, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerRole, 183, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyType, 184, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteFailures, 196, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDNumReadWriteErrorCorrections, 197, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDErrorLog, 198, NANDDriverLog, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardUserAreaSize, 199, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardProtectedAreaSize, 200, SdCardSizeSpec, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SdCardNumActivationFailures, 201, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumActivationErrorCorrections, 202, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteFailures, 203, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardNumReadWriteErrorCorrections, 204, SdCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardErrorLog, 205, SdCardDriverLog , FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptionKey, 206, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo, 207, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardTimeoutRetryErrorCount, 208, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptCount, 209, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRemountForDataCorruptRetryOutCount, 210, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertionCount, 211, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardRemovalCount, 212, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicInitializeCount, 213, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TestU16, 214, Test, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(TestU8, 215, Test, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TestI16, 216, Test, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(TestI8, 217, Test, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(SystemAppletScene, 218, SystemAppletSceneInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CodecType, 219, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DecodeBuffers, 220, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FrameWidth, 221, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FrameHeight, 222, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorPrimaries, 223, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(TransferCharacteristics, 224, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(MatrixCoefficients, 225, VideoInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(DisplayWidth, 226, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DisplayHeight, 227, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARWidth, 228, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(DARHeight, 229, VideoInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ColorFormat, 230, VideoInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(ColorSpace, 231, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SurfaceLayout, 232, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BitStream, 233, VideoInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(VideoDecState, 234, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GpuErrorChannelId, 235, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorAruId, 236, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorType, 237, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultInfo, 238, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorWriteAccess, 239, GpuErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(GpuErrorFaultAddress, 240, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorFaultUnit, 241, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorFaultType, 242, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorHwContextPointer, 243, GpuErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(GpuErrorContextStatus, 244, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaIntr, 245, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaErrorType, 246, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeaderShadow, 247, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaHeader, 248, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow0, 249, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureCount, 281, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAsicReinitializeFailureDetail, 282, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardRefreshSuccessCount, 283, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardAwakenCount, 284, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAwakenFailureCount, 285, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromInsert, 286, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardReadCountFromAwaken, 287, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageAddress, 288, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastReadErrorPageCount, 289, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AppletManagerContextTrace, 290, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispIsRegistered, 291, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispIsSuspend, 292, NvDispDeviceInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDC0SurfaceNum, 293, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispDC1SurfaceNum, 294, NvDispDeviceInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectX, 295, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectY, 296, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectWidth, 297, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSrcRectHeight, 298, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectX, 299, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectY, 300, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectWidth, 301, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDstRectHeight, 302, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowIndex, 303, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowBlendOperation, 304, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlphaOperation, 305, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowDepth, 306, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowAlpha, 307, NvDispDcWindowInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispWindowHFilter, 308, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowVFilter, 309, NvDispDcWindowInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispWindowOptions, 310, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispWindowSyncPointId, 311, NvDispDcWindowInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPSorPower, 312, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPClkType, 313, NvDispDpModeInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPEnable, 314, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPState, 315, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdid, 316, NvDispDpModeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDPEdidSize, 317, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPEdidExtSize, 318, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPFakeMode, 319, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPModeNumber, 320, NvDispDpModeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPPlugInOut, 321, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPAuxIntHandler, 322, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPForceMaxLinkBW, 323, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPIsConnected, 324, NvDispDpModeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkValid, 325, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxBW, 326, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkMaxLaneCount, 327, NvDispDpLinkSpec, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkDownSpread, 328, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportEnhancedFraming, 329, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBpp, 330, NvDispDpLinkSpec, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScaramberCap, 331, NvDispDpLinkSpec, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkBW, 332, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLaneCount, 333, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDPLinkEnhancedFraming, 334, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkScrambleEnable, 335, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActivePolarity, 336, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveCount, 337, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTUSize, 338, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkActiveFrac, 339, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkWatermark, 340, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkHBlank, 341, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkVBlank, 342, NvDispDpLinkStatus, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEnhancedFraming, 343, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkOnlyEdpCap, 344, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkSupportFastLT, 345, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkLTDataValid, 346, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkTsp3Support, 347, NvDispDpLinkStatus, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDPLinkAuxInterval, 348, NvDispDpLinkStatus, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpCreated, 349, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpUserRequest, 350, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpPlugged, 351, NvDispDpHdcpInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispHdcpState, 352, NvDispDpHdcpInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispHdcpFailCount, 353, NvDispDpHdcpInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispHdcpHdcp22, 354, NvDispDpHdcpInfo, FieldType_NumericI8, FieldFlag_None ) \ + HANDLER(NvDispHdcpMaxRetry, 355, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpHpd, 356, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispHdcpRepeater, 357, NvDispDpHdcpInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxBuf, 358, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecRxLength, 359, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxBuf, 360, NvDispDpAuxCecInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispCecTxLength, 361, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecTxRet, 362, NvDispDpAuxCecInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispCecState, 363, NvDispDpAuxCecInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispCecTxInfo, 364, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispCecRxInfo, 365, NvDispDpAuxCecInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDCIndex, 366, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCInitialize, 367, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCClock, 368, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCFrequency, 369, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCFailed, 370, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCModeWidth, 371, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeHeight, 372, NvDispDcInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(NvDispDCModeBpp, 373, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCPanelFrequency, 374, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinDirty, 375, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCWinEnable, 376, NvDispDcInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDCVrr, 377, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDCPanelInitialize, 378, NvDispDcInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDsiDataFormat, 379, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiVideoMode, 380, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiRefreshRate, 381, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiLpCmdModeFrequency, 382, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiHsCmdModeFrequency, 383, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPanelResetTimeout, 384, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiPhyFrequency, 385, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiFrequency, 386, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDsiInstance, 387, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHostCtrlEnable, 388, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiInit, 389, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnable, 390, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsMode, 391, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiVendorId, 392, NvDispDsiInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NvDispDcDsiLcdVendorNum, 393, NvDispDsiInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHsClockControl, 394, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiEnableHsClockInLpMode, 395, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiTeFrameUpdate, 396, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispDcDsiGangedType, 397, NvDispDsiInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispDcDsiHbpInPktSeq, 398, NvDispDsiInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NvDispErrID, 399, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData0, 400, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvDispErrData1, 401, NvDispErrIDInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SdCardMountStatus, 402, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SdCardMountUnexpectedResult, 403, SdCardMountInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSize, 404, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SdCardTotalSize, 405, SDCardFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceInitialLaunch, 406, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSincePowerOn, 407, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ElapsedTimeSinceLastAwake, 408, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(OccurrenceTick, 409, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(RetailInteractiveDisplayFlag, 410, RetailInteractiveDisplayInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FatFsError, 411, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsExtraError, 412, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorDrive, 413, FsProxyErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsErrorName, 414, FsProxyErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorManufactureCode, 415, MonitorCapability, FieldType_String, FieldFlag_None ) \ + HANDLER(MonitorProductCode, 416, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorSerialNumber, 417, MonitorCapability, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(MonitorManufactureYear, 418, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PhysicalAddress, 419, MonitorCapability, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(Is4k60Hz, 420, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is4k30Hz, 421, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is1080P60Hz, 422, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(Is720P60Hz, 423, MonitorCapability, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcmChannelMax, 424, MonitorCapability, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(CrashReportHash, 425, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorReportSharePermission, 426, ErrorReportSharePermissionInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(VideoCodecTypeEnum, 427, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoBitRate, 428, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoFrameRate, 429, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoWidth, 430, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(VideoHeight, 431, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioCodecTypeEnum, 432, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioSampleRate, 433, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioChannelCount, 434, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(AudioBitRate, 435, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaContainerType, 436, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaProfileType, 437, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaLevelType, 438, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaCacheSizeEnum, 439, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorStatusEnum, 440, MultimediaInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(MultimediaErrorLog, 441, MultimediaInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ServerFqdn, 442, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerIpAddress, 443, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestStringEncrypt, 444, Test, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(TestU8ArrayEncrypt, 445, Test, FieldType_U8Array, FieldFlag_Encrypt) \ + HANDLER(TestU32ArrayEncrypt, 446, Test, FieldType_U32Array, FieldFlag_Encrypt) \ + HANDLER(TestU64ArrayEncrypt, 447, Test, FieldType_U64Array, FieldFlag_Encrypt) \ + HANDLER(TestI32ArrayEncrypt, 448, Test, FieldType_I32Array, FieldFlag_Encrypt) \ + HANDLER(TestI64ArrayEncrypt, 449, Test, FieldType_I64Array, FieldFlag_Encrypt) \ + HANDLER(CipherKey, 450, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FileSystemPath, 451, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerOpenUrl, 452, ErrorInfo, FieldType_String, FieldFlag_Encrypt) \ + HANDLER(WebMediaPlayerLastSocketErrors, 453, ErrorInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(UnknownControllerCount, 454, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AttachedControllerCount, 455, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothControllerCount, 456, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbControllerCount, 457, ConnectedControllerInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ControllerTypeList, 458, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerInterfaceList, 459, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ControllerStyleList, 460, ConnectedControllerInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsPooledBufferPeakFreeSize, 461, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferRetriedCount, 462, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferReduceAllocationCount, 463, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakFreeSize, 464, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferManagerRetriedCount, 465, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsExpHeapPeakFreeSize, 466, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsBufferPoolPeakFreeSize, 467, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferSuccessCount, 468, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPatrolReadAllocateBufferFailureCount, 469, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SteadyClockInternalOffset, 470, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SteadyClockCurrentTimePointValue, 471, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextOffset, 472, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(UserClockContextTimeStampValue, 473, UserClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextOffset, 474, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NetworkClockContextTimeStampValue, 475, NetworkClockContextInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemAbortFlag, 476, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ApplicationAbortFlag, 477, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(NifmErrorCode, 478, ConnectionStatusInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsApplicationId, 479, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyIdList, 480, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyVersionList, 481, ErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyTypeList, 482, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsContentMetaKeyInstallTypeList, 483, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LcsSenderFlag, 484, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsApplicationRequestFlag, 485, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsHasExFatDriverFlag, 486, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LcsIpAddress, 487, ErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccount, 488, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAocRegistrationType, 489, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpAttributeFlag, 490, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpSupportedLanguageFlag, 491, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpParentalControlFlag, 492, AcpGeneralSettingsInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AcpScreenShot, 493, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpVideoCapture, 494, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpDataLossConfirmation, 495, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPlayLogPolicy, 496, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpPresenceGroupId, 497, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpRatingAge, 498, AcpRatingSettingsInfo, FieldType_I8Array, FieldFlag_None ) \ + HANDLER(AcpAocBaseId, 499, AcpAocSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpSaveDataOwnerId, 500, AcpStorageSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSize, 501, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSize, 502, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSize, 503, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSize, 504, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpBcatDeliveryCacheStorageSize, 505, AcpBcatSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpApplicationErrorCodeCategory, 506, AcpGeneralSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpLocalCommunicationId, 507, AcpGeneralSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpLogoType, 508, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpLogoHandling, 509, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRuntimeAocInstall, 510, AcpAocSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpCrashReport, 511, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpHdcp, 512, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpSeedForPseudoDeviceId, 513, AcpGeneralSettingsInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpBcatPassphrase, 514, AcpBcatSettingsInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataSizeMax, 515, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSaveDataJournalSizeMax, 516, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataSizeMax, 517, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpDeviceSaveDataJournalSizeMax, 518, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpTemporaryStorageSize, 519, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageSize, 520, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageJournalSize, 521, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageDataAndJournalSizeMax, 522, AcpStorageSettingsInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpCacheStorageIndexMax, 523, AcpStorageSettingsInfo, FieldType_NumericI16, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryableApplicationId, 524, AcpPlayLogSettingsInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpPlayLogQueryCapability, 525, AcpPlayLogSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AcpRepairFlag, 526, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningApplicationPatchStorageLocation, 527, RunningApplicationInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningApplicationVersionNumber, 528, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsRecoveredByInvalidateCacheCount, 529, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsSaveDataIndexCount, 530, FsProxyErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsBufferManagerPeakTotalAllocatableSize, 531, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(MonitorCurrentWidth, 532, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentHeight, 533, MonitorSettings, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(MonitorCurrentRefreshRate, 534, MonitorSettings, FieldType_String, FieldFlag_None ) \ + HANDLER(RebootlessSystemUpdateVersion, 535, RebootlessSystemUpdateVersionInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo1, 536, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Speed, 544, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort0ResetTimeInUs, 545, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0IrqCount, 546, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort0Statistics, 547, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePort1Flags, 548, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Speed, 549, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PciePort1ResetTimeInUs, 550, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1IrqCount, 551, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PciePort1Statistics, 552, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PcieFunction0VendorId, 553, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0DeviceId, 554, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction0PmState, 555, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction0IsAcquired, 556, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieFunction1VendorId, 557, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1DeviceId, 558, PcieLoggedStateInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(PcieFunction1PmState, 559, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PcieFunction1IsAcquired, 560, PcieLoggedStateInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PcieGlobalRootComplexStatistics, 561, PcieLoggedStateInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(PciePllResistorCalibrationValue, 562, PcieLoggedStateInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(CertificateRequestedHostName, 563, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateCommonName, 564, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CertificateSANCount, 565, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CertificateSANs, 566, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsBufferPoolMaxAllocateSize, 567, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateIssuerName, 568, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ApplicationAliveTime, 569, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationInFocusTime, 570, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationOutOfFocusTime, 571, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(ApplicationBackgroundFocusTime, 572, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(AcpUserAccountSwitchLock, 573, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(USB3HostAvailableFlag, 574, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(USB3DeviceAvailableFlag, 575, USB3AvailableInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationSendDataId, 576, AcpNeighborDetectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AcpNeighborDetectionClientConfigurationReceivableDataIds, 577, AcpNeighborDetectionInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(AcpStartupUserAccountOptionFlag, 578, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServerErrorCode, 579, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletManagerMetaLogTrace, 580, ErrorInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(ServerCertificateSerialNumber, 581, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificatePublicKeyAlgorithm, 582, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateSignatureAlgorithm, 583, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(ServerCertificateNotBefore, 584, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ServerCertificateNotAfter, 585, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(CertificateAlgorithmInfoBits, 586, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(TlsConnectionPeerIpAddress, 587, NetworkSecurityCertificateInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TlsConnectionLastHandshakeState, 588, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(TlsConnectionInfoBits, 589, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslStateBits, 590, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessInfoBits, 591, NetworkSecurityCertificateInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SslProcessHeapSize, 592, NetworkSecurityCertificateInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(SslBaseErrorCode, 593, NetworkSecurityCertificateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDumpSize, 594, GpuCrashInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GpuCrashDump, 595, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(RunningApplicationProgramIndex, 596, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(UsbTopology, 597, UsbStateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(AkamaiReferenceId, 598, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NvHostErrID, 599, NvHostErrInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NvHostErrDataArrayU32, 600, NvHostErrInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(HasSyslogFlag, 601, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AcpRuntimeParameterDelivery, 602, AcpGeneralSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PlatformRegion, 603, RegionSettingInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationId, 604, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaAppletId, 605, RunningUlaInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(RunningUlaVersion, 606, RunningUlaInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RunningUlaApplicationStorageLocation, 607, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(RunningUlaPatchStorageLocation, 608, RunningUlaInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(NANDTotalSizeOfSystem, 609, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(NANDFreeSpaceOfSystem, 610, NANDFreeSpaceInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AccessPointSSIDAsHex, 611, AccessPointInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(PanelVendorId, 612, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelRevisionId, 613, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PanelModelId, 614, InternalPanelInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ErrorContext, 615, ErrorInfoAuto, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ErrorContextSize, 616, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(ErrorContextTotalSize, 617, ErrorInfoAuto, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryLimit, 618, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountLimit, 619, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountLimit, 620, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountLimit, 621, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountLimit, 622, ResourceLimitLimitInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemPhysicalMemoryPeak, 623, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemThreadCountPeak, 624, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemEventCountPeak, 625, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemTransferMemoryCountPeak, 626, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(SystemSessionCountPeak, 627, ResourceLimitPeakInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GpuCrashHash, 628, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(TouchScreenPanelGpioValue, 629, TouchScreenInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BrowserCertificateHostName, 630, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateCommonName, 631, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(BrowserCertificateOrganizationalUnitName, 632, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FsPooledBufferFailedIdealAllocationCountOnAsyncAccess, 633, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(AudioOutputTarget, 634, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AudioOutputChannelCount, 635, AudioDeviceInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AppletTotalActiveTime, 636, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(WakeCount, 637, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(PredominantWakeReason, 638, AbnormalWakeInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock2, 639, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(EdidExtensionBlock3, 640, EdidInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(LumenRequestId, 641, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(LlnwLlid, 642, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(SupportingLimitedApplicationLicenses, 643, RunningApplicationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserDirectoryPeakOpenCount, 653, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardFilePeakOpenCount, 654, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardDirectoryPeakOpenCount, 655, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(SslAlertInfo, 656, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(SslVersionInfo, 657, NetworkSecurityCertificateInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueFileEntryPeakOpenCount, 658, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisSystemUniqueDirectoryEntryPeakOpenCount, 659, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueFileEntryPeakOpenCount, 660, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsBisUserUniqueDirectoryEntryPeakOpenCount, 661, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueFileEntryPeakOpenCount, 662, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(FatFsSdCardUniqueDirectoryEntryPeakOpenCount, 663, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ + HANDLER(ServerErrorIsRetryable, 664, ErrorInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(FsDeepRetryStartCount, 665, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(FsUnrecoverableByGameCardAccessFailedCount, 666, FsProxyErrorInfo2, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(BuiltInWirelessOUI, 667, BuiltInWirelessOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WirelessAPOUI, 668, WirelessAPOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(EthernetAdapterOUI, 669, EthernetAdapterOUIInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatSafeControlResult, 670, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatErrorNumber, 671, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisSystemFatSafeErrorNumber, 672, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatSafeControlResult, 673, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatErrorNumber, 674, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FatFsBisUserFatSafeErrorNumber, 675, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(GpuCrashDump2, 676, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDType, 677, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDType, 678, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardLastDeactivateReasonResult, 679, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastDeactivateReason, 680, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(InvalidErrorCode, 681, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizMode, 1003, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PowerSupplyPath, 1004, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquired, 1005, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequested, 1006, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(AdspExceptionRegisters, 1007, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsr, 1008, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegisters, 1009, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddress, 1010, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDump, 1011, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ diff --git a/utilities/erpt.py b/utilities/erpt.py index 12739661b..94d0919cd 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -238,6 +238,7 @@ CATEGORIES = { 139 : 'EthernetAdapterOUIInfo', 140 : 'NANDTypeInfo', 141 : 'MicroSDTypeInfo', + 1000 : 'TestNx', } FIELD_TYPES = { @@ -408,6 +409,14 @@ def find_flags(full, num_fields, magic_idx): ind = full.index(KNOWN) - magic_idx return list(up('<'+'B'*num_fields, full[ind:ind+num_fields])) +def find_id_array(full, num_fields, magic_idx, table_format): + if table_format == 0: + return list(range(num_fields)) + else: + KNOWN = pk(' Date: Thu, 28 Mar 2024 04:33:44 -0700 Subject: [PATCH 107/238] emummc: update for 18.0.0 --- emummc/README.md | 2 +- emummc/source/FS/FS_offsets.c | 8 ++++ emummc/source/FS/FS_versions.h | 3 ++ emummc/source/FS/offsets/1800.h | 59 +++++++++++++++++++++++++++ emummc/source/FS/offsets/1800_exfat.h | 59 +++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 emummc/source/FS/offsets/1800.h create mode 100644 emummc/source/FS/offsets/1800_exfat.h diff --git a/emummc/README.md b/emummc/README.md index 3b36a5a57..81e43f4b4 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 17.0.0** +**1.0.0 - 18.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index a1031a8bc..069f5d9d1 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -69,6 +69,8 @@ #include "offsets/1603_exfat.h" #include "offsets/1700.h" #include "offsets/1700_exfat.h" +#include "offsets/1800.h" +#include "offsets/1800_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -149,6 +151,8 @@ DEFINE_OFFSET_STRUCT(_1603); DEFINE_OFFSET_STRUCT(_1603_EXFAT); DEFINE_OFFSET_STRUCT(_1700); DEFINE_OFFSET_STRUCT(_1700_EXFAT); +DEFINE_OFFSET_STRUCT(_1800); +DEFINE_OFFSET_STRUCT(_1800_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -258,6 +262,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1700)); case FS_VER_17_0_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1700_EXFAT)); + case FS_VER_18_0_0: + return &(GET_OFFSET_STRUCT_NAME(_1800)); + case FS_VER_18_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_1800_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index 0459f9b9b..fc7011011 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -101,6 +101,9 @@ enum FS_VER FS_VER_17_0_0, FS_VER_17_0_0_EXFAT, + FS_VER_18_0_0, + FS_VER_18_0_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/1800.h b/emummc/source/FS/offsets/1800.h new file mode 100644 index 000000000..1b0513152 --- /dev/null +++ b/emummc/source/FS/offsets/1800.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1800_H__ +#define __FS_1800_H__ + +// Accessor vtable getters +#define FS_OFFSET_1800_SDMMC_ACCESSOR_GC 0x18AB00 +#define FS_OFFSET_1800_SDMMC_ACCESSOR_SD 0x18C800 +#define FS_OFFSET_1800_SDMMC_ACCESSOR_NAND 0x18AFE0 + +// Hooks +#define FS_OFFSET_1800_SDMMC_WRAPPER_READ 0x186A50 +#define FS_OFFSET_1800_SDMMC_WRAPPER_WRITE 0x186AB0 +#define FS_OFFSET_1800_RTLD 0x2A3A4 +#define FS_OFFSET_1800_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) + +#define FS_OFFSET_1800_CLKRST_SET_MIN_V_CLK_RATE 0x1A77D0 + +// Misc funcs +#define FS_OFFSET_1800_LOCK_MUTEX 0x17FCC0 +#define FS_OFFSET_1800_UNLOCK_MUTEX 0x17FD10 + +#define FS_OFFSET_1800_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186A10 +#define FS_OFFSET_1800_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186A30 + +// Misc Data +#define FS_OFFSET_1800_SD_MUTEX 0xFD13F0 +#define FS_OFFSET_1800_NAND_MUTEX 0xFCCB28 +#define FS_OFFSET_1800_ACTIVE_PARTITION 0xFCCB68 +#define FS_OFFSET_1800_SDMMC_DAS_HANDLE 0xFB1950 + +// NOPs +#define FS_OFFSET_1800_SD_DAS_INIT 0x28F24 + +// Nintendo Paths +#define FS_OFFSET_1800_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1800_H__ diff --git a/emummc/source/FS/offsets/1800_exfat.h b/emummc/source/FS/offsets/1800_exfat.h new file mode 100644 index 000000000..358c65f8f --- /dev/null +++ b/emummc/source/FS/offsets/1800_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1800_EXFAT_H__ +#define __FS_1800_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_1800_EXFAT_SDMMC_ACCESSOR_GC 0x195B90 +#define FS_OFFSET_1800_EXFAT_SDMMC_ACCESSOR_SD 0x197890 +#define FS_OFFSET_1800_EXFAT_SDMMC_ACCESSOR_NAND 0x196070 + +// Hooks +#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_READ 0x191AE0 +#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_WRITE 0x191B40 +#define FS_OFFSET_1800_EXFAT_RTLD 0x2A3A4 +#define FS_OFFSET_1800_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) + +#define FS_OFFSET_1800_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B2860 + +// Misc funcs +#define FS_OFFSET_1800_EXFAT_LOCK_MUTEX 0x18AD50 +#define FS_OFFSET_1800_EXFAT_UNLOCK_MUTEX 0x18ADA0 + +#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191AA0 +#define FS_OFFSET_1800_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191AC0 + +// Misc Data +#define FS_OFFSET_1800_EXFAT_SD_MUTEX 0xFE33F0 +#define FS_OFFSET_1800_EXFAT_NAND_MUTEX 0xFDEB28 +#define FS_OFFSET_1800_EXFAT_ACTIVE_PARTITION 0xFDEB68 +#define FS_OFFSET_1800_EXFAT_SDMMC_DAS_HANDLE 0xFBE950 + +// NOPs +#define FS_OFFSET_1800_EXFAT_SD_DAS_INIT 0x28F24 + +// Nintendo Paths +#define FS_OFFSET_1800_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1800_EXFAT_H__ From 551821e7e2366805ab6d00f0770a7a107ae3cf55 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 04:36:14 -0700 Subject: [PATCH 108/238] erpt: actually support non-sequential ids, nintendo why --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 30 +++---- .../include/stratosphere/erpt/erpt_types.hpp | 2 - .../stratosphere/erpt/srv/erpt_srv_types.hpp | 78 ++++++++++++++++--- .../erpt/srv/erpt_srv_context_record.cpp | 6 +- .../source/erpt/srv/erpt_srv_formatter.hpp | 5 +- .../source/erpt/srv/erpt_srv_main.cpp | 4 +- .../source/erpt/srv/erpt_srv_reporter.cpp | 2 +- 7 files changed, 91 insertions(+), 36 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index cb3d3173a..92d6db7dc 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -35,7 +35,7 @@ HANDLER(FieldType_NumericU8, 12) \ HANDLER(FieldType_NumericI16, 13) \ HANDLER(FieldType_NumericI8, 14) \ - HANDLER(FieldType_I8Array, 15) \ + HANDLER(FieldType_I8Array, 15) #define AMS_ERPT_FOREACH_CATEGORY(HANDLER) \ HANDLER(Test, 0 ) \ @@ -180,7 +180,7 @@ HANDLER(EthernetAdapterOUIInfo, 139 ) \ HANDLER(NANDTypeInfo, 140 ) \ HANDLER(MicroSDTypeInfo, 141 ) \ - HANDLER(TestNx, 1000) \ + HANDLER(TestNx, 1000) #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ @@ -355,13 +355,13 @@ HANDLER(CompositorDisplayState, 169, CompositorDisplayInfo, FieldType_String, FieldFlag_None ) \ HANDLER(CompositorHWCState, 170, CompositorHWCInfo, FieldType_String, FieldFlag_None ) \ HANDLER(InputCurrentLimit, 171, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(BoostModeCurrentLimit, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(BoostModeCurrentLimitDeprecated, 172, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FastChargeCurrentLimit, 173, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeVoltageLimit, 174, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(ChargeConfiguration, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(HizMode, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ChargeConfigurationDeprecated, 175, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(HizModeDeprecated, 176, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(ChargeEnabled, 177, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(PowerSupplyPath, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PowerSupplyPathDeprecated, 178, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BatteryTemperature, 179, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BatteryChargePercent, 180, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(BatteryChargeVoltage, 181, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -371,8 +371,8 @@ HANDLER(PowerSupplyVoltage, 185, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(PowerSupplyCurrent, 186, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(ControllerPowerSupplyAcquired, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(OtgRequested, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ControllerPowerSupplyAcquiredDeprecated, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(OtgRequestedDeprecated, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ @@ -436,15 +436,15 @@ HANDLER(GpuErrorPbdmaGpShadow1, 250, GpuErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AccessPointChannel, 251, AccessPointInfo, FieldType_NumericU16, FieldFlag_None ) \ HANDLER(ThreadName, 252, ErrorInfo, FieldType_String, FieldFlag_None ) \ - HANDLER(AdspExceptionRegisters, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionSpsr, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionRegistersDeprecated, 253, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionSpsrDeprecated, 254, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionProgramCounter, 255, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionLinkRegister, 256, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackPointer, 257, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionArmModeRegisters, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionStackAddress, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(AdspExceptionStackDump, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionArmModeRegistersDeprecated, 258, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ @@ -877,5 +877,5 @@ HANDLER(AdspExceptionArmModeRegisters, 1009, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionStackAddress, 1010, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackDump, 1011, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp index 858919f4b..3d31b2c42 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_types.hpp @@ -34,7 +34,6 @@ namespace ams::erpt { enum CategoryId { AMS_ERPT_FOREACH_CATEGORY(GENERATE_ENUM) - CategoryId_Count, }; #undef GENERATE_ENUM @@ -43,7 +42,6 @@ namespace ams::erpt { enum FieldId { AMS_ERPT_FOREACH_FIELD(GENERATE_ENUM) - FieldId_Count, }; #undef GENERATE_ENUM diff --git a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp index a4604743b..348f3cb5f 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/srv/erpt_srv_types.hpp @@ -58,34 +58,88 @@ namespace ams::erpt::srv { }; #undef STRINGIZE_HANDLER - #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = CategoryId_##CATEGORY, - constexpr inline const CategoryId FieldToCategoryMap[] = { + #define GET_FIELD_CATEGORY(FIELD, ID, CATEGORY, TYPE, FLAG) CategoryId_##CATEGORY, + constexpr inline const CategoryId FieldIndexToCategoryMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_CATEGORY) }; #undef GET_FIELD_CATEGORY - #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = TYPE, - constexpr inline const FieldType FieldToTypeMap[] = { + #define GET_FIELD_TYPE(FIELD, ID, CATEGORY, TYPE, FLAG) TYPE, + constexpr inline const FieldType FieldIndexToTypeMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_TYPE) }; #undef GET_FIELD_TYPE - #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) [FieldId_##FIELD] = FLAG, - constexpr inline const FieldFlag FieldToFlagMap[] = { + #define GET_FIELD_FLAG(FIELD, ID, CATEGORY, TYPE, FLAG) FLAG, + constexpr inline const FieldFlag FieldIndexToFlagMap[] = { AMS_ERPT_FOREACH_FIELD(GET_FIELD_FLAG) }; #undef GET_FIELD_FLAG - inline CategoryId ConvertFieldToCategory(FieldId id) { - return FieldToCategoryMap[id]; + #define GET_FIELD_ID(FIELD, ...) FieldId_##FIELD, + constexpr inline const FieldId FieldIndexToFieldIdMap[] = { + AMS_ERPT_FOREACH_FIELD(GET_FIELD_ID) + }; + #undef GET_FIELD_ID + + #define GET_CATEGORY_ID(CATEGORY, ...) CategoryId_##CATEGORY, + constexpr inline const CategoryId CategoryIndexToCategoryIdMap[] = { + AMS_ERPT_FOREACH_CATEGORY(GET_CATEGORY_ID) + }; + #undef GET_CATEGORY_ID + + constexpr util::optional FindFieldIndex(FieldId id) { + if (std::is_constant_evaluated()) { + for (size_t i = 0; i < util::size(FieldIndexToFieldIdMap); ++i) { + if (FieldIndexToFieldIdMap[i] == id) { + return i; + } + } + + return util::nullopt; + } else { + if (const auto it = std::lower_bound(std::begin(FieldIndexToFieldIdMap), std::end(FieldIndexToFieldIdMap), id); it != std::end(FieldIndexToFieldIdMap) && *it == id) { + return std::distance(FieldIndexToFieldIdMap, it); + } else { + return util::nullopt; + } + } } - inline FieldType ConvertFieldToType(FieldId id) { - return FieldToTypeMap[id]; + constexpr util::optional FindCategoryIndex(CategoryId id) { + if (std::is_constant_evaluated()) { + for (size_t i = 0; i < util::size(CategoryIndexToCategoryIdMap); ++i) { + if (CategoryIndexToCategoryIdMap[i] == id) { + return i; + } + } + + return util::nullopt; + } else { + if (const auto it = std::lower_bound(std::begin(CategoryIndexToCategoryIdMap), std::end(CategoryIndexToCategoryIdMap), id); it != std::end(CategoryIndexToCategoryIdMap) && *it == id) { + return std::distance(CategoryIndexToCategoryIdMap, it); + } else { + return util::nullopt; + } + } } - inline FieldFlag ConvertFieldToFlag(FieldId id) { - return FieldToFlagMap[id]; + constexpr inline CategoryId ConvertFieldToCategory(FieldId id) { + const auto index = FindFieldIndex(id); + AMS_ASSERT(index.has_value()); + return FieldIndexToCategoryMap[index.value()]; + } + + constexpr inline FieldType ConvertFieldToType(FieldId id) { + const auto index = FindFieldIndex(id); + AMS_ASSERT(index.has_value()); + return FieldIndexToTypeMap[index.value()]; + } + + constexpr inline FieldFlag ConvertFieldToFlag(FieldId id) { + const auto index = FindFieldIndex(id); + AMS_ASSERT(index.has_value()); + return FieldIndexToFlagMap[index.value()]; } constexpr inline ReportFlagSet MakeNoReportFlags() { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp index 1d2b4681b..23dde0b33 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_record.cpp @@ -69,13 +69,13 @@ namespace ams::erpt::srv { auto guard = SCOPE_GUARD { m_ctx.field_count = 0; }; - R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); - R_UNLESS(0 <= m_ctx.category && m_ctx.category < CategoryId_Count, erpt::ResultInvalidArgument()); + R_UNLESS(m_ctx.field_count <= FieldsPerContext, erpt::ResultInvalidArgument()); + R_UNLESS(FindCategoryIndex(m_ctx.category).has_value(), erpt::ResultInvalidArgument()); for (u32 i = 0; i < m_ctx.field_count; i++) { m_ctx.fields[i] = ctx_ptr->fields[i]; - R_UNLESS(0 <= m_ctx.fields[i].id && m_ctx.fields[i].id < FieldId_Count, erpt::ResultInvalidArgument()); + R_UNLESS(FindFieldIndex(m_ctx.fields[i].id).has_value(), erpt::ResultInvalidArgument()); R_UNLESS(0 <= m_ctx.fields[i].type && m_ctx.fields[i].type < FieldType_Count, erpt::ResultInvalidArgument()); R_UNLESS(m_ctx.fields[i].type == ConvertFieldToType(m_ctx.fields[i].id), erpt::ResultFieldTypeMismatch()); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp index b50712be3..fcdb4836a 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_formatter.hpp @@ -62,7 +62,10 @@ namespace ams::erpt::srv { static Result AddId(Report *report, FieldId field_id) { static_assert(MaxFieldStringSize < ElementSize_256); - R_TRY(AddStringValue(report, FieldString[field_id], strnlen(FieldString[field_id], MaxFieldStringSize))); + const auto index = FindFieldIndex(field_id); + AMS_ASSERT(index.has_value()); + + R_TRY(AddStringValue(report, FieldString[index.value()], strnlen(FieldString[index.value()], MaxFieldStringSize))); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp index 6f23bde32..8fb682244 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_main.cpp @@ -105,8 +105,8 @@ namespace ams::erpt::srv { g_sf_allocator.Attach(g_heap_handle); - for (auto i = 0; i < CategoryId_Count; i++) { - Context *ctx = new Context(static_cast(i)); + for (const auto category_id : CategoryIndexToCategoryIdMap) { + Context *ctx = new Context(category_id); AMS_ABORT_UNLESS(ctx != nullptr); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index afe0ce1fa..274f9d5ab 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -277,7 +277,7 @@ namespace ams::erpt::srv { void SaveSyslogReportIfRequired(const ContextEntry *ctx, const ReportId &report_id) { bool needs_save_syslog = true; for (u32 i = 0; i < ctx->field_count; i++) { - static_assert(FieldToTypeMap[FieldId_HasSyslogFlag] == FieldType_Bool); + static_assert(FieldIndexToTypeMap[*FindFieldIndex(FieldId_HasSyslogFlag)] == FieldType_Bool); if (ctx->fields[i].id == FieldId_HasSyslogFlag && !ctx->fields[i].value_bool) { needs_save_syslog = false; break; From af4127259163dd3afe126a5a506c67910a1817f8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 04:43:07 -0700 Subject: [PATCH 109/238] spl: add support for new spl:es command 33 --- .../include/stratosphere/spl/impl/spl_api_impl.hpp | 1 + .../include/stratosphere/spl/impl/spl_es_interface.hpp | 3 ++- libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp | 4 ++++ stratosphere/spl/source/spl_es_service.hpp | 4 ++++ stratosphere/spl/source/spl_secure_monitor_manager.cpp | 4 ++++ stratosphere/spl/source/spl_secure_monitor_manager.hpp | 1 + 6 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp index db2354329..1a79d67b1 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_api_impl.hpp @@ -70,6 +70,7 @@ namespace ams::spl::impl { Result ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size); Result PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); Result LoadPreparedAesKey(s32 keyslot, const AccessKey &access_key); + Result PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); /* FS */ Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option); diff --git a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp index 0fda18172..237c3124e 100644 --- a/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/spl/impl/spl_es_interface.hpp @@ -28,6 +28,7 @@ AMS_SF_METHOD_INFO(C, H, 28, Result, DecryptAndStoreDrmDeviceCertKey, (const sf::InPointerBuffer &src, spl::AccessKey access_key, spl::KeySource key_source), (src, access_key, key_source), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 29, Result, ModularExponentiateWithDrmDeviceCertKey, (const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod), (out, base, mod), hos::Version_5_0_0) \ AMS_SF_METHOD_INFO(C, H, 31, Result, PrepareEsArchiveKey, (sf::Out out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation), (out_access_key, base, mod, label_digest, generation), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 32, Result, LoadPreparedAesKey, (s32 keyslot, spl::AccessKey access_key), (keyslot, access_key), hos::Version_6_0_0) + AMS_SF_METHOD_INFO(C, H, 32, Result, LoadPreparedAesKey, (s32 keyslot, spl::AccessKey access_key), (keyslot, access_key), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 33, Result, PrepareEsUnknown2Key, (sf::Out out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation), (out_access_key, base, mod, label_digest, generation), hos::Version_18_0_0) AMS_SF_DEFINE_INTERFACE_WITH_BASE(ams::spl::impl, IEsInterface, ::ams::spl::impl::IDeviceUniqueDataInterface, AMS_SPL_I_ES_INTERFACE_INTERFACE_INFO, 0x346D5001) diff --git a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp index acec07407..c5c450b1b 100644 --- a/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp +++ b/libraries/libstratosphere/source/spl/impl/spl_api_impl.cpp @@ -893,6 +893,10 @@ namespace ams::spl::impl { R_RETURN(PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, smc::EsDeviceUniqueKeyType::ArchiveKey, generation)); } + Result PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) { + R_RETURN(PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, smc::EsDeviceUniqueKeyType::Unknown2, generation)); + } + /* FS */ Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) { R_RETURN(DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, option)); diff --git a/stratosphere/spl/source/spl_es_service.hpp b/stratosphere/spl/source/spl_es_service.hpp index a4cba97f6..57943ec24 100644 --- a/stratosphere/spl/source/spl_es_service.hpp +++ b/stratosphere/spl/source/spl_es_service.hpp @@ -55,6 +55,10 @@ namespace ams::spl { Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key) { R_RETURN(m_manager.LoadPreparedAesKey(keyslot, this, access_key)); } + + Result PrepareEsUnknown2Key(sf::Out out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) { + R_RETURN(m_manager.PrepareEsUnknown2Key(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation)); + } }; static_assert(spl::impl::IsIEsInterface); diff --git a/stratosphere/spl/source/spl_secure_monitor_manager.cpp b/stratosphere/spl/source/spl_secure_monitor_manager.cpp index e5b899169..c31bae8bf 100644 --- a/stratosphere/spl/source/spl_secure_monitor_manager.cpp +++ b/stratosphere/spl/source/spl_secure_monitor_manager.cpp @@ -121,6 +121,10 @@ namespace ams::spl { R_RETURN(impl::PrepareEsArchiveKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation)); } + Result SecureMonitorManager::PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) { + R_RETURN(impl::PrepareEsUnknown2Key(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation)); + } + Result SecureMonitorManager::PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) { R_RETURN(impl::PrepareCommonEsTitleKey(out_access_key, key_source, generation)); } diff --git a/stratosphere/spl/source/spl_secure_monitor_manager.hpp b/stratosphere/spl/source/spl_secure_monitor_manager.hpp index f54ff5da0..c01311ef3 100644 --- a/stratosphere/spl/source/spl_secure_monitor_manager.hpp +++ b/stratosphere/spl/source/spl_secure_monitor_manager.hpp @@ -52,6 +52,7 @@ namespace ams::spl { Result LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option); Result PrepareEsTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); Result PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); + Result PrepareEsUnknown2Key(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation); Result PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation); Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key); Result AllocateAesKeySlot(s32 *out_keyslot, const void *owner); From a325e18cb566ae071b6fc11b1f554151e8f3410e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 28 Mar 2024 09:55:38 -0700 Subject: [PATCH 110/238] loader: add usb3 patches for 18.0.0 --- stratosphere/loader/source/ldr_embedded_usb_patches.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index f655c6a94..4ae97c2ec 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -59,6 +59,11 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_17_0_0[] = { { 0x71EC, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_18_0_0[] = { + { 0x6DCC, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x6E48, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 }, @@ -70,4 +75,5 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("30B15A83E94D91750E7470795414AD1AE9C6A8DB"), util::size(Usb30ForceEnablePatches_15_0_0), Usb30ForceEnablePatches_15_0_0 }, /* 15.0.0 */ { ParseModuleId("225865A442B4B66E8BD14B3E9450B901BDF29A40"), util::size(Usb30ForceEnablePatches_16_0_0), Usb30ForceEnablePatches_16_0_0 }, /* 16.0.0 */ { ParseModuleId("70D4C2ABCD049F16B301186924367F813DA70248"), util::size(Usb30ForceEnablePatches_17_0_0), Usb30ForceEnablePatches_17_0_0 }, /* 17.0.0 */ + { ParseModuleId("4F21AE15E814FA46515C0401BB23D4F7ADCBF3F4"), util::size(Usb30ForceEnablePatches_18_0_0), Usb30ForceEnablePatches_18_0_0 }, /* 18.0.0 */ }; From 4f7db6e60ec343a38b9b9d91b1da910ab4c2fee7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Mar 2024 02:54:40 -0700 Subject: [PATCH 111/238] docs: add changelog for 1.7.0 --- docs/changelog.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 6a49e1901..ebd2344ef 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,25 @@ # Changelog +## 1.7.0 ++ Basic support was added for 18.0.0. + + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. + + There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update, once I am not traveling so much. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + `spl` was updated to reflect the latest official behavior. ++ `fusee`'s no longer supports applying IPS patches to KIPs. + + The only KIPs that are ever present are a) atmosphère modules, b) custom system modules, or c) FS. + + The IPS subsystem was originally designed to make nogc patches work for FS, but these are now internal, and it appears the literal only kip patches that exist are for piracy. + + I could not find any kip patches posted anywhere made for any other purpose. + + It fundamentally does not make sense to slow down boot for every normal user for a feature that has no actual use-case, especially when `fusee` seeks to be a minimal bootloader. ++ Minor improvements were made to atmosphere's gdbstub, including: + + Support was added for QStartNoAckMode. + + An issue was fixed that could cause a fatal error when creating too many breakpoints. ++ A number of minor issues were fixed and improvements were made, including: + + `pt-BR` (`PortugueseBr`) is now accepted as a valid language when overriding game locales. + + A bug was fixed that could cause atmosphere to incorrectly serialize output object IDs over IPC when using domain objects. + + A bug was fixed in `pm`'s resource limit boost logic that could potentially cause legitimate boosts to fail in certain circumstances. + + `loader`/`ro` will now throw a fatal error when using invalid IPS patches that go out of bounds, instead of corrupting memory. ++ General system stability improvements to enhance the user's experience. ## 1.6.2 + Support was finished for 17.0.0. + `erpt` was updated to support the latest official behavior. From 3ccb0ae02bc06769f44d61233bf177301ba9d5f3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Mar 2024 02:56:10 -0700 Subject: [PATCH 112/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "8b85add71" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "8b85add71" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 67a7451a7..f0484ffab 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = bfc55834869fe24f8d94550bc6909a65ae7d35c2 - parent = 742fd16080bce8cd664d6244304a771f82e8aa04 + commit = 8b85add711f965e3ceeed043cf8648634fe7d8a2 + parent = 4f7db6e60ec343a38b9b9d91b1da910ab4c2fee7 method = merge cmdver = 0.4.1 From 31ad4eec1ddea80180469dd431a8a2b6fe6e73f6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Mar 2024 02:57:53 -0700 Subject: [PATCH 113/238] git subrepo push emummc subrepo: subdir: "emummc" merged: "832b24426" upstream: origin: "https://github.com/m4xw/emummc" branch: "develop" commit: "832b24426" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- emummc/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index 9cf888ba6..0aab4ee6e 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = 9513a5412057b1f1bc44ed8e717c57c726763a88 - parent = e4d08ae0c5342cdb0875d164522a63ec9d233052 + commit = 832b2442685b45b086697ffe09c5fde05d7444e9 + parent = 3ccb0ae02bc06769f44d61233bf177301ba9d5f3 method = merge cmdver = 0.4.1 From 29cc13543ae4eaa7e92a8e8efc35d75ea404d6bc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Mar 2024 03:18:20 -0700 Subject: [PATCH 114/238] kern: fix using memory config for half-of-true-size --- libraries/libmesosphere/source/kern_k_system_control_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index 8412fbf75..fe0b56996 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -39,7 +39,7 @@ namespace ams::kern { KPhysicalAddress KSystemControlBase::Init::GetKernelPhysicalBaseAddress(KPhysicalAddress base_address) { const size_t real_dram_size = KSystemControl::Init::GetRealMemorySize(); const size_t intended_dram_size = KSystemControl::Init::GetIntendedMemorySize(); - if (intended_dram_size * 2 < real_dram_size) { + if (intended_dram_size * 2 <= real_dram_size) { return base_address; } else { return base_address + ((real_dram_size - intended_dram_size) / 2); From 410f23035efeb9e1bd399a020334793bba95bf91 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Mar 2024 03:19:17 -0700 Subject: [PATCH 115/238] docs: update changelog for 1.7.0 --- docs/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.md b/docs/changelog.md index ebd2344ef..1532855a4 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,6 +19,7 @@ + A bug was fixed that could cause atmosphere to incorrectly serialize output object IDs over IPC when using domain objects. + A bug was fixed in `pm`'s resource limit boost logic that could potentially cause legitimate boosts to fail in certain circumstances. + `loader`/`ro` will now throw a fatal error when using invalid IPS patches that go out of bounds, instead of corrupting memory. + + Support was fixed for booting using a memory configuration of half of the true available memory (e.g. forcing a 4GB configuration on an 8GB board). + General system stability improvements to enhance the user's experience. ## 1.6.2 + Support was finished for 17.0.0. From 35d93a7c4188cda103957aa757fd31f9fe7d18cb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 29 Mar 2024 03:20:12 -0700 Subject: [PATCH 116/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "fadec2981" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "fadec2981" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index f0484ffab..c1120c7e7 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 8b85add711f965e3ceeed043cf8648634fe7d8a2 - parent = 4f7db6e60ec343a38b9b9d91b1da910ab4c2fee7 + commit = fadec2981727636ec7ba81d6c83995b7b9782190 + parent = 410f23035efeb9e1bd399a020334793bba95bf91 method = merge cmdver = 0.4.1 From 548b48b2a6351ecf8e373f0789be1cf38509df8d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 27 May 2024 15:43:58 -0700 Subject: [PATCH 117/238] loader: update to reflect latest 18.0.0 changes well, this sure is late, whoops --- .../fssystem_crypto_configuration.hpp | 8 +- .../stratosphere/ldr/ldr_platform_id.hpp | 27 +++++ .../include/stratosphere/ldr/ldr_types.hpp | 2 + .../fssystem_crypto_configuration.cpp | 44 ++++++-- .../vapours/results/loader_results.hpp | 2 + .../loader/source/ldr_content_management.cpp | 35 ++++-- .../loader/source/ldr_content_management.hpp | 20 ++-- .../loader/source/ldr_loader_service.cpp | 102 ++++++++++-------- stratosphere/loader/source/ldr_meta.cpp | 50 +++++---- stratosphere/loader/source/ldr_meta.hpp | 4 +- .../loader/source/ldr_process_creation.cpp | 59 +++++++--- .../loader/source/ldr_process_creation.hpp | 4 +- 12 files changed, 240 insertions(+), 117 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp index 4ca3316e2..90f2ccdb0 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp @@ -16,6 +16,7 @@ #pragma once #include #include +#include namespace ams::fssystem { @@ -25,10 +26,13 @@ namespace ams::fssystem { void InvalidateHardwareAesKey(); - const u8 *GetAcidSignatureKeyModulus(bool prod, size_t key_generation); + bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation); + + const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused); + size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused); + const u8 *GetAcidSignatureKeyPublicExponent(); - constexpr inline size_t AcidSignatureKeyModulusSize = NcaCryptoConfiguration::Rsa2048KeyModulusSize; constexpr inline size_t AcidSignatureKeyPublicExponentSize = NcaCryptoConfiguration::Rsa2048KeyPublicExponentSize; } diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp new file mode 100644 index 000000000..884cd0945 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +namespace ams::ldr { + + /* TODO: Is this really a FS type? What namespace does this actually live inside? */ + enum PlatformId { + PlatformId_Nx = 0, + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index 328957aae..325d2a35d 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace ams::ldr { @@ -224,6 +225,7 @@ namespace ams::ldr { MetaFlag_OptimizeMemoryAllocation = (1 << 4), MetaFlag_DisableDeviceAddressSpaceMerge = (1 << 5), + MetaFlag_EnableAliasRegionExtraSize = (1 << 6), }; enum AddressSpaceType { diff --git a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp index 4575a0df4..dbd2f86cd 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp @@ -22,9 +22,11 @@ namespace ams::fssystem { constexpr inline const size_t KeySize = crypto::AesDecryptor128::KeySize; - constexpr inline const size_t AcidSignatureKeyGenerationMax = 1; + constexpr inline const size_t NxAcidSignatureKeyGenerationMax = 1; - constexpr inline const u8 AcidSignatureKeyModulusDev[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = { + constexpr inline const size_t NxAcidSignatureKeyModulusSize = NcaCryptoConfiguration::Rsa2048KeyModulusSize; + + constexpr inline const u8 NxAcidSignatureKeyModulusDev[NxAcidSignatureKeyGenerationMax + 1][NxAcidSignatureKeyModulusSize] = { { 0xD6, 0x34, 0xA5, 0x78, 0x6C, 0x68, 0xCE, 0x5A, 0xC2, 0x37, 0x17, 0xF3, 0x82, 0x45, 0xC6, 0x89, 0xE1, 0x2D, 0x06, 0x67, 0xBF, 0xB4, 0x06, 0x19, 0x55, 0x6B, 0x27, 0x66, 0x0C, 0xA4, 0xB5, 0x87, @@ -63,7 +65,7 @@ namespace ams::fssystem { } }; - constexpr inline const u8 AcidSignatureKeyModulusProd[AcidSignatureKeyGenerationMax + 1][AcidSignatureKeyModulusSize] = { + constexpr inline const u8 NxAcidSignatureKeyModulusProd[NxAcidSignatureKeyGenerationMax + 1][NxAcidSignatureKeyModulusSize] = { { 0xDD, 0xC8, 0xDD, 0xF2, 0x4E, 0x6D, 0xF0, 0xCA, 0x9E, 0xC7, 0x5D, 0xC7, 0x7B, 0xAD, 0xFE, 0x7D, 0x23, 0x89, 0x69, 0xB6, 0xF2, 0x06, 0xA2, 0x02, 0x88, 0xE1, 0x55, 0x91, 0xAB, 0xCB, 0x4D, 0x50, @@ -102,7 +104,7 @@ namespace ams::fssystem { } }; - static_assert(sizeof(AcidSignatureKeyModulusProd) == sizeof(AcidSignatureKeyModulusDev)); + static_assert(sizeof(NxAcidSignatureKeyModulusProd) == sizeof(NxAcidSignatureKeyModulusDev)); constexpr inline const u8 AcidSignatureKeyPublicExponent[] = { 0x01, 0x00, 0x01 @@ -295,10 +297,36 @@ namespace ams::fssystem { } } - const u8 *GetAcidSignatureKeyModulus(bool prod, size_t key_generation) { - AMS_ASSERT(key_generation <= AcidSignatureKeyGenerationMax); - const size_t used_keygen = (key_generation % (AcidSignatureKeyGenerationMax + 1)); - return prod ? AcidSignatureKeyModulusProd[used_keygen] : AcidSignatureKeyModulusDev[used_keygen]; + bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation) { + switch (platform) { + case ldr::PlatformId_Nx: + return key_generation <= NxAcidSignatureKeyGenerationMax; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused) { + AMS_ASSERT(IsValidSignatureKeyGeneration(platform, key_generation)); + AMS_UNUSED(unk_unused); + + switch (platform) { + case ldr::PlatformId_Nx: + { + const size_t used_keygen = (key_generation % (NxAcidSignatureKeyGenerationMax + 1)); + return prod ? NxAcidSignatureKeyModulusProd[used_keygen] : NxAcidSignatureKeyModulusDev[used_keygen]; + } + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + + size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused) { + AMS_UNUSED(unk_unused); + + switch (platform) { + case ldr::PlatformId_Nx: + return NxAcidSignatureKeyModulusSize; + AMS_UNREACHABLE_DEFAULT_CASE(); + } } const u8 *GetAcidSignatureKeyPublicExponent() { diff --git a/libraries/libvapours/include/vapours/results/loader_results.hpp b/libraries/libvapours/include/vapours/results/loader_results.hpp index 825be3784..d9cfa62b5 100644 --- a/libraries/libvapours/include/vapours/results/loader_results.hpp +++ b/libraries/libvapours/include/vapours/results/loader_results.hpp @@ -34,6 +34,8 @@ namespace ams::ldr { R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11); R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12); + R_DEFINE_ERROR_RESULT(InvalidPlatformId, 14); + R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 51); R_DEFINE_ERROR_RESULT(InvalidNroImage, 52); R_DEFINE_ERROR_RESULT(InvalidNrrImage, 53); diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index 75260f0b7..2a704bcd5 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -25,12 +25,12 @@ namespace ams::ldr { } /* ScopedCodeMount functionality. */ - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { - m_result = this->Initialize(loc); + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + m_result = this->Initialize(loc, platform); } - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { - m_result = this->Initialize(loc); + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + m_result = this->Initialize(loc, platform); } ScopedCodeMount::~ScopedCodeMount() { @@ -46,25 +46,28 @@ namespace ams::ldr { } } - Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc) { + Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, PlatformId platform) { /* Capture override status, if necessary. */ this->EnsureOverrideStatus(loc); AMS_ABORT_UNLESS(m_has_status); /* Get the content path. */ char content_path[fs::EntryNameLengthMax + 1]; - R_TRY(GetProgramPath(content_path, sizeof(content_path), loc)); + R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, platform)); + + /* Get the content attributes. */ + const auto content_attributes = GetPlatformContentAttributes(platform); /* Mount the atmosphere code file system. */ - R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, fs::ContentAttributes_None, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); + R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); m_mounted_ams = true; /* Mount the sd or base code file system. */ - R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, fs::ContentAttributes_None, loc.program_id)); + R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id)); m_mounted_sd_or_code = true; /* Mount the base code file system. */ - if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, fs::ContentAttributes_None, loc.program_id))) { + if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id))) { m_mounted_code = true; } @@ -80,7 +83,7 @@ namespace ams::ldr { } /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc) { + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform) { /* Check for storage id none. */ if (static_cast(loc.storage_id) == ncm::StorageId::None) { std::memset(out_path, 0, out_size); @@ -88,6 +91,10 @@ namespace ams::ldr { R_SUCCEED(); } + /* Get the content attributes. */ + const auto content_attributes = GetPlatformContentAttributes(platform); + AMS_UNUSED(content_attributes); + lr::Path path; /* Check that path registration is allowable. */ @@ -159,4 +166,12 @@ namespace ams::ldr { R_SUCCEED(); } + fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform) { + switch (platform) { + case PlatformId_Nx: + return fs::ContentAttributes_None; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + } diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index f2163776f..bc5848826 100644 --- a/stratosphere/loader/source/ldr_content_management.hpp +++ b/stratosphere/loader/source/ldr_content_management.hpp @@ -34,8 +34,8 @@ namespace ams::ldr { bool m_mounted_sd_or_code; bool m_mounted_code; public: - ScopedCodeMount(const ncm::ProgramLocation &loc); - ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); + ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform); + ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, PlatformId platform); ~ScopedCodeMount(); Result GetResult() const { @@ -59,21 +59,27 @@ namespace ams::ldr { return m_base_code_verification_data; } private: - Result Initialize(const ncm::ProgramLocation &loc); + Result Initialize(const ncm::ProgramLocation &loc, PlatformId platform); void EnsureOverrideStatus(const ncm::ProgramLocation &loc); }; - constexpr inline const char * const AtmosphereCodeMountName = "ams-code"; - constexpr inline const char * const SdOrCodeMountName = "sd-code"; - constexpr inline const char * const CodeMountName = "code"; + constexpr inline const char * const AtmosphereCodeMountName = "ams-code"; + constexpr inline const char * const AtmosphereCompatMountName = "ams-cmpt"; + constexpr inline const char * const SdOrCodeMountName = "sd-code"; + constexpr inline const char * const CodeMountName = "code"; + constexpr inline const char * const CompatMountName = "cmpt"; #define ENCODE_ATMOSPHERE_CODE_PATH(relative) "ams-code:" relative + #define ENCODE_ATMOSPHERE_CMPT_PATH(relative) "ams-cmpt:" relative #define ENCODE_SD_OR_CODE_PATH(relative) "sd-code:" relative #define ENCODE_CODE_PATH(relative) "code:" relative + #define ENCODE_CMPT_PATH(relative) "cmpt:" relative /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc); + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform); Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc); Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc); + fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform); + } diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index 61c849799..8a888caac 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -27,56 +27,72 @@ namespace ams::ldr { constinit ArgumentStore g_argument_store; + bool IsValidPlatform(PlatformId platform) { + return platform == PlatformId_Nx; + } + + Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, PlatformId platform) { + /* Check that the platform is valid. */ + R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); + + /* Get the location and override status. */ + ncm::ProgramLocation loc; + cfg::OverrideStatus override_status; + R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id)); + + /* Get the program path. */ + char path[fs::EntryNameLengthMax]; + R_TRY(GetProgramPath(path, sizeof(path), loc, platform)); + path[sizeof(path) - 1] = '\x00'; + + /* Create the process. */ + R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, platform)); + } + + Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, PlatformId platform) { + /* Check that the platform is valid. */ + R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); + + /* Zero output. */ + std::memset(out, 0, sizeof(*out)); + + /* Get the program path. */ + char path[fs::EntryNameLengthMax]; + R_TRY(GetProgramPath(path, sizeof(path), loc, platform)); + path[sizeof(path) - 1] = '\x00'; + + /* Get the program info. */ + cfg::OverrideStatus status; + R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, platform)); + + if (loc.program_id != out->program_id) { + /* Redirect the program path. */ + const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast(loc.storage_id)); + R_TRY(RedirectProgramPath(path, sizeof(path), new_loc)); + + /* Update the arguments, as needed. */ + if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) { + R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size)); + } + } + + /* If we should, set the output status. */ + if (out_status != nullptr) { + *out_status = status; + } + + R_SUCCEED(); + } + } Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) { - /* Declare program path, which we'll need later. */ - - /* Get the location and override status. */ - ncm::ProgramLocation loc; - cfg::OverrideStatus override_status; - R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id)); - - /* Get the program path. */ - char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc)); - path[sizeof(path) - 1] = '\x00'; - - /* Create the process. */ - R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit)); + R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, PlatformId_Nx)); } Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { - /* Zero output. */ - std::memset(out, 0, sizeof(*out)); - - /* Get the program path. */ - char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc)); - path[sizeof(path) - 1] = '\x00'; - - /* Get the program info. */ - cfg::OverrideStatus status; - R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path)); - - if (loc.program_id != out->program_id) { - /* Redirect the program path. */ - const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast(loc.storage_id)); - R_TRY(RedirectProgramPath(path, sizeof(path), new_loc)); - - /* Update the arguments, as needed. */ - if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) { - R_TRY(this->SetProgramArgument(new_loc.program_id, entry->argument, entry->argument_size)); - } - } - - /* If we should, set the output status. */ - if (out_status != nullptr) { - *out_status = status; - } - - R_SUCCEED(); + R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, PlatformId_Nx)); } Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp index 8d1e5c31a..ee43aeedc 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -55,21 +55,8 @@ namespace ams::ldr { R_UNLESS(npdm->magic == Npdm::Magic, ldr::ResultInvalidMeta()); /* Validate flags. */ - u32 mask; - if (hos::GetVersion() >= hos::Version_11_0_0) { - /* 11.0.0 added bit 5 = "DisableDeviceAddressSpaceMerge". */ - mask = ~0x3F; - } else if (hos::GetVersion() >= hos::Version_7_0_0) { - /* 7.0.0 added bit 4 = "UseOptimizedMemory" */ - mask = ~0x1F; - } else { - mask = ~0xF; - } - - /* We set the "DisableDeviceAddressSpaceMerge" bit on all versions, so be permissive with it. */ - mask &= ~0x20; - - R_UNLESS(!(npdm->flags & mask), ldr::ResultInvalidMeta()); + constexpr u32 InvalidMetaFlagMask = 0x80000000; + R_UNLESS(!(npdm->flags & InvalidMetaFlagMask), ldr::ResultInvalidMeta()); /* Validate Acid extents. */ R_TRY(ValidateSubregion(sizeof(Npdm), size, npdm->acid_offset, npdm->acid_size, sizeof(Acid))); @@ -90,8 +77,8 @@ namespace ams::ldr { } /* Validate that the acid version is correct. */ - constexpr u8 MinimumValueForAcid209 = 14; /* TODO: What is the actual meaning of this value? */ - if (acid->unknown_209 < MinimumValueForAcid209) { + constexpr u8 SupportedSdkMajorVersion = ams::svc::ConvertToSdkMajorVersion(ams::svc::SupportedKernelMajorVersion); + if (acid->unknown_209 < SupportedSdkMajorVersion) { R_UNLESS(acid->version == 0, ldr::ResultInvalidMeta()); R_UNLESS(acid->unknown_209 == 0, ldr::ResultInvalidMeta()); } @@ -116,22 +103,30 @@ namespace ams::ldr { R_SUCCEED(); } - const u8 *GetAcidSignatureModulus(u32 key_generation) { - return fssystem::GetAcidSignatureKeyModulus(!IsDevelopmentForAcidSignatureCheck(), key_generation); + const u8 *GetAcidSignatureModulus(PlatformId platform, u8 key_generation, bool unk_unused) { + return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused); } - Result ValidateAcidSignature(Meta *meta) { + size_t GetAcidSignatureModulusSize(PlatformId platform, bool unk_unused) { + return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused); + } + + Result ValidateAcidSignature(Meta *meta, PlatformId platform, bool unk_unused) { /* Loader did not check signatures prior to 10.0.0. */ if (hos::GetVersion() < hos::Version_10_0_0) { meta->check_verification_data = false; R_SUCCEED(); } + /* Get the signature key generation. */ + const auto signature_key_generation = meta->npdm->signature_key_generation; + R_UNLESS(fssystem::IsValidSignatureKeyGeneration(platform, signature_key_generation), ldr::ResultInvalidMeta()); + /* Verify the signature. */ const u8 *sig = meta->acid->signature; const size_t sig_size = sizeof(meta->acid->signature); - const u8 *mod = GetAcidSignatureModulus(meta->npdm->signature_key_generation); - const size_t mod_size = fssystem::AcidSignatureKeyModulusSize; + const u8 *mod = GetAcidSignatureModulus(platform, signature_key_generation, unk_unused); + const size_t mod_size = GetAcidSignatureModulusSize(platform, unk_unused); const u8 *exp = fssystem::GetAcidSignatureKeyPublicExponent(); const size_t exp_size = fssystem::AcidSignatureKeyPublicExponentSize; const u8 *msg = meta->acid->modulus; @@ -195,7 +190,10 @@ namespace ams::ldr { } /* API. */ - Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused) { + /* Set the cached program id back to zero. */ + g_cached_program_id = {}; + /* Try to load meta from file. */ fs::FileHandle file; R_TRY(fs::OpenFile(std::addressof(file), AtmosphereMetaPath, fs::OpenMode_Read)); @@ -261,7 +259,7 @@ namespace ams::ldr { R_TRY(fs::OpenFile(std::addressof(file), BaseMetaPath, fs::OpenMode_Read)); ON_SCOPE_EXIT { fs::CloseFile(file); }; R_TRY(LoadMetaFromFile(file, std::addressof(g_original_meta_cache))); - R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta))); + R_TRY(ValidateAcidSignature(std::addressof(g_original_meta_cache.meta), platform, unk_unused)); meta->modulus = g_original_meta_cache.meta.modulus; meta->check_verification_data = g_original_meta_cache.meta.check_verification_data; } @@ -280,9 +278,9 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform) { if (g_cached_program_id != loc.program_id || g_cached_override_status != status) { - R_RETURN(LoadMeta(out_meta, loc, status)); + R_RETURN(LoadMeta(out_meta, loc, status, platform, false)); } *out_meta = g_meta_cache.meta; R_SUCCEED(); diff --git a/stratosphere/loader/source/ldr_meta.hpp b/stratosphere/loader/source/ldr_meta.hpp index 7356185da..2ac88b63b 100644 --- a/stratosphere/loader/source/ldr_meta.hpp +++ b/stratosphere/loader/source/ldr_meta.hpp @@ -36,8 +36,8 @@ namespace ams::ldr { }; /* Meta API. */ - Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused); + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform); void InvalidateMetaCache(); } diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index 58e4cf955..a7d657897 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -34,23 +34,43 @@ namespace ams::ldr { enum NsoIndex { Nso_Rtld = 0, Nso_Main = 1, - Nso_SubSdk0 = 2, - Nso_SubSdk1 = 3, - Nso_SubSdk2 = 4, - Nso_SubSdk3 = 5, - Nso_SubSdk4 = 6, - Nso_SubSdk5 = 7, - Nso_SubSdk6 = 8, - Nso_SubSdk7 = 9, - Nso_SubSdk8 = 10, - Nso_SubSdk9 = 11, - Nso_Sdk = 12, + Nso_Compat0 = 2, + Nso_Compat1 = 3, + Nso_Compat2 = 4, + Nso_Compat3 = 5, + Nso_Compat4 = 6, + Nso_Compat5 = 7, + Nso_Compat6 = 8, + Nso_Compat7 = 9, + Nso_Compat8 = 10, + Nso_Compat9 = 11, + Nso_SubSdk0 = 12, + Nso_SubSdk1 = 13, + Nso_SubSdk2 = 14, + Nso_SubSdk3 = 15, + Nso_SubSdk4 = 16, + Nso_SubSdk5 = 17, + Nso_SubSdk6 = 18, + Nso_SubSdk7 = 19, + Nso_SubSdk8 = 20, + Nso_SubSdk9 = 21, + Nso_Sdk = 22, Nso_Count, }; constexpr inline const char *NsoPaths[Nso_Count] = { ENCODE_ATMOSPHERE_CODE_PATH("/rtld"), ENCODE_ATMOSPHERE_CODE_PATH("/main"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat0"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat1"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat2"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat3"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat4"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat5"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat6"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat7"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat8"), + ENCODE_ATMOSPHERE_CMPT_PATH("/compat9"), ENCODE_ATMOSPHERE_CODE_PATH("/subsdk0"), ENCODE_ATMOSPHERE_CODE_PATH("/subsdk1"), ENCODE_ATMOSPHERE_CODE_PATH("/subsdk2"), @@ -360,6 +380,11 @@ namespace ams::ldr { flags |= svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; } + /* 18.0.0+/meso Set Alias region extra size. */ + if (meta_flags & Npdm::MetaFlag_EnableAliasRegionExtraSize) { + flags |= svc::CreateProcessFlag_EnableAliasRegionExtraSize; + } + *out = flags; R_SUCCEED(); } @@ -639,15 +664,15 @@ namespace ams::ldr { } /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit) { + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform) { /* Mount code. */ AMS_UNUSED(path); - ScopedCodeMount mount(loc, override_status); + ScopedCodeMount mount(loc, override_status, platform); R_TRY(mount.GetResult()); /* Load meta, possibly from cache. */ Meta meta; - R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status)); + R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform)); /* Validate meta. */ R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData())); @@ -695,16 +720,16 @@ namespace ams::ldr { R_SUCCEED(); } - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path) { + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform) { Meta meta; /* Load Meta. */ { AMS_UNUSED(path); - ScopedCodeMount mount(loc); + ScopedCodeMount mount(loc, platform); R_TRY(mount.GetResult()); - R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus())); + R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false)); if (out_status != nullptr) { *out_status = mount.GetOverrideStatus(); } diff --git a/stratosphere/loader/source/ldr_process_creation.hpp b/stratosphere/loader/source/ldr_process_creation.hpp index f700dba15..79a622169 100644 --- a/stratosphere/loader/source/ldr_process_creation.hpp +++ b/stratosphere/loader/source/ldr_process_creation.hpp @@ -19,8 +19,8 @@ namespace ams::ldr { /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform); Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); Result UnpinProgram(PinId id); From f35c94810c58083905ab9751a12d779909a59338 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 26 May 2024 14:32:11 -0700 Subject: [PATCH 118/238] ams: fix compilation with gcc 14 (closes #2330) --- fusee/program/source/sdram/fusee_sdram.cpp | 6 ++++-- .../svc/codegen/impl/svc_codegen_impl_code_generator.hpp | 8 ++++---- .../codegen/impl/svc_codegen_impl_layout_conversion.hpp | 4 ++-- .../svc/codegen/impl/svc_codegen_impl_meta_code.hpp | 2 +- .../include/vapours/util/arch/arm64/util_atomic.hpp | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/fusee/program/source/sdram/fusee_sdram.cpp b/fusee/program/source/sdram/fusee_sdram.cpp index 46133beee..1ad265a14 100644 --- a/fusee/program/source/sdram/fusee_sdram.cpp +++ b/fusee/program/source/sdram/fusee_sdram.cpp @@ -1002,14 +1002,16 @@ namespace ams::nxboot { \ constexpr u32 SrcLow = RANGE_LOW(SRC_RANGE); \ constexpr u32 DstLow = RANGE_LOW(DST_RANGE); \ + constexpr auto Shift = (SrcLow < DstLow) ? (DstLow - SrcLow) \ + : (SrcLow - DstLow); \ \ cur_reg_value &= ~Mask; \ if constexpr (SrcLow == DstLow) { \ cur_reg_value |= (src_value & Mask); \ } else if constexpr (SrcLow < DstLow) { \ - cur_reg_value |= ((src_value << (DstLow - SrcLow)) & Mask); \ + cur_reg_value |= ((src_value << Shift) & Mask); \ } else { \ - cur_reg_value |= ((src_value >> (SrcLow - DstLow)) & Mask); \ + cur_reg_value |= ((src_value >> Shift) & Mask); \ } \ } \ } diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp index 355ac1412..e33b88a56 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_code_generator.hpp @@ -201,7 +201,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("ldr x%c[r], [sp, %c[offset]]" :: [r]"i"(Reg), [offset]"i"(Offset) : "memory"); } else { - static_assert(Size != Size); + static_assert(false, "Invalid Size"); } } @@ -212,7 +212,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("ldp x%c[r0], x%c[r1], [sp, %c[offset]]" :: [r0]"i"(Reg0), [r1]"i"(Reg1), [offset]"i"(Offset) : "memory"); } else { - static_assert(Size != Size); + static_assert(false, "Invalid Size"); } } @@ -223,7 +223,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("str x%c[r], [sp, %c[offset]]" :: [r]"i"(Reg), [offset]"i"(Offset) : "memory"); } else { - static_assert(Size != Size); + static_assert(false, "Invalid Size"); } } @@ -234,7 +234,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (Size == 8) { __asm__ __volatile__("stp x%c[r0], x%c[r1], [sp, %c[offset]]" :: [r0]"i"(Reg0), [r1]"i"(Reg1), [offset]"i"(Offset) : "memory"); } else { - static_assert(Size != Size); + static_assert(false, "Invalid Size"); } } diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp index 213c0d397..ab1ee69f9 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_layout_conversion.hpp @@ -461,7 +461,7 @@ namespace ams::svc::codegen::impl { if constexpr (CodeGenKind == CodeGenerationKind::SvcInvocationToKernelProcedure) { return Operation::ImplType::template CanGenerateCodeForSvcInvocationToKernelProcedure(allocator); } else { - static_assert(CodeGenKind != CodeGenKind, "Invalid CodeGenerationKind"); + static_assert(false, "Invalid CodeGenerationKind"); } } @@ -474,7 +474,7 @@ namespace ams::svc::codegen::impl { } else if constexpr (CodeGenKind == CodeGenerationKind::KernelProcedureToSvcInvocation) { Operation::ImplType::template GenerateCodeForKernelProcedureToSvcInvocation(mcg); } else { - static_assert(CodeGenKind != CodeGenKind, "Invalid CodeGenerationKind"); + static_assert(false, "Invalid CodeGenerationKind"); } } }; diff --git a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp index 47dba1d29..7dcb8e734 100644 --- a/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp +++ b/libraries/libvapours/include/vapours/svc/codegen/impl/svc_codegen_impl_meta_code.hpp @@ -127,7 +127,7 @@ namespace ams::svc::codegen::impl { META_CODE_OPERATION_KIND_GENERATE_CODE(Pack) META_CODE_OPERATION_KIND_GENERATE_CODE(Unpack) META_CODE_OPERATION_KIND_GENERATE_CODE(LoadStackAddress) - else { static_assert(Kind != Kind, "Unknown MetaOperationKind"); } + else { static_assert(false, "Unknown MetaOperationKind"); } #undef META_CODE_OPERATION_KIND_GENERATE_CODE } diff --git a/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp b/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp index 543126026..a06b54b5c 100644 --- a/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp +++ b/libraries/libvapours/include/vapours/util/arch/arm64/util_atomic.hpp @@ -157,7 +157,7 @@ namespace ams::util { } else if constexpr (Order == std::memory_order_acq_rel || Order == std::memory_order_seq_cst) { return ::ams::util::impl::LoadAcquireExclusiveForAtomic(p); } else { - static_assert(Order != Order, "Invalid memory order"); + static_assert(false, "Invalid memory order"); } } @@ -172,7 +172,7 @@ namespace ams::util { } else if constexpr (Order == std::memory_order_acq_rel || Order == std::memory_order_seq_cst) { return ::ams::util::impl::StoreReleaseExclusiveForAtomic(p, s); } else { - static_assert(Order != Order, "Invalid memory order"); + static_assert(false, "Invalid memory order"); } } From 1609f804f2d272410803037e3ed6f54e37d10294 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 26 May 2024 15:39:00 -0700 Subject: [PATCH 119/238] ams: build with -std=gnu++23 --- libraries/config/common.mk | 2 +- libraries/libstratosphere/source/ams/ams_emummc_api.cpp | 2 +- libraries/libstratosphere/source/fs/fs_api.cpp | 4 ++-- .../source/fssrv/impl/fssrv_program_info.cpp | 2 +- .../source/htc/server/rpc/htc_rpc_task_table.hpp | 2 +- .../libstratosphere/source/osdbg/impl/osdbg_types.hpp | 8 ++++++-- .../include/vapours/util/util_typed_storage.hpp | 2 +- troposphere/daybreak/Makefile | 2 +- troposphere/haze/Makefile | 2 +- 9 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libraries/config/common.mk b/libraries/config/common.mk index 887a68c9c..ed1965866 100644 --- a/libraries/config/common.mk +++ b/libraries/config/common.mk @@ -44,7 +44,7 @@ else ifeq ($(strip $(ATMOSPHERE_COMPILER_NAME)),clang) export ATMOSPHERE_CFLAGS += -Wno-c99-designator -Wno-gnu-alignof-expression -Wno-unused-private-field endif -export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++20 -Wno-invalid-offsetof +export ATMOSPHERE_CXXFLAGS := -fno-rtti -fno-exceptions -std=gnu++23 -Wno-invalid-offsetof export ATMOSPHERE_ASFLAGS := diff --git a/libraries/libstratosphere/source/ams/ams_emummc_api.cpp b/libraries/libstratosphere/source/ams/ams_emummc_api.cpp index ce3b7f9f0..ca47cc455 100644 --- a/libraries/libstratosphere/source/ams/ams_emummc_api.cpp +++ b/libraries/libstratosphere/source/ams/ams_emummc_api.cpp @@ -73,7 +73,7 @@ namespace ams::emummc { /* Retrieve and cache values. */ { - typename std::aligned_storage<2 * (MaxDirLen + 1), os::MemoryPageSize>::type path_storage; + alignas(os::MemoryPageSize) std::byte path_storage[2 * (MaxDirLen + 1)]; struct { char file_path[MaxDirLen + 1]; diff --git a/libraries/libstratosphere/source/fs/fs_api.cpp b/libraries/libstratosphere/source/fs/fs_api.cpp index f04e3049b..c548fc674 100644 --- a/libraries/libstratosphere/source/fs/fs_api.cpp +++ b/libraries/libstratosphere/source/fs/fs_api.cpp @@ -23,8 +23,8 @@ namespace ams::fs { #if defined(ATMOSPHERE_OS_HORIZON) namespace { - constinit std::aligned_storage_t<0x80> g_fsp_service_object_buffer; - constinit std::aligned_storage_t<0x80> g_fsp_ldr_service_object_buffer; + alignas(0x10) constinit std::byte g_fsp_service_object_buffer[0x80] = {}; + alignas(0x10) constinit std::byte g_fsp_ldr_service_object_buffer[0x80] = {}; constinit bool g_use_static_fsp_service_object_buffer = false; constinit bool g_use_static_fsp_ldr_service_object_buffer = false; diff --git a/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp b/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp index 7fe1ca96a..18b157a4a 100644 --- a/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp +++ b/libraries/libstratosphere/source/fssrv/impl/fssrv_program_info.cpp @@ -20,7 +20,7 @@ namespace ams::fssrv::impl { namespace { - constinit std::aligned_storage<0x80>::type g_static_buffer_for_program_info_for_initial_process = {}; + alignas(0x10) constinit std::byte g_static_buffer_for_program_info_for_initial_process[0x80] = {}; template class StaticAllocatorForProgramInfoForInitialProcess : public std::allocator { diff --git a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp index 62637b490..318c01645 100644 --- a/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp +++ b/libraries/libstratosphere/source/htc/server/rpc/htc_rpc_task_table.hpp @@ -41,7 +41,7 @@ namespace ams::htc::server::rpc { #else static constexpr size_t MaxTaskSize = 0xE1D8; #endif - using TaskStorage = typename std::aligned_storage::type; + struct TaskStorage { alignas(alignof(void *)) std::byte _storage[MaxTaskSize]; }; private: bool m_valid[MaxRpcCount]{}; TaskStorage m_storages[MaxRpcCount]{}; diff --git a/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp b/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp index 5f947f255..a579ff449 100644 --- a/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp +++ b/libraries/libstratosphere/source/osdbg/impl/osdbg_types.hpp @@ -19,9 +19,13 @@ namespace ams::osdbg::impl { template - using AlignedStorageIlp32 = typename std::aligned_storage::type; + struct AlignedStorageIlp32 { + alignas(Alignment) std::byte _storage[Size + NumPointers * sizeof(u32)]; + }; template - using AlignedStorageLp64 = typename std::aligned_storage::type; + struct AlignedStorageLp64 { + alignas(Alignment) std::byte _storage[Size + NumPointers * sizeof(u64)]; + }; } diff --git a/libraries/libvapours/include/vapours/util/util_typed_storage.hpp b/libraries/libvapours/include/vapours/util/util_typed_storage.hpp index 710050465..50ebc3727 100644 --- a/libraries/libvapours/include/vapours/util/util_typed_storage.hpp +++ b/libraries/libvapours/include/vapours/util/util_typed_storage.hpp @@ -22,7 +22,7 @@ namespace ams::util { template struct TypedStorage { - typename std::aligned_storage::type _storage; + alignas(Align) std::byte _storage[Size]; }; template diff --git a/troposphere/daybreak/Makefile b/troposphere/daybreak/Makefile index f93397c1d..adb6339f1 100644 --- a/troposphere/daybreak/Makefile +++ b/troposphere/daybreak/Makefile @@ -61,7 +61,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__SWITCH__ -CXXFLAGS := $(CFLAGS) -std=gnu++20 -fno-exceptions -fno-rtti +CXXFLAGS := $(CFLAGS) -std=gnu++23 -fno-exceptions -fno-rtti ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) diff --git a/troposphere/haze/Makefile b/troposphere/haze/Makefile index b6d12ea14..e1e29949c 100644 --- a/troposphere/haze/Makefile +++ b/troposphere/haze/Makefile @@ -61,7 +61,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \ CFLAGS += $(INCLUDE) -D__SWITCH__ -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++20 +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++23 ASFLAGS := -g $(ARCH) LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) From 05fde7b7644228385df6feb7347e309926da6fc6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 26 May 2024 15:40:06 -0700 Subject: [PATCH 120/238] ams: may as well test removal of CRTP from Result --- .../include/vapours/results/results_common.hpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libraries/libvapours/include/vapours/results/results_common.hpp b/libraries/libvapours/include/vapours/results/results_common.hpp index 0d0624eb8..67d81faad 100644 --- a/libraries/libvapours/include/vapours/results/results_common.hpp +++ b/libraries/libvapours/include/vapours/results/results_common.hpp @@ -85,14 +85,13 @@ namespace ams { }; /* Use CRTP for Results. */ - template class ResultBase { public: using BaseType = typename ResultTraits::BaseType; static constexpr BaseType SuccessValue = ResultTraits::SuccessValue; public: - constexpr ALWAYS_INLINE BaseType GetModule() const { return ResultTraits::GetModuleFromValue(static_cast(this)->GetValue()); } - constexpr ALWAYS_INLINE BaseType GetDescription() const { return ResultTraits::GetDescriptionFromValue(static_cast(this)->GetValue()); } + constexpr ALWAYS_INLINE BaseType GetModule(this auto const &self) { return ResultTraits::GetModuleFromValue(self.GetValue()); } + constexpr ALWAYS_INLINE BaseType GetDescription(this auto const &self) { return ResultTraits::GetDescriptionFromValue(self.GetValue()); } }; class ResultInternalAccessor; @@ -101,10 +100,10 @@ namespace ams { class ResultSuccess; - class Result final : public result::impl::ResultBase { + class Result final : public result::impl::ResultBase { friend class result::impl::ResultInternalAccessor; public: - using Base = typename result::impl::ResultBase; + using Base = typename result::impl::ResultBase; private: typename Base::BaseType m_value; private: @@ -157,9 +156,9 @@ namespace ams { } - class ResultSuccess final : public result::impl::ResultBase { + class ResultSuccess final : public result::impl::ResultBase { public: - using Base = typename result::impl::ResultBase; + using Base = typename result::impl::ResultBase; public: constexpr ALWAYS_INLINE operator Result() const { return result::impl::MakeResult(Base::SuccessValue); } static constexpr ALWAYS_INLINE bool CanAccept(Result result) { return result.IsSuccess(); } @@ -189,9 +188,9 @@ namespace ams { namespace result::impl { template - class ResultErrorBase : public ResultBase> { + class ResultErrorBase : public ResultBase { public: - using Base = typename result::impl::ResultBase>; + using Base = typename result::impl::ResultBase; static constexpr typename Base::BaseType Module = _Module; static constexpr typename Base::BaseType Description = _Description; static constexpr typename Base::BaseType Value = ResultTraits::MakeStaticValue::value; From c41a6b80d75c313d56ee3f481c015823f1e1225d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 5 Jun 2024 09:22:53 -0700 Subject: [PATCH 121/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "087f68257" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "087f68257" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index c1120c7e7..5cd7fce67 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = fadec2981727636ec7ba81d6c83995b7b9782190 - parent = 410f23035efeb9e1bd399a020334793bba95bf91 + commit = 087f682571631d5d8734dd994b6caa3e96b8e07c + parent = 05fde7b7644228385df6feb7347e309926da6fc6 method = merge cmdver = 0.4.1 From 5b135d12ca574c8493cd88c9405ad860d040e4a2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 5 Jun 2024 11:28:29 -0700 Subject: [PATCH 122/238] libstrat: fix more gnu++23 errors --- .../libstratosphere/include/stratosphere/sf/sf_buffers.hpp | 2 +- .../include/stratosphere/sf/sf_default_allocation_policy.hpp | 2 +- .../include/stratosphere/sf/sf_exp_heap_allocator.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp index 32286f48f..bc134fd91 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_buffers.hpp @@ -42,7 +42,7 @@ namespace ams::sf { } else if constexpr(TransferMode == BufferTransferMode::AutoSelect) { return SfBufferAttr_HipcAutoSelect; } else { - static_assert(TransferMode != TransferMode, "Invalid BufferTransferMode"); + static_assert(false, "Invalid BufferTransferMode"); } }(); diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp index 64a491eb0..56ca7f5a7 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_default_allocation_policy.hpp @@ -29,7 +29,7 @@ namespace ams::sf { private: struct Holder { MemoryResource *allocator; - typename std::aligned_storage::type storage; + alignas(alignof(T)) std::byte storage[sizeof(T)]; }; public: void *Allocate(size_t size) { diff --git a/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp b/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp index 5a30b09ee..6ec6fcdca 100644 --- a/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp +++ b/libraries/libstratosphere/include/stratosphere/sf/sf_exp_heap_allocator.hpp @@ -57,7 +57,7 @@ namespace ams::sf { struct Globals { ExpHeapAllocator allocator; - typename std::aligned_storage::type buffer; + alignas(0x10) std::byte buffer[Size == 0 ? 1 : Size]; }; static constinit inline Globals _globals = {}; From 9eb92f37dba7840031760838ff6bdf7c54b7ac7b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 5 Jun 2024 11:29:13 -0700 Subject: [PATCH 123/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "d58ff30a1" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "d58ff30a1" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 5cd7fce67..74cc0ba59 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 087f682571631d5d8734dd994b6caa3e96b8e07c - parent = 05fde7b7644228385df6feb7347e309926da6fc6 + commit = d58ff30a12e447141336befd39f56ce14c3e73d1 + parent = 5b135d12ca574c8493cd88c9405ad860d040e4a2 method = merge cmdver = 0.4.1 From 257ac2bd33e1214e25e3380e0c11f84cfe12947a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 10 Jun 2024 22:16:24 -0700 Subject: [PATCH 124/238] emummc: update to support 18.1.0 --- emummc/source/FS/FS_offsets.c | 8 ++++ emummc/source/FS/FS_versions.h | 3 ++ emummc/source/FS/offsets/1810.h | 59 +++++++++++++++++++++++++++ emummc/source/FS/offsets/1810_exfat.h | 59 +++++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 emummc/source/FS/offsets/1810.h create mode 100644 emummc/source/FS/offsets/1810_exfat.h diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index 069f5d9d1..b2059c092 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -71,6 +71,8 @@ #include "offsets/1700_exfat.h" #include "offsets/1800.h" #include "offsets/1800_exfat.h" +#include "offsets/1810.h" +#include "offsets/1810_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -153,6 +155,8 @@ DEFINE_OFFSET_STRUCT(_1700); DEFINE_OFFSET_STRUCT(_1700_EXFAT); DEFINE_OFFSET_STRUCT(_1800); DEFINE_OFFSET_STRUCT(_1800_EXFAT); +DEFINE_OFFSET_STRUCT(_1810); +DEFINE_OFFSET_STRUCT(_1810_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -266,6 +270,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1800)); case FS_VER_18_0_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1800_EXFAT)); + case FS_VER_18_1_0: + return &(GET_OFFSET_STRUCT_NAME(_1810)); + case FS_VER_18_1_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_1810_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index fc7011011..ec4f9ecf8 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -104,6 +104,9 @@ enum FS_VER FS_VER_18_0_0, FS_VER_18_0_0_EXFAT, + FS_VER_18_1_0, + FS_VER_18_1_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/1810.h b/emummc/source/FS/offsets/1810.h new file mode 100644 index 000000000..2b71db7a1 --- /dev/null +++ b/emummc/source/FS/offsets/1810.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1810_H__ +#define __FS_1810_H__ + +// Accessor vtable getters +#define FS_OFFSET_1810_SDMMC_ACCESSOR_GC 0x18AB00 +#define FS_OFFSET_1810_SDMMC_ACCESSOR_SD 0x18C800 +#define FS_OFFSET_1810_SDMMC_ACCESSOR_NAND 0x18AFE0 + +// Hooks +#define FS_OFFSET_1810_SDMMC_WRAPPER_READ 0x186A50 +#define FS_OFFSET_1810_SDMMC_WRAPPER_WRITE 0x186AB0 +#define FS_OFFSET_1810_RTLD 0x2A3A4 +#define FS_OFFSET_1810_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) + +#define FS_OFFSET_1810_CLKRST_SET_MIN_V_CLK_RATE 0x1A77D0 + +// Misc funcs +#define FS_OFFSET_1810_LOCK_MUTEX 0x17FCC0 +#define FS_OFFSET_1810_UNLOCK_MUTEX 0x17FD10 + +#define FS_OFFSET_1810_SDMMC_WRAPPER_CONTROLLER_OPEN 0x186A10 +#define FS_OFFSET_1810_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x186A30 + +// Misc Data +#define FS_OFFSET_1810_SD_MUTEX 0xFD13F0 +#define FS_OFFSET_1810_NAND_MUTEX 0xFCCB28 +#define FS_OFFSET_1810_ACTIVE_PARTITION 0xFCCB68 +#define FS_OFFSET_1810_SDMMC_DAS_HANDLE 0xFB1950 + +// NOPs +#define FS_OFFSET_1810_SD_DAS_INIT 0x28F24 + +// Nintendo Paths +#define FS_OFFSET_1810_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1810_H__ diff --git a/emummc/source/FS/offsets/1810_exfat.h b/emummc/source/FS/offsets/1810_exfat.h new file mode 100644 index 000000000..4ac55481c --- /dev/null +++ b/emummc/source/FS/offsets/1810_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1810_EXFAT_H__ +#define __FS_1810_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_GC 0x195B90 +#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_SD 0x197890 +#define FS_OFFSET_1810_EXFAT_SDMMC_ACCESSOR_NAND 0x196070 + +// Hooks +#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_READ 0x191AE0 +#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_WRITE 0x191B40 +#define FS_OFFSET_1810_EXFAT_RTLD 0x2A3A4 +#define FS_OFFSET_1810_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x44))) + +#define FS_OFFSET_1810_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1B2860 + +// Misc funcs +#define FS_OFFSET_1810_EXFAT_LOCK_MUTEX 0x18AD50 +#define FS_OFFSET_1810_EXFAT_UNLOCK_MUTEX 0x18ADA0 + +#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191AA0 +#define FS_OFFSET_1810_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191AC0 + +// Misc Data +#define FS_OFFSET_1810_EXFAT_SD_MUTEX 0xFE33F0 +#define FS_OFFSET_1810_EXFAT_NAND_MUTEX 0xFDEB28 +#define FS_OFFSET_1810_EXFAT_ACTIVE_PARTITION 0xFDEB68 +#define FS_OFFSET_1810_EXFAT_SDMMC_DAS_HANDLE 0xFBE950 + +// NOPs +#define FS_OFFSET_1810_EXFAT_SD_DAS_INIT 0x28F24 + +// Nintendo Paths +#define FS_OFFSET_1810_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00068B08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x000758DC, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007C77C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x000905C4, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1810_EXFAT_H__ From 76628e273a6de8f2aaca3fa39043669dc7d1b3eb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 10 Jun 2024 22:17:23 -0700 Subject: [PATCH 125/238] ams: bump to 1.7.1 (support for 18.1.0) --- docs/changelog.md | 6 ++++++ fusee/program/source/fusee_stratosphere.cpp | 6 ++++++ .../libstratosphere/include/stratosphere/hos/hos_types.hpp | 1 + libraries/libvapours/include/vapours/ams/ams_api_version.h | 4 ++-- .../libvapours/include/vapours/ams/ams_target_firmware.h | 4 +++- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 1532855a4..ae38d0d70 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,10 @@ # Changelog +## 1.7.1 ++ Support was added for 18.1.0. ++ Atmosphère was updated to use GCC 14/newlib (latest devkitA64/devkitARM releases). ++ Further changes were for 18.0.0: + + `loader` was updated to reflect the latest official behavior. ++ General system stability improvements to enhance the user's experience. ## 1.7.0 + Basic support was added for 18.0.0. + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index add639c05..23630b71b 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -174,6 +174,9 @@ namespace ams::nxboot { FsVersion_18_0_0, FsVersion_18_0_0_Exfat, + FsVersion_18_1_0, + FsVersion_18_1_0_Exfat, + FsVersion_Count, }; @@ -260,6 +263,9 @@ namespace ams::nxboot { { 0x79, 0x5F, 0x5A, 0x5E, 0xB0, 0xC6, 0x77, 0x9E }, /* FsVersion_18_0_0 */ { 0x1E, 0x2C, 0x64, 0xB1, 0xCC, 0xE2, 0x78, 0x24 }, /* FsVersion_18_0_0_Exfat */ + + { 0xA3, 0x39, 0xF0, 0x1C, 0x95, 0xBF, 0xA7, 0x68 }, /* FsVersion_18_1_0 */ + { 0x20, 0x4C, 0xBA, 0x86, 0xDE, 0x08, 0x44, 0x6A }, /* FsVersion_18_1_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index ff8c36898..597cc0876 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -83,6 +83,7 @@ namespace ams::hos { Version_17_0_0 = ::ams::TargetFirmware_17_0_0, Version_17_0_1 = ::ams::TargetFirmware_17_0_1, Version_18_0_0 = ::ams::TargetFirmware_18_0_0, + Version_18_1_0 = ::ams::TargetFirmware_18_1_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 2319e1895..0e06af0fb 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -17,10 +17,10 @@ #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #define ATMOSPHERE_RELEASE_VERSION_MINOR 7 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 18 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 112bbd74f..0dde6da81 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -81,8 +81,9 @@ #define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_0_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_1_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -156,6 +157,7 @@ namespace ams { TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0, TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1, TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, + TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From 1e3349e99a023517269b3fc1bc32fd84e5b3caa9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 10 Jun 2024 22:18:04 -0700 Subject: [PATCH 126/238] emummc: update readme --- emummc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emummc/README.md b/emummc/README.md index 81e43f4b4..f01783ba5 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 18.0.0** +**1.0.0 - 18.1.0** ## Features * Arbitrary SDMMC backend selection From ab5cc7568430e2c1b3fa1be6be104b7c5f71eb32 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 10 Jun 2024 22:18:44 -0700 Subject: [PATCH 127/238] git subrepo push emummc subrepo: subdir: "emummc" merged: "f23f943d4" upstream: origin: "https://github.com/m4xw/emummc" branch: "develop" commit: "f23f943d4" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- emummc/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index 0aab4ee6e..f4eb810eb 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = 832b2442685b45b086697ffe09c5fde05d7444e9 - parent = 3ccb0ae02bc06769f44d61233bf177301ba9d5f3 + commit = f23f943d4092ca9490dbcebbdd117abc3740abcf + parent = 1e3349e99a023517269b3fc1bc32fd84e5b3caa9 method = merge cmdver = 0.4.1 From 39c201e37f36db086cf931433ab33fda29f0ba59 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 10 Jun 2024 22:19:29 -0700 Subject: [PATCH 128/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "bb7678691" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "bb7678691" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 74cc0ba59..fe36741b8 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = d58ff30a12e447141336befd39f56ce14c3e73d1 - parent = 5b135d12ca574c8493cd88c9405ad860d040e4a2 + commit = bb767869105d0eb5c38425f54bf20614639a078d + parent = ab5cc7568430e2c1b3fa1be6be104b7c5f71eb32 method = merge cmdver = 0.4.1 From e85bc4db0be6bca2e78d6274cee5b6be8c79bc6e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 11 Jun 2024 10:29:02 -0700 Subject: [PATCH 129/238] fusee: add nogc case for 18.1 --- fusee/program/source/fusee_stratosphere.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index 23630b71b..a7a380d97 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -637,6 +637,14 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x195FD9, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x16FBE0, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_18_1_0: + AddPatch(fs_meta, 0x18AF49, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x164B50, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_18_1_0_Exfat: + AddPatch(fs_meta, 0x195FD9, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x16FBE0, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } From 4617fec672eb47744f05c20fdb26254cebd1f893 Mon Sep 17 00:00:00 2001 From: hexkyz Date: Wed, 10 Jul 2024 21:36:22 +0100 Subject: [PATCH 130/238] fusee: add missing mtc tables --- .../bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin | Bin 0 -> 4300 bytes .../bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin | Bin 0 -> 4300 bytes .../bin/T210b01SdevEmcDvfsTableH1a4gb01/2.bin | Bin 0 -> 4300 bytes .../bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin | Bin 0 -> 4300 bytes .../bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin | Bin 0 -> 4300 bytes .../bin/T210b01SdevEmcDvfsTableM1a4gb01/2.bin | Bin 0 -> 4300 bytes .../lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 | Bin 0 -> 993 bytes .../lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 | Bin 0 -> 1044 bytes .../lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 | Bin 0 -> 1050 bytes .../lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 | Bin 0 -> 989 bytes .../lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 | Bin 0 -> 1043 bytes .../lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 | Bin 0 -> 1048 bytes fusee/program/source/mtc/fusee_mtc.cpp | 6 + fusee/program/source/mtc/fusee_mtc_mariko.cpp | 2 + .../source/mtc/fusee_mtc_tables_mariko.inc | 900 +++++++++++------- 15 files changed, 565 insertions(+), 343 deletions(-) create mode 100644 fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin create mode 100644 fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin create mode 100644 fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/2.bin create mode 100644 fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin create mode 100644 fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin create mode 100644 fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/2.bin create mode 100644 fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 create mode 100644 fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 create mode 100644 fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 create mode 100644 fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 create mode 100644 fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 create mode 100644 fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/0.bin new file mode 100644 index 0000000000000000000000000000000000000000..821a173420ccb5fb7f346d1163620d21d6919e60 GIT binary patch literal 4300 zcmZQ(U|=vXj5jhcF)%QQ_se%qOAkveD$dN$iw`rQs;V896;$S^bburPpe zK~7FVe12&OF6B%O5)L>GqCmplih+Tbfq{XMfq~%(0|NsG0|P@B0|NsW0|SF10|SEu z0|NsK0|SEy0|Nsq5%z%e!7#{7kl9uY3=FbJdO4wHax*~e2H6Q>gOq^m5@%pw5M^Ls z0MXJQK?Vi}1qKENHY5xRdyo`J45Wt%#DSU%GLH|c7TL`pJ%)zN9XwF~GB7YSfP5|l z^`{gA1A`cp%>q))z`$@28YUn!K|&zEfoNEGfb0eN(VBsQ0fa&JfiTETAb%pW4Go!3 z$bdA1{JkJyA}H(^FzA3?Q2}=Ue||89L2!47G4L{QGl(-dGq^IiGB`81F}O20GPp7D zFn|o?#VIbv0MZH43(_qP_8*4vgG@kPNuh!NivklUUKkwM7|t+oG6*o7Vc=pgW?*7| za8SWfSYCvIkzpn%zBw2e0s;a+DdaN)!+(BZc7_H}9KpN0nsolAi%%? z!o~>_plkvb2IV!7+d=72L`19u;%-KUh6xM|EG+EosSGR(@(seQ41xmkp!DZZB*4Jn zAjFszEyTzmz`@TDA;7@!M?jE4n1er{2E-N-WMF1s_bC!!h_VR{6%i3T5gW_X0mUHp ziP%`a9w_#Sjpg$JrRCB5$^c3c3~2dv=4gHeCsPc9R{52ofsKuUft8J6kmXlUhLvYv zU;t%kP`w}rsvkwfIv@oEb@MB}{0OS!Kp5l(QtMAp*&+BP$vM@AkpkDo{ z!GIrv+%c4~CK^EZ3#c^-YDuDtkMgmHfafF?24sv~6+#qLma;H1Fo0Txp!5tXgAuY2 zmV*;NLjtIC0pWs4SRMdzkl7&qKw(A(1`Zzvh6V)zE(Q$&h6b3sK=lZS4XSfsG^k+? zVuLWO4g!g>gB{Pr#K^?Vz{0w?h@YRK04&5H&mhInKoEoak05nEObiU082&TdV))N6 zm*GDc@_@*yqL46B`{|v{VI2Wq+5ts&d*}yDNI~-I; ze_;gmBq1(?k)V1M)Q5)gvCs#Q#E{u=VMv<-)CXtmU|?YCU|`_wU|?W40BWtB&NzC$iTzE0`BL7^nu0`Kw%vNay$bA0|1&J>0bZ< literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableH1a4gb01/1.bin new file mode 100644 index 0000000000000000000000000000000000000000..7224626db9fabc42839984484d5aa81b40e6d3b7 GIT binary patch literal 4300 zcmZQ(U|=vXj5jnkHZ(FY&@+hl%Xdyo4@)g7&dkq?4>Qm+(KC$?Gtx6)zySh87<^b5 zz_=hMCpW${1&2Zg28ITS21W)3h7U{#B_KY6M;`0HH3NeK0|NudtS1Z%3>*v$3|$Ni z3|tHh42ld43=#|s3@i)`3?d8+46H<00n!J9v5GtH!{4<7>qgE#{NgBSw?0~-Sa0}s>;klR6Q5Diiz z2lbB_1A_nq1A_pF`1p~zLkj9&P^fY+urcT|Fff4Z1leZ@WpjW$%)r3F#LB<`G7E%3 z@h!~2zyP8_aSE~v6dmde3=H**5X=n?D^M7iF)%R5K*LXnfq~)UN9GeAP;+?~BuoT_ z{cc8v0}Kre3>9F1{^ti%XapM@cLz5E8v`o?H#iPJVFYpmC)od>PzK3C;t5@xn*pQ~ zBoERJ;-MKn2)Xh~3Jv^U6qrC^#^AulV8W`&pv7RqD$L-^$jU=e6wfEa@;gTj6fun1nHY70g6Dd zI4BK*+zv{IA|hfPpmYgJpA8cj7+6@?*=I7bFvvFuvoZ(@$b*uRLy-UjgM$!bR_luVPX`o(*e5(Z_&(&o3QndN1kLhm10=sP46^(R%CMmN2~;;JGcYh%g35dm zu?}r;eZ$5;&HPFzKY|JsP+bEmH$V{ssvAJ%2*`b)as=c?kT|HE0@a-$464gU>rZg0 z&%g$5`GD%j(fV_!)}NsK2ukCibPvi0pmdK?e{P^&{i(o!AA;O5l(8lnP-ReLP-9SF zP-ReJ&}2{qwW1ofdneJ5UMUkcP`0r5fZ24PSi3e<-KVLh

FD47Ln287vrPGB`5KWSGD(lYte9 z_GB<&XkeJhz``(-L7IVsVJ5iWHj_b)0fHqMW-?4=n8~2bFcU1N!@vM$f!g69cYa}n z^r1n~0^)-($eo}*G>FE553qb${cH6vHjp%&4QlSVf2CgFatdkJ=6FwBRvBKoFGer!H0zbj03=9k)GeGu&*dRZE zXcee`WEdC(m>3uYKz{i6k-0+#>R$#1h6Wx6HU?t`1_nz81_o;e1_pB|TLI*8kbX7> z29SLq42o}%y&&2GYA+}{^cWZz&M-nSFEq?R?g53X5>ohm{K$MF0ctMqf`o~nu;0zd zaDbtKfuREI&;R^j3XNc6#|aZnlrxgC@aMMT6pK_luVPX`o(*e5(Z z_$^D`7c{3FjG#n3&mV6bIqV6b3lU~pt; zV3@$rz`%+`doq|XG%z$UurM?*h%s=0x@2IsBtruO2umR@2t?ErPDL2Y)Z6qvdZD7AorA%K;E0VLhQpa4opP&P=+ltYk#hk*s$&j)L0 PkZ1tWb3h$#1_lNI(pvK} literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/0.bin new file mode 100644 index 0000000000000000000000000000000000000000..5649c6bf6bb4a057cc83410acf1de53dad7addd7 GIT binary patch literal 4300 zcmZQ(U|=vXj5jhcF)%QQ_se%qOAkveD$dN$iw`rQs;V896;$S^bburPpe zK~7FVe12&OF6B%O5)L>GqCmplih+Tbfq{XMfq~%(0|NsG0|P@B0|NsW0|SF10|SEu z0|NsK0|SEy0|Nsq5%z%e!7#{7kl9uY3=FbJdO4wHax*~e2H6Q>gOq^m5@%pw5M^Ls z0MXJQK?Vi}1qKENHY5xRdyo`J45Wt%#DSU%GLH|c7TL`pJ%)zN9XwF~GB7YSfP5|l z^`{gA1A`cp%>q))z`$@28YUn!K|&zEfoNEGfb0eN(VBsQ0fa&JfiTETAU!ZP$j^p` z%qL_(nnC_vkT4Mx_6rzvz^!2J+$*7h?eF1nC9o76T76$nSVO9n~0eMjRb0`vE zU~mv(%!(FbWDwxsXNVABVE7{-$RNzYA5a5giwH6>GqC#<2{1(2gocWUh@FUy<>`Q8 z5c@=IEME^4`^3ib`GC^$Xnth?r3ePJ{5o?qzk-t~20^R*%Fw{Z#=yYJ#xTh8D=5Rt zGcYiKGBl`+mjl(0B4Qno0)o2v6<>Y?)o~yUas#RLC#Y-@hSrgwA`leBpoj&rLFR$X zWkb~Ypd!-%RMTMApDYX@vp{7RsN5Q@KS7~5u$Wf)aj@2(p!^65aZnn>tUp;88a7a` z{?uT=4?*r2%2*Q(p!)^Xngq2Z(Zxsk*h9c`k_rPd#;yt>3Mxxk7#SEqtwK)S-ZI!6YmXfH=r(5PzUBBLf464+BGkf&dqTh5$nY%w3>*1jL46P~8J+ zn8Wz6ItV1j4t6{f6C)Ed0}JcoB7S~`0X z{e=JJgMopmgMop!gMoqJ0I1ClSH!@; xa3fG^0Ruw-D+2>ax`ROhl#rlokeDimAOjBr3%H*T(gzw(0EKr9$ngve3;=h4>01B* literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin b/fusee/program/mtc_tables/bin/T210b01SdevEmcDvfsTableM1a4gb01/1.bin new file mode 100644 index 0000000000000000000000000000000000000000..ddb81753112e9b7110d69cf58b688797d7d61320 GIT binary patch literal 4300 zcmZQ(U|=vXj5jnkHZ(FY&@+hl%Xdyo4@)g7&dkq?4>Qm+(KC$?Gtx6)zySh87<^b5 zz_=hMCpW${1&2Zg28ITS21W)3h7U{#B_KY6M;`0HH3NeK0|NudtS1Z%3>*v$3|$Ni z3|tHh42ld43=#|s3@i)`3?d8+46H<00n!J9v5GtH!{56FCR1_lN(1_lN;1_lNms2L!)gV-RNkAZ9F1{^ti%XapM@cLz5E8v`o?H#iPJVFYpmC)od>PzK3C;t5@xn*pQ~ zBoERJ;-MKn2)Xh~3Jv^U6qrC^#^AulV8W`&pv7RqD$L-^$jU=e6wfEa@;gTj6fun1nHY70g6Dd zI4BK*+zv{IA|hfPpmYgJpA8cj7+6@?*=I7bFvvFuvoZ(@$b*uRLy-UjgM$!bR_luVPX`o(*e5(Z_&(&o3QndN1kLhm10=sP46^(R%CMmN2~;;JGcYh%g35dm zu?}r;eZ$5;&HPFzKY|JsP+bEmH$V{ssvAJ%2*`b)as=c?kT|HE0@a-$3{pQ@e}YSW z1~zcZ2UI_f)}KSQ{siSmP#OoNdr&?ArF)e6a|8A2PXz}25af=bj5X1KDuW_}8iN9Z zDuWV(CW9ilH3@1-qKgk@KMy9igW4S|j0_B*Rv|mI|A6j32Pb}p1W@B2NdlG!KtjlD z5PzUBsGezHU}#Vf;9}4aU}ylLO#30Wg#n3=hM5e?3^T!UIt&b87N{K#a_1LD zNFN&HClDWmLGA?gp+Phbe1PT4>R+pWv4N!FY*3iEf2CgFatdkJ=6FwBRvBKoFGer!H0zbj03?MO(y&yKo4K_>f1_34p1_6*CK7M5Gkb(M_fq|ichk=d3n1O-8l7WH2nt_4A9LiPzc^sslje$Xc z0fIsC4YC(RTR`mvMTZ^(1H&0c2eybK%+Yz%y0|AOKH3H1K~>U=jkk%z=%;fz6OXpTU7moM8eZC-Z}Y3W>tl6OxgU0VO*amq9>)0gNXkN`SHn zSR9lFL2d`7LlF_N4p6!TrO$>53=AwR?Cc86EDZ7u!mJE}0`j1=>`)}Yz~CUnm=!I= z$RNPM&k!NN!0<;vkRh0ZU%&~(77=7{W?*Mi7GQ|72@Mqy5jznZ%hLhHAod9l5568K z_VMuG^BK*ri1H3Czs?-Zui#{gLC`F}HbC+#xQH7>`4yC5=_ssK=~C^N6{+3 z63UOD`UOE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2M<{P37H562i^q<6Kfa^7cl6wF$h+OG3fv24`XEh$iv+s#=y(K%^=R; z%;3u4%HYi4#^BE2$l%7n)5jpsE5X2~AjV+Dz+l6`V8k)gLiUP+;W|BC|C z48{+93=V7zXBapc1Q^aRa4{G&Ffl(ksNg6pFT%jcFf)cRfrEh|ARs`AN#L^sW4JIo zLj#u&gRl?_0}}(2AnSZaWdWu@CWa?W!Yq@R^i2dNFt9OKGIJ_2%x_?DU|hrL;@2-2a}VCh*-xCh7atF3=I<)7+6@? z*;5%<7~~s-Ss4TcF=j;zF)|2n@H0dRFfjZP5M&VM;18(bVff50 zBFMnZ!0uBdzz}5<8Y&_pb|N;Gr-Ow-=mZOcGG7l1gMbeU1OEo*|D5tOH!%N?o6pd| z#>T+F%EqvPxrU*KNkCqOfjNUoSZ)Keyub!#2mT4noWgu84Ez(A6&X?(<%K6Oi!&Ir z${S2zW|n7hVE_NWK%UWooy(tvp<%-WW^;WF1||k>eny71(wdA6JPHgf9?blV4FAO} zJtwKKfC8SEVGEN33nK%A7?-d_3oCB`bCeT5LjtD=gB&9d1OFd}yzfkm3=AAT3=9nl z0$dCl0t^j|H#mhE|FE)fFbK2qFo-j@urY`*2(ka;yUfJM#LU3Ly10m+pP}Fxi$8-D zLjwx~pP;k=%SWaL1|KE{hD{9r8E!HBXPC?IpNT=7hlAlGlP5zxLj%Kq1{Q|@3~L!U z82)!K82@KD#=;<+tHU7ph>d};VD{JPZvnpp3}CzyJWC{H_N8 literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 new file mode 100644 index 0000000000000000000000000000000000000000..c32abfc779342d35683c3eff1d096cd2eb229b47 GIT binary patch literal 1044 zcmew_&CI~SU|<+;Xl!g~WMH6Y5bu}ooR%JzT2!2wpBEoypl70I8Xsn)XTZS7z>*js z!r;Tgz{1d9kdu=eUz)7#J8t7#J8>0~iFvxmXw&LKvn8FfcHbGBPmiR$&mf zh+qg-V_;yA)?pAP93qMgN=&Ri3=9Db3?CSUg*h064RRP5`Wchd85kJq8Ce*Fxpf#BCNKn>F)%R5 zTwxFrs$oz*;Ss^$z`Gz}Vh!V@-HZ$e7#bKDD*71Z`9l~PFSD_6cW^VXF|aalgM7)* z!XU`Wz$nPb#=tMZz^cH_V8y_oz#z!V!=TU2z{t?wAg`p*!2d;o$%OHPID-Qlg9)o9 zgBF7ct1yEvBRlhhg9?el@*)h349}Sv7`QnY7y<&)m=qK~J1~a#YcMpZ`Y;F!u`sZB zF*2|+C<`(LG8Hl~IJAl|IT$hOD+o+rU=wm+XW&$1nBTzQz`!EVz@TuNfm`G~CxeHK zjEsyVgOY#%3xla|qQr4#VPg(vh7P7c5fQNt-2+S?*x48wCNMCtu&}ewWMW~EZxCi> z5EPJiXZpbJP$a;>;2^}96)nWbAi%-T5Fx<8@JB$9A((?-z=?<9GrNc&gEIp=o3a2y zluc-;h=|yU*jSzp76t|$hTsz(9(+A43<5qZ4E!6I|8vUE+`#-lUZ`OMvpmBF<{Dwf z4@?Yin1YoV7#J)!Fw1LiV0Pf2z|1Qzk@? literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 new file mode 100644 index 0000000000000000000000000000000000000000..b97594bc05ded161072e55aaef6a05103b9e05f4 GIT binary patch literal 1050 zcmZ3$%)r24U>I*`X28hspF7?!-#INkEVZaOGe0jr%s|gX&on;FNY8+Qk%28SOM=0N zg@J{kz91(jH@-AQhk<=sgG2)(0|UbcCSeABMg~R({ow!B3=9rF4F83mFfcH1FfcH5 zF)%Q2F)%PFGB7YmFfcH%FfcHPFfcH%1~3SSbFnZmgfL7`U|?W4z{tSxK!stl3j+g# zECU0BW(q?v4+8^(t_%Z14#QSaggH1EgjIML8e|w41eh2Y1dcF-ef-GWA!Eb%nYn?7fsMhKfq}u2 zfq}uAfq}uChe1g}LXkm0jPm>;jEtAr*tk1*88{f&82A|2 zIv5#R7y`K&7#P@_800x57}yke8LSu>6hJ-_<$AFW1~!HhjLghTZ2ipr3=Rw|0u2lb zry00K-g7c|$jHdZNHQo12(U1iPDqqE&dgB3B&^-R6euDh)?w_y^nsm?p6eufAE28KTZf(*eN`~prq44>IW z1R0ze*x8f?7@}-KLq$ZyPQ=FYbg(cm@Gu0Q@bKX4VPO#PVPW9k!2F+6e&z<||M5Z% z8<^!8HZa#P^e_d>GcYjNZ(x>p+`#O?KY^K7Ude&||Nl?&j1KI)@*5^Fo9inuFfnlR zGcv4|)?{S(!l=%m$e_-kz@WyU%%H`f#NffqBLNEK|7Hw1%nmG!3=Cpi!t6U(c>|cE zocI|MI7JvZc=+TQ&oGn-^1NVPz|f!|z{Q{;z|dgJBFz4PRhXZJL6{ko2zD?CGg>eR zb4*|pGOu8{%*w;T%OI(eQ^e2DQ1Fb!pFxVDfrWw3@B%0aeP?49VqmakXkf5lXkc(; zXkeJY(7?dT!SIpElfi_cfuVtcg`t5#jDdrpp@Pl0fkBdmVWI>>1H)8?1_oI*215o0 zojVN14Gbb{7?i#+?qLw-6krhMU}2P3RA%JvJP^hh${Nbb#KR!Wc!!;VkwI9WgW*63 z17n9S15*bB18;{81H%?>4o`*!Hv**=FfatLGBC(97E(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC%s+Oay}i?}CJhHH?M}7SU|>@aW3Xaiuwh`ZV-OU7z`)PQ(Ayxdq|m_s zMS*Ds;|D$l2R4Q?44e!C3}+a)7>pU1m>(Qea1@poVPIsK8N-;s!N3p@5TL{)@Y#Ve zT$r7qfy;+MScrvziGfLwbv~oA08=0n!xJW9mPt(dCIS-}*qAGsITab^H!wIbun06T zD4b;AG+tYZhm2X;n=h6xM| zEG+EosSGR(@(seQ41xmk4NM>S9f|}P7#xHcv!aC<83Z`^86pH282$(dG6-|<2h{K| zd}bFBWMF1s_bC!!h_VR{6%i3T5gW_X!NMSPf`vhuuZM*}z=wr_e*^P>PWhP|nE%Jk zXJ}w!V_;xqW7xo4!_dPdAg{u}Y{Dcgw}Dw+U<0!Q{{&`EVLlcH{t3*A3@MEA!V{Rq z8H`!w4JI%%%d3=J`$Ovu2%001Kht)2h? literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 new file mode 100644 index 0000000000000000000000000000000000000000..80af9d71764d9873a852495fa56a66d0954f55f8 GIT binary patch literal 1043 zcmew_&CI~SU|<+;Xl!g~WMH6Y5bu}ooR%JzT2!2wpBEoypl70I8Xsn)XTZS7z>*js z!r;Tgz{1d9kdu=eUz)7#J8t7#J8>0~iFvxmXw&LKvn8FfcHbGBPmiR$&mf zh+qg-V_;yA)?pAx+M$@1q{N5 zJPb-4B8m)3OsqZ(3;_%b9~gy&IT(Zuau^u;8I#l*7#QjqSr~-5br=~YFa&EbFfhnm zVGt6kVNgEd5y9ZVyC7j=4dbNUj0^`D8W~$k5*)ucXkx|3!hxgztV6*4e5w2Ck}7%}QA2uxsL6LMf@;8bLo-@xF&z#`DVpm3UjTjV__gNKZa zjEp3Ml7IjUgQ;(##BpX}V-9A94yHg65wQ;4156*-*%%roFfg#Nu(Qu(VquVP5N2f% z6p(jk`oQl{B*4JnAjFszEyTzmz`@TDA;7@!M?jDvn1f%yiHG4cyNDozGXp!DvH(Mr zO=zfyh}enPSe_0R1_mC6;1eDmd_61-0zNDZ{2Q46bIQ-$!2Ca6s9^)MJi`X&8ezr{ zObljm>>h6V)zE(Q$&h6WZFK4IZMtiqfOY{JX}48q`)P{GE)!XT*U z#qgMwg_E6|K}0UAh@YRK;2DcQgA_vp3j?3wT2K=F&i03ofx(txCW8gTOa@1WnG6#c zW-_pHFnnb4WH4c9V3^6k!Z4FTnt_91rU0AqOa?g?hK&*oGa05b%w$kzm?^_xr~}G1 z!Xhgel)f`-A~ z>R@2t?a*Oh*uu@>$*|x?pwt2eh5%Mj{xR%eP}s^U+QGswU6(_Ufro*GfiXaUft{hj K2b3on7#INd&$9#o literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 new file mode 100644 index 0000000000000000000000000000000000000000..b3ad2304e91fd6a16e22ede02e3d043cfbc1faa9 GIT binary patch literal 1048 zcmZ3$%)r24U>I*`X28hspF7?!-#INkEVZaOGe0jr%s|gX&on;FNY8+Qk%28SOM=0N zg@J{kz91(jH@-AQhk<=sgG2)(0|UbcCSeABMg~R({ow!B3=9rF4F83mFfcH1FfcH5 zF)%Q2F)%PFGB7YmFfcH%FfcHPFfcH%1~3SSbFnZmgfL7`U|?W4z{tSxK!stl3j+g# zECU0BW(q?v4+8^(t_%Z14#Qf1BT1u3=9ln3=9lx z3=9l>A`HS@JPg7d91OxLJPZvo3=9HH3=9HC7{We&WbTl$Vf@V8z{9}CV9db4V9CJ1 zV9mh5V9vv!q#&Wlki@~pz#zcD!XV6C0dl#pMG6B$KVy;}0|UbuMivHPUK2)!2@DLs z7{!$w7=u54WImA)!QjBVAYoz+6eufAE28KTZf(*eN`~prq44>IW z1R0ze*x8f?7@}-KLq$ZyPQ=FYbg(cm@Gu0Q@bKX4VPO#PVPW9k!2F+6e&z<||M5Z% z8<^!8HZa#P^e_d>GcYjNZ(x>p+`#O?KY^K7Ude&||Nl?&j1KI)@*5^Fo9inuFfnlR zGcv4|)?{S(!l=%m$e_-kz@WyU%%H`f#NffqBLNEK|7Hw1%nmG!3=Cpi!t6U(c>|cE zocI|MI7JvZc=+TQ&oGn-^1NVPz|f!|z{Q{;z|dgJBFz4PRhU16RhX%SRhV}NgD|57 zgD}SgHX-v0mdmU>9J~yYDmg{`{0s%pSo|5J7#dg@_zW+A($IG{W+4U!TZRS(3x);; zM}`K52@DMktQ-se4VBEkUvW7wF3*#OJVNL-CVGb5Xc|~PL?#=^YjG?TdtV}!%!i;y=85kLa^*I<0 zgfK96=rS;MFfj0T=rAyB;pXsUSa2gyY5@a704oE7JcD5egThu;(GC`d>82cl3_J`h T42%H+4D1XIb3mDsfq?-42+Xz& literal 0 HcmV?d00001 diff --git a/fusee/program/source/mtc/fusee_mtc.cpp b/fusee/program/source/mtc/fusee_mtc.cpp index 74a1acd7b..7b513c9e3 100644 --- a/fusee/program/source/mtc/fusee_mtc.cpp +++ b/fusee/program/source/mtc/fusee_mtc.cpp @@ -60,6 +60,12 @@ namespace ams::nxboot { /* DramId_MarikoHoagMicron1y4gb */ 0x0F, /* DramId_MarikoAulaMicron1y4gb */ 0x0F, /* DramId_MarikoAulaSamsung1y8gbX */ 0x0D, + /* DramId_MarikoIowaHynix1a4gb */ 0x13, + /* DramId_MarikoHoagHynix1a4gb */ 0x13, + /* DramId_MarikoAulaHynix1a4gb */ 0x13, + /* DramId_MarikoIowaMicron1a4gb */ 0x14, + /* DramId_MarikoHoagMicron1a4gb */ 0x14, + /* DramId_MarikoAulaMicron1a4gb */ 0x14, }; int GetMemoryTrainingTableIndex() { diff --git a/fusee/program/source/mtc/fusee_mtc_mariko.cpp b/fusee/program/source/mtc/fusee_mtc_mariko.cpp index b231229af..e6497af70 100644 --- a/fusee/program/source/mtc/fusee_mtc_mariko.cpp +++ b/fusee/program/source/mtc/fusee_mtc_mariko.cpp @@ -97,6 +97,8 @@ namespace ams::nxboot { HANDLE_CASE(0x10, T210b01SdevEmcDvfsTableH1y4gb01) HANDLE_CASE(0x11, T210b01SdevEmcDvfsTableS1y8gb04) HANDLE_CASE(0x12, T210b01SdevEmcDvfsTableS1z4gb01) + HANDLE_CASE(0x13, T210b01SdevEmcDvfsTableH1a4gb01) + HANDLE_CASE(0x14, T210b01SdevEmcDvfsTableM1a4gb01) default: ShowFatalError("Unknown EmcDvfsTimingTableIndex: %d\n", index); } diff --git a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc index 11ed68d5a..83b06e808 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc @@ -229,10 +229,10 @@ constexpr const u8 T210b01SdevEmcDvfsTableS4gb01[0x67B] = { 0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = { +constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, + 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, @@ -242,99 +242,98 @@ constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = { 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, + 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, + 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, + 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, + 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, + 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, + 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, + 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x78, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x13, 0x29, 0x01, 0x00, 0x13, 0x32, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, - 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, - 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, - 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, - 0x00, 0x6E, 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, - 0x28, 0x10, 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, - 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, - 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, - 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, - 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, - 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, - 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, - 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, - 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, - 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, - 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, - 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, - 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, - 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, - 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, - 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, - 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, - 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, - 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, - 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, - 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, - 0x09, 0x13, 0x37, 0x0C, 0x00, 0x13, 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x70, 0x00, 0x13, 0x10, - 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, - 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, - 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, - 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x88, 0x0E, 0x00, 0x09, 0x00, 0x07, - 0x00, 0x0E, 0x00, 0x03, 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, - 0x00, 0x05, 0x20, 0x0E, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, - 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, - 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, - 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, - 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, - 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, - 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, - 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, - 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, - 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, - 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xB6, 0x04, - 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, 0x00, - 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, - 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, - 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, - 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, - 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, - 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, - 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, - 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, - 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, - 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, - 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, - 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, - 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, - 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, + 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, + 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, + 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, + 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, + 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, + 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, + 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, + 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, + 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, + 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, + 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, + 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, + 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, + 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, + 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, + 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, + 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, + 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, + 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, + 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, + 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, + 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, + 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, + 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, + 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, + 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, + 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, + 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, + 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, + 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, + 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, + 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, + 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, + 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, + 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, + 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, + 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, + 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, + 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, + 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, + 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, + 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, + 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, + 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, + 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, + 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, + 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, + 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, + 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, + 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, + 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, + 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, + 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, + 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, + 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, + 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, + 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, + 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, + 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, + 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, + 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, + 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, + 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, + 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, + 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, + 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, + 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, + 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, + 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, + 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, + 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, + 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, + 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, + 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, + 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, + 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, + 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[0x68C] = { @@ -445,114 +444,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[0x68C] = { 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbX03[0x67D] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, - 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, - 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, - 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, - 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, - 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, - 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, - 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, - 0x00, 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, - 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, - 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, - 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, - 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, - 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, - 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, - 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, - 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, - 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, - 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, - 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, - 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, - 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, - 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, - 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, - 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, - 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, - 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, - 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, - 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, - 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, - 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, - 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, - 0x06, 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, - 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, - 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, - 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, - 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, - 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, - 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, - 0x02, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, - 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, - 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, - 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, - 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, - 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, - 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, - 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, - 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, - 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, - 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, - 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, - 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, - 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { +constexpr const u8 T210b01SdevEmcDvfsTableM1a4gb01[0x679] = { 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, @@ -569,7 +461,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, + 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, @@ -592,7 +484,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, + 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, @@ -602,61 +494,61 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, - 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, - 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, - 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, - 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, - 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, - 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, - 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, - 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, - 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, - 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, - 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, - 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, - 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, - 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, - 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, - 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, - 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, - 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, - 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, - 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, - 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, - 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, + 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, + 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, + 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, + 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, + 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, + 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, + 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, + 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, + 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, + 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, + 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, + 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, + 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, + 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, + 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, + 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, 0x00, + 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, + 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, + 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, + 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, + 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, + 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, + 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, + 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, + 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, + 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, + 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, + 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, + 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, + 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, + 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, + 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, + 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, + 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, + 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, + 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x12, + 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, + 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, + 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, + 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, + 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, + 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, + 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, + 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, + 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, + 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, + 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, + 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, + 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, + 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, + 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, + 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, + 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, + 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[0x67D] = { @@ -766,6 +658,113 @@ constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[0x67D] = { 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbX03[0x67D] = { + 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, + 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, + 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, + 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, + 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, + 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, + 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, + 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, + 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, + 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, + 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, + 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, + 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, + 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, + 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, + 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, + 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, + 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, + 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, + 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, + 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, + 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, + 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, + 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, + 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, + 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, + 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, + 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, + 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, + 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, + 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, + 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, + 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, + 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, + 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, + 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, + 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, + 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, + 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, + 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, + 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, + 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, + 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, + 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, + 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, + 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, + 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, + 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, + 0x00, 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, + 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, + 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, + 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, + 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, + 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, + 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, + 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, + 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, + 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, + 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, + 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, + 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, + 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, + 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, + 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, + 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, + 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, + 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, + 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, + 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, + 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, + 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, + 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, + 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, + 0x06, 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, + 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, + 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, + 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, + 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, + 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, + 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, + 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, + 0x02, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, + 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, + 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, + 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, + 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, + 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, + 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, + 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, + 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, + 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, + 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, + 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, + 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, + 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, + 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, + 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, + 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, + 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, + 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, + 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, + 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + constexpr const u8 T210b01SdevEmcDvfsTableM1y4gb01[0x67B] = { 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, @@ -1195,7 +1194,7 @@ constexpr const u8 T210b01SdevEmcDvfsTableS4gb03[0x67B] = { 0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; -constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = { +constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = { 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, @@ -1208,100 +1207,99 @@ constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = { 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x08, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, + 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, + 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, + 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0x48, + 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, + 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x18, 0x00, + 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, + 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, + 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, 0x00, - 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, 0x33, - 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, - 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, - 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, - 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, - 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, - 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, - 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, - 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, - 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, - 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x10, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x13, 0x29, 0x01, 0x00, 0x13, 0x35, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0xD8, 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x04, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, - 0x03, 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, - 0xC0, 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, - 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, - 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, - 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, - 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, - 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, - 0x00, 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, - 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1C, 0x8C, - 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, 0x08, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, - 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, - 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, - 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, - 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x35, 0x50, 0x50, 0xA0, 0x8C, 0x09, 0x5F, 0x8C, 0x30, - 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, - 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, - 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, - 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, - 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, - 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, - 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, - 0x03, 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, - 0x07, 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, - 0xB6, 0x04, 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, - 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, - 0x08, 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0x50, 0x1F, 0x0B, 0x04, 0x00, 0x11, - 0x0F, 0xCC, 0x00, 0x20, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, - 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, - 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, 0x00, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, - 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, - 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, - 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, - 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, - 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, - 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, - 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, - 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, - 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, + 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, + 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, + 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, + 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, + 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, + 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, + 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, + 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, + 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, + 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, + 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, + 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, + 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, + 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, + 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, + 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, + 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, + 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x78, 0x00, 0x02, 0x00, 0x0B, + 0x0F, 0x01, 0x00, 0xAD, 0x13, 0x29, 0x01, 0x00, 0x13, 0x32, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, + 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, + 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, + 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, + 0x00, 0x6E, 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, + 0x28, 0x10, 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, + 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, + 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, + 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, + 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, + 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, + 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, + 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, + 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, + 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, + 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, + 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, + 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, + 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, + 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, + 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, + 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, + 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, + 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, + 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, + 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, + 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, + 0x09, 0x13, 0x37, 0x0C, 0x00, 0x13, 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x70, 0x00, 0x13, 0x10, + 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, + 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, + 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, + 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x88, 0x0E, 0x00, 0x09, 0x00, 0x07, + 0x00, 0x0E, 0x00, 0x03, 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, + 0x00, 0x05, 0x20, 0x0E, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, + 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, + 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, + 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, + 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, + 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, + 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, + 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, + 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, + 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, + 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, + 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, + 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xB6, 0x04, + 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, 0x00, + 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, + 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, + 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, + 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, + 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, + 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, + 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, + 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, + 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, + 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, + 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, + 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, + 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, + 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[0x687] = { @@ -1412,6 +1410,113 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[0x687] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +constexpr const u8 T210b01SdevEmcDvfsTableH1a4gb01[0x67B] = { + 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, + 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, + 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, + 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, + 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, + 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, + 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, + 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, + 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, + 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, + 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, + 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, + 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, + 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, + 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, + 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, + 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, + 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, + 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, + 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, + 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, + 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, + 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, + 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, + 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, + 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, + 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, + 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, + 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, + 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, + 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, + 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, + 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, + 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, + 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, + 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, + 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, + 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, + 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, + 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, + 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, + 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, + 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, + 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, + 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, + 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, + 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, + 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, + 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, + 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, + 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, + 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, + 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, + 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, + 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, + 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, + 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, + 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, + 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, + 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, + 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, + 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, + 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, + 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, + 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, + 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, + 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, + 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, + 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, + 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, + 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, + 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, + 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, + 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, + 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, + 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, + 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, + 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, + 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, + 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, + 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, + 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, + 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, + 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, + 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, + 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, + 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, + 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, + 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, + 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, + 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, + 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, + 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, + 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, + 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, + 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, + 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, + 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, + 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, + 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, + 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, + 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[0x681] = { 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, @@ -1520,6 +1625,115 @@ constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[0x681] = { 0x00, }; +constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = { + 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, + 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, + 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, + 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, + 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, + 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, + 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, + 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, + 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, + 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, + 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x08, + 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, + 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, + 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, + 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0x48, + 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, + 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x16, 0x00, + 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, + 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, + 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, + 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, + 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, + 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, + 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, + 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, + 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, + 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, 0x00, + 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, 0x33, + 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, + 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, + 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, + 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, + 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, + 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, + 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, + 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, + 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, + 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, + 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, + 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, + 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, + 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x10, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, + 0x13, 0x29, 0x01, 0x00, 0x13, 0x35, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, + 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, + 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, + 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, + 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, + 0x01, 0xD8, 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x04, 0x84, + 0x06, 0x00, 0x14, 0x00, 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, + 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, + 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, + 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, + 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, + 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, + 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, + 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, + 0x03, 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, + 0xC0, 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, + 0x00, 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, + 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, + 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, + 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, + 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, + 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, + 0x00, 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, + 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, + 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, + 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1C, 0x8C, + 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, + 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, + 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, + 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, + 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, + 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, 0x08, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, + 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, + 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, + 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, + 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x35, 0x50, 0x50, 0xA0, 0x8C, 0x09, 0x5F, 0x8C, 0x30, + 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, + 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, + 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, + 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, + 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, + 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, + 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, + 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, + 0x03, 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, + 0x07, 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, + 0xB6, 0x04, 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, + 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, + 0x08, 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0x50, 0x1F, 0x0B, 0x04, 0x00, 0x11, + 0x0F, 0xCC, 0x00, 0x20, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, + 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, + 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, 0x00, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, + 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, + 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, + 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, + 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, + 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, + 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, + 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, + 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, + 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbX03[0x680] = { 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, From 423a05a1e90bf711f724b8d2a723dbbb5e0d5281 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 1 Sep 2024 16:27:01 -0700 Subject: [PATCH 131/238] meso: fix sign-comparison warn on svc/interrupt flag compare --- .../libmesosphere/include/mesosphere/kern_k_capabilities.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index 7b5a93dcc..7c2f5dbcd 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -192,7 +192,7 @@ namespace ams::kern { u32 m_program_type; private: constexpr bool SetSvcAllowed(u32 id) { - if (AMS_LIKELY(id < m_svc_access_flags.GetCount())) { + if (AMS_LIKELY(id < static_cast(m_svc_access_flags.GetCount()))) { m_svc_access_flags[id] = true; return true; } else { @@ -201,7 +201,7 @@ namespace ams::kern { } constexpr bool SetInterruptPermitted(u32 id) { - if (AMS_LIKELY(id < m_irq_access_flags.GetCount())) { + if (AMS_LIKELY(id < static_cast(m_irq_access_flags.GetCount()))) { m_irq_access_flags[id] = true; return true; } else { From 027e209073cd46265f0483c4502f6b55a3c9f26a Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 1 Sep 2024 22:27:48 -0700 Subject: [PATCH 132/238] kern/ldr: enable the use of relr for relocations --- mesosphere/kernel/kernel.ld | 3 +++ mesosphere/kernel/kernel.specs | 2 +- .../kernel/source/arch/arm64/init/kern_init_core.cpp | 8 ++++---- mesosphere/kernel_ldr/kernel_ldr.ld | 7 ++++--- mesosphere/kernel_ldr/kernel_ldr.specs | 2 +- mesosphere/kernel_ldr/source/kern_init_loader.cpp | 8 ++++---- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/mesosphere/kernel/kernel.ld b/mesosphere/kernel/kernel.ld index 356cea88c..779488a35 100644 --- a/mesosphere/kernel/kernel.ld +++ b/mesosphere/kernel/kernel.ld @@ -14,6 +14,7 @@ SECTIONS /* =========== CODE section =========== */ PROVIDE(__start__ = 0x0); . = __start__; + __bin_start__ = .; __code_start = . ; .start : @@ -159,6 +160,7 @@ SECTIONS __bss_start__ = .; .rela.dyn : { *(.rela.*) } :data + .relr.dyn : { *(.relr.*) } :data .bss ADDR(.rela.dyn) (NOLOAD) : { *(.dynbss) @@ -169,6 +171,7 @@ SECTIONS __bss_end__ = .; + __bin_end__ = .; __end__ = ABSOLUTE(.); /* ================== diff --git a/mesosphere/kernel/kernel.specs b/mesosphere/kernel/kernel.specs index 7ca30e94d..a6b848cd0 100644 --- a/mesosphere/kernel/kernel.specs +++ b/mesosphere/kernel/kernel.specs @@ -1,7 +1,7 @@ %rename link old_link *link: -%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib +%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -z pack-relative-relocs -nostdlib *startfile: crti%O%s crtbegin%O%s diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index f74cb050c..faf34576d 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -15,8 +15,8 @@ */ #include -extern "C" void _start(); -extern "C" void __end__(); +extern "C" void __bin_start__(); +extern "C" void __bin_end__(); namespace ams::kern { @@ -264,8 +264,8 @@ namespace ams::kern::init { KMemoryLayout::GetPhysicalMemoryRegionTree().InsertDirectly(KernelPhysicalAddressSpaceBase, KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1); /* Save start and end for ease of use. */ - const uintptr_t code_start_virt_addr = reinterpret_cast(_start); - const uintptr_t code_end_virt_addr = reinterpret_cast(__end__); + const uintptr_t code_start_virt_addr = reinterpret_cast(__bin_start__); + const uintptr_t code_end_virt_addr = reinterpret_cast(__bin_end__); /* Setup the containing kernel region. */ constexpr size_t KernelRegionSize = 1_GB; diff --git a/mesosphere/kernel_ldr/kernel_ldr.ld b/mesosphere/kernel_ldr/kernel_ldr.ld index c56886133..26802a6f3 100644 --- a/mesosphere/kernel_ldr/kernel_ldr.ld +++ b/mesosphere/kernel_ldr/kernel_ldr.ld @@ -12,6 +12,7 @@ SECTIONS /* =========== CODE section =========== */ PROVIDE(__start__ = 0x0); . = __start__; + __bin_start__ = .; __code_start = . ; .crt0 : @@ -74,9 +75,8 @@ SECTIONS .gnu_extab : ONLY_IF_RO { *(.gnu_extab*) } : rodata .dynamic : { *(.dynamic) } :krnlldr :dyn - .dynsym : { *(.dynsym) } :krnlldr - .dynstr : { *(.dynstr) } :krnlldr .rela.dyn : { *(.rela.*) } :krnlldr + .relr.dyn : { *(.relr.*) } :krnlldr .hash : { *(.hash) } :krnlldr .gnu.hash : { *(.gnu.hash) } :krnlldr .gnu.version : { *(.gnu.version) } :krnlldr @@ -159,6 +159,7 @@ SECTIONS } :krnlldr __bss_end__ = .; + __bin_end__ = .; __end__ = ABSOLUTE(.) ; /* ================== @@ -166,7 +167,7 @@ SECTIONS ================== */ /* Discard sections that difficult post-processing */ - /DISCARD/ : { *(.group .comment .note .interp) } + /DISCARD/ : { *(.group .comment .note .interp .dynsym .dynstr) } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } diff --git a/mesosphere/kernel_ldr/kernel_ldr.specs b/mesosphere/kernel_ldr/kernel_ldr.specs index 593f42369..42d7e341e 100644 --- a/mesosphere/kernel_ldr/kernel_ldr.specs +++ b/mesosphere/kernel_ldr/kernel_ldr.specs @@ -1,7 +1,7 @@ %rename link old_link *link: -%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel_ldr.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -nostdlib +%(old_link) -T %:getenv(ATMOSPHERE_TOPDIR /kernel_ldr.ld) -pie --gc-sections -z text -z nodynamic-undefined-weak -z pack-relative-relocs -nostdlib *startfile: crti%O%s crtbegin%O%s diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index 8b991d943..33fe56393 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -19,8 +19,8 @@ /* Necessary for calculating kernelldr size/base for initial identity mapping */ extern "C" { - extern const u8 __start__[]; - extern const u8 __end__[]; + extern const u8 __bin_start__[]; + extern const u8 __bin_end__[]; } @@ -88,8 +88,8 @@ namespace ams::kern::init::loader { /* Map in an RWX identity mapping for ourselves. */ constexpr PageTableEntry KernelLdrRWXIdentityAttribute(PageTableEntry::Permission_KernelRWX, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); - const uintptr_t kernel_ldr_base = util::AlignDown(reinterpret_cast(__start__), PageSize); - const uintptr_t kernel_ldr_size = util::AlignUp(reinterpret_cast(__end__), PageSize) - kernel_ldr_base; + const uintptr_t kernel_ldr_base = util::AlignDown(reinterpret_cast(__bin_start__), PageSize); + const uintptr_t kernel_ldr_size = util::AlignUp(reinterpret_cast(__bin_end__), PageSize) - kernel_ldr_base; init_pt.Map(kernel_ldr_base, kernel_ldr_size, kernel_ldr_base, KernelRWXIdentityAttribute, allocator, 0); /* Map in the page table region as RW- for ourselves. */ From 009f58172118f850f08655dc5f4d8a3ff3d50027 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 23 Sep 2024 02:41:57 -0700 Subject: [PATCH 133/238] creport: optimize ScopedFile performance --- .../creport/source/creport_crash_report.cpp | 12 +++++- .../creport/source/creport_modules.cpp | 2 +- .../creport/source/creport_scoped_file.cpp | 42 +++++++++++++++---- .../creport/source/creport_scoped_file.hpp | 11 ++++- 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/stratosphere/creport/source/creport_crash_report.cpp b/stratosphere/creport/source/creport_crash_report.cpp index 9936102e5..fec6cbc67 100644 --- a/stratosphere/creport/source/creport_crash_report.cpp +++ b/stratosphere/creport/source/creport_crash_report.cpp @@ -26,6 +26,8 @@ namespace ams::creport { static_assert(DyingMessageAddressOffset == AMS_OFFSETOF(ams::svc::aarch64::ProcessLocalRegion, dying_message_region_address)); static_assert(DyingMessageAddressOffset == AMS_OFFSETOF(ams::svc::aarch32::ProcessLocalRegion, dying_message_region_address)); + constexpr size_t CrashReportDataCacheSize = 256_KB; + /* Helper functions. */ bool TryGetCurrentTimestamp(u64 *out) { /* Clear output. */ @@ -307,7 +309,15 @@ namespace ams::creport { /* Save crash report. */ util::SNPrintf(file_path, sizeof(file_path), "sdmc:/atmosphere/crash_reports/%011lu_%016lx.log", timestamp, m_process_info.program_id); { - ScopedFile file(file_path); + /* Try to allocate data cache. */ + void * const data_cache = lmem::AllocateFromExpHeap(m_heap_handle, CrashReportDataCacheSize + os::MemoryPageSize); + ON_SCOPE_EXIT { if (data_cache != nullptr) { lmem::FreeToExpHeap(m_heap_handle, data_cache); } }; + + /* Align up the data cache. This is safe because null will align up to null. */ + void * const aligned_cache = reinterpret_cast(util::AlignUp(reinterpret_cast(data_cache), os::MemoryPageSize)); + + /* Open and save the file using the cache. */ + ScopedFile file(file_path, aligned_cache, aligned_cache != nullptr ? CrashReportDataCacheSize : 0); if (file.IsOpen()) { this->SaveToFile(file); } diff --git a/stratosphere/creport/source/creport_modules.cpp b/stratosphere/creport/source/creport_modules.cpp index 69620b92b..b6a3486e1 100644 --- a/stratosphere/creport/source/creport_modules.cpp +++ b/stratosphere/creport/source/creport_modules.cpp @@ -46,7 +46,7 @@ namespace ams::creport { } void ModuleList::SaveToFile(ScopedFile &file) { - file.WriteFormat(" Number of Modules: %zu\n", m_num_modules); + file.WriteFormat(" Number of Modules: %02zu\n", m_num_modules); for (size_t i = 0; i < m_num_modules; i++) { const auto& module = m_modules[i]; file.WriteFormat(" Module %02zu:\n", i); diff --git a/stratosphere/creport/source/creport_scoped_file.cpp b/stratosphere/creport/source/creport_scoped_file.cpp index 4daf9e046..1b6341c99 100644 --- a/stratosphere/creport/source/creport_scoped_file.cpp +++ b/stratosphere/creport/source/creport_scoped_file.cpp @@ -60,22 +60,24 @@ namespace ams::creport { /* Print the line prefix. */ if (first) { - this->WriteFormat("%s", prefix); + this->Write(prefix, prefix_len); first = false; } else { - this->WriteFormat("%*s", prefix_len, ""); + std::memset(g_format_buffer, ' ', prefix_len); + this->Write(g_format_buffer, prefix_len); } /* Dump up to 0x20 of hex memory. */ { char hex[MaximumLineLength * 2 + 2] = {}; for (size_t i = 0; i < cur_size; i++) { - util::SNPrintf(hex + i * 2, 3, "%02X", data_u8[data_ofs++]); + hex[i * 2 + 0] = "0123456789ABCDEF"[data_u8[data_ofs] >> 4]; + hex[i * 2 + 1] = "0123456789ABCDEF"[data_u8[data_ofs] & 0xF]; + ++data_ofs; } hex[cur_size * 2 + 0] = '\n'; - hex[cur_size * 2 + 1] = '\x00'; - this->WriteString(hex); + this->Write(hex, cur_size * 2 + 1); } /* Continue. */ @@ -83,16 +85,40 @@ namespace ams::creport { } } + void ScopedFile::Write(const void *data, size_t size) { /* If we're not open, we can't write. */ if (!this->IsOpen()) { return; } - /* Advance, if we write successfully. */ - if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::Flush))) { - m_offset += size; + /* If we have a cache, write to it. */ + if (m_cache != nullptr) { + /* Write into the cache, if we can. */ + if (m_cache_size - m_cache_offset >= size || R_SUCCEEDED(this->TryWriteCache())) { + std::memcpy(m_cache + m_cache_offset, data, size); + m_cache_offset += size; + } + } else { + /* Advance, if we write successfully. */ + if (R_SUCCEEDED(fs::WriteFile(m_file, m_offset, data, size, fs::WriteOption::None))) { + m_offset += size; + } } } + Result ScopedFile::TryWriteCache() { + /* If there's no cached data, there's nothing to do. */ + R_SUCCEED_IF(m_cache_offset == 0); + + /* Try to write any cached data. */ + R_TRY(fs::WriteFile(m_file, m_offset, m_cache, m_cache_offset, fs::WriteOption::None)); + + /* Update our extents. */ + m_offset += m_cache_offset; + m_cache_offset = 0; + + R_SUCCEED(); + } + } \ No newline at end of file diff --git a/stratosphere/creport/source/creport_scoped_file.hpp b/stratosphere/creport/source/creport_scoped_file.hpp index 7b302b589..5adcbeb09 100644 --- a/stratosphere/creport/source/creport_scoped_file.hpp +++ b/stratosphere/creport/source/creport_scoped_file.hpp @@ -25,8 +25,11 @@ namespace ams::creport { fs::FileHandle m_file; s64 m_offset; bool m_opened; + u8 *m_cache; + const size_t m_cache_size; + s64 m_cache_offset; public: - ScopedFile(const char *path) : m_file(), m_offset(), m_opened(false) { + ScopedFile(const char *path, void *cache = nullptr, size_t cache_size = 0) : m_file(), m_offset(), m_opened(false), m_cache(static_cast(cache)), m_cache_size(cache_size), m_cache_offset(0) { if (R_SUCCEEDED(fs::CreateFile(path, 0))) { m_opened = R_SUCCEEDED(fs::OpenFile(std::addressof(m_file), path, fs::OpenMode_Write | fs::OpenMode_AllowAppend)); } @@ -34,6 +37,10 @@ namespace ams::creport { ~ScopedFile() { if (m_opened) { + if (m_cache != nullptr) { + this->TryWriteCache(); + } + fs::FlushFile(m_file); fs::CloseFile(m_file); } } @@ -47,6 +54,8 @@ namespace ams::creport { void DumpMemory(const char *prefix, const void *data, size_t size); void Write(const void *data, size_t size); + private: + Result TryWriteCache(); }; } \ No newline at end of file From 10c7a395285c133e4c17c52d84728a4c7b24accd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 24 Sep 2024 13:15:21 -0700 Subject: [PATCH 134/238] kern/creport: use mod0 to locate symbol table for all modules --- .../source/arch/arm64/kern_k_debug.cpp | 41 ++++++++----------- .../creport/source/creport_modules.cpp | 38 +++++------------ 2 files changed, 26 insertions(+), 53 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index eb04243cf..89587597b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -623,11 +623,6 @@ namespace ams::kern::arch::arm64 { } } - /* Read the first instruction. */ - if (!ReadValue(std::addressof(temp_32), process, base_address)) { - return PrintAddress(address); - } - /* Get the module name. */ char module_name[0x20]; const bool has_module_name = GetModuleName(module_name, sizeof(module_name), process, base_address); @@ -637,36 +632,32 @@ namespace ams::kern::arch::arm64 { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (temp_32 == 0) { - /* Module is dynamically loaded by rtld. */ + /* Locate .dyn using rocrt::ModuleHeader. */ + { + /* Determine the ModuleHeader offset. */ u32 mod_offset; if (!ReadValue(std::addressof(mod_offset), process, base_address + sizeof(u32))) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset)) { + + /* Read the signature. */ + constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature); + if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + SignatureFieldOffset)) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (temp_32 != 0x30444F4D) { /* MOD0 */ + + /* Check that the module signature is expected. */ + if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + sizeof(u32))) { + + /* Determine the dynamic offset. */ + constexpr u32 DynamicFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, dynamic_offset); + if (!ReadValue(std::addressof(temp_32), process, base_address + mod_offset + DynamicFieldOffset)) { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - dyn_address = base_address + mod_offset + temp_32; - } else if (temp_32 == 0x14000002) { - /* Module embeds rtld. */ - if (!ReadValue(std::addressof(temp_32), process, base_address + 0x5C)) { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); - } - if (temp_32 != 0x94000002) { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); - } - if (!ReadValue(std::addressof(temp_32), process, base_address + 0x60)) { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); - } - dyn_address = base_address + 0x60 + temp_32; - } else { - return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); + + dyn_address = module.start_address + mod_offset + temp_32; } /* Locate tables inside .dyn. */ diff --git a/stratosphere/creport/source/creport_modules.cpp b/stratosphere/creport/source/creport_modules.cpp index b6a3486e1..7ea58e0dd 100644 --- a/stratosphere/creport/source/creport_modules.cpp +++ b/stratosphere/creport/source/creport_modules.cpp @@ -282,56 +282,38 @@ namespace ams::creport { return; } - /* Read the first instruction of .text. */ - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address, sizeof(temp_32)))) { - return; - } - /* We want to find the symbol table/.dynamic. */ uintptr_t dyn_address = 0; uintptr_t sym_tab = 0; uintptr_t str_tab = 0; size_t num_sym = 0; - /* Detect module type. */ - if (temp_32 == 0) { - /* Module is dynamically loaded by rtld. */ + /* Locate .dyn using rocrt::ModuleHeader. */ + { + /* Determine the ModuleHeader offset. */ u32 mod_offset; if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(mod_offset)), m_debug_handle, module.start_address + sizeof(u32), sizeof(u32)))) { return; } - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset, sizeof(u32)))) { + /* Read the signature. */ + constexpr u32 SignatureFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, signature); + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + SignatureFieldOffset, sizeof(u32)))) { return; } + /* Check that the module signature is expected. */ if (temp_32 != rocrt::ModuleHeaderVersion) { /* MOD0 */ return; } - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + sizeof(u32), sizeof(u32)))) { + /* Determine the dynamic offset. */ + constexpr u32 DynamicFieldOffset = AMS_OFFSETOF(rocrt::ModuleHeader, dynamic_offset); + if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + mod_offset + DynamicFieldOffset, sizeof(u32)))) { return; } dyn_address = module.start_address + mod_offset + temp_32; - } else if (temp_32 == 0x14000002) { - /* Module embeds rtld. */ - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + 0x5C, sizeof(u32)))) { - return; - } - - if (temp_32 != 0x94000002) { - return; - } - - if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast(std::addressof(temp_32)), m_debug_handle, module.start_address + 0x60, sizeof(u32)))) { - return; - } - - dyn_address = module.start_address + 0x60 + temp_32; - } else { - /* Module has unknown format. */ - return; } From c4a5d4db096fc22ae8edf6d5402fc217295bec4c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 8 Oct 2024 11:50:32 -0700 Subject: [PATCH 135/238] fusee/exo/ams: update with new keydata/version enums --- .../program/source/boot/secmon_boot_key_data.s | 9 +++++++-- .../program/source/boot/secmon_package2.cpp | 2 +- fusee/program/source/fusee_key_derivation.cpp | 11 ++++++++--- fusee/program/source/fusee_package2.cpp | 2 +- fusee/program/source/fusee_setup_horizon.cpp | 2 ++ fusee/program/source/fusee_stratosphere.cpp | 16 ++++++++++++++++ .../exosphere/pkg1/pkg1_key_generation.hpp | 1 + .../libexosphere/include/exosphere/pkg2.hpp | 2 +- libraries/libexosphere/source/fuse/fuse_api.cpp | 1 + .../fs/impl/fs_id_string_impl.os.generic.cpp | 5 +++-- .../include/vapours/ams/ams_api_version.h | 8 ++++---- .../include/vapours/ams/ams_target_firmware.h | 4 +++- 12 files changed, 48 insertions(+), 15 deletions(-) diff --git a/exosphere/program/source/boot/secmon_boot_key_data.s b/exosphere/program/source/boot/secmon_boot_key_data.s index b745114f1..826441314 100644 --- a/exosphere/program/source/boot/secmon_boot_key_data.s +++ b/exosphere/program/source/boot/secmon_boot_key_data.s @@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* TODO: Update on next change of keys. */ /* Mariko Development Master Kek Source. */ -.byte 0xE4, 0x45, 0xD0, 0x14, 0xA0, 0xE5, 0xE9, 0x4B, 0xFE, 0x76, 0xF4, 0x29, 0x41, 0xBB, 0x64, 0xED +.byte 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70 /* Mariko Production Master Kek Source. */ -.byte 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 +.byte 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 /* Development Master Key Vectors. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ @@ -109,6 +109,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 /* Master key 0E encrypted with Master key 0F. */ .byte 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 /* Master key 0F encrypted with Master key 10. */ .byte 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */ +.byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */ /* Production Master Key Vectors. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ @@ -129,6 +130,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 /* Master key 0E encrypted with Master key 0F. */ .byte 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD /* Master key 0F encrypted with Master key 10. */ .byte 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */ +.byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */ /* Device Master Key Source Sources. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ @@ -146,6 +148,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C /* 16.0.0 Device Master Key Source Source. */ .byte 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 /* 17.0.0 Device Master Key Source Source. */ .byte 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */ +.byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */ /* Development Device Master Kek Sources. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ @@ -163,6 +166,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F /* 16.0.0 Device Master Kek Source. */ .byte 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 /* 17.0.0 Device Master Kek Source. */ .byte 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */ +.byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */ /* Production Device Master Kek Sources. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ @@ -180,3 +184,4 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F /* 16.0.0 Device Master Kek Source. */ .byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */ .byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */ +.byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */ diff --git a/exosphere/program/source/boot/secmon_package2.cpp b/exosphere/program/source/boot/secmon_package2.cpp index a51e1a712..2d6b8948e 100644 --- a/exosphere/program/source/boot/secmon_package2.cpp +++ b/exosphere/program/source/boot/secmon_package2.cpp @@ -94,7 +94,7 @@ namespace ams::secmon::boot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 18); + static_assert(pkg1::KeyGeneration_Count == 19); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_key_derivation.cpp b/fusee/program/source/fusee_key_derivation.cpp index cad7ca589..3d8eb31bf 100644 --- a/fusee/program/source/fusee_key_derivation.cpp +++ b/fusee/program/source/fusee_key_derivation.cpp @@ -23,17 +23,17 @@ namespace ams::nxboot { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 + 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0xE4, 0x45, 0xD0, 0x14, 0xA0, 0xE5, 0xE9, 0x4B, 0xFE, 0x76, 0xF4, 0x29, 0x41, 0xBB, 0x64, 0xED + 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70 }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 + 0xD7, 0x63, 0x74, 0x46, 0x4E, 0xBA, 0x78, 0x0A, 0x7C, 0x9D, 0xB3, 0xE8, 0x7A, 0x3D, 0x71, 0xE3 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -72,6 +72,7 @@ namespace ams::nxboot { { 0xEA, 0x90, 0x6E, 0xA8, 0xAE, 0x92, 0x99, 0x64, 0x36, 0xC1, 0xF3, 0x1C, 0xC6, 0x32, 0x83, 0x8C }, /* 16.0.0 Device Master Key Source Source. */ { 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, /* 17.0.0 Device Master Key Source Source. */ { 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */ + { 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -90,6 +91,7 @@ namespace ams::nxboot { { 0xF0, 0xF3, 0xFF, 0x52, 0x75, 0x2F, 0xBA, 0x4D, 0x09, 0x72, 0x30, 0x89, 0xA9, 0xDF, 0xFE, 0x1F }, /* 16.0.0 Device Master Kek Source. */ { 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, /* 17.0.0 Device Master Kek Source. */ { 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */ + { 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -108,6 +110,7 @@ namespace ams::nxboot { { 0xFF, 0xF6, 0x4B, 0x0F, 0xFF, 0x0D, 0xC0, 0x4F, 0x56, 0x8A, 0x40, 0x74, 0x67, 0xC5, 0xFE, 0x9F }, /* 16.0.0 Device Master Kek Source. */ { 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 }, /* 17.0.0 Device Master Kek Source. */ { 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */ + { 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -129,6 +132,7 @@ namespace ams::nxboot { { 0xAF, 0x11, 0x4C, 0x67, 0x17, 0x7A, 0x52, 0x43, 0xF7, 0x70, 0x2F, 0xC7, 0xEF, 0x81, 0x72, 0x16 }, /* Master key 0E encrypted with Master key 0F. */ { 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, /* Master key 0F encrypted with Master key 10. */ { 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */ + { 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -150,6 +154,7 @@ namespace ams::nxboot { { 0x78, 0x66, 0x19, 0xBD, 0x86, 0xE7, 0xC1, 0x09, 0x9B, 0x6F, 0x92, 0xB2, 0x58, 0x7D, 0xCF, 0x26 }, /* Master key 0E encrypted with Master key 0F. */ { 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 }, /* Master key 0F encrypted with Master key 10. */ { 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */ + { 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */ }; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; diff --git a/fusee/program/source/fusee_package2.cpp b/fusee/program/source/fusee_package2.cpp index 535f0f68d..9735b0f0b 100644 --- a/fusee/program/source/fusee_package2.cpp +++ b/fusee/program/source/fusee_package2.cpp @@ -80,7 +80,7 @@ namespace ams::nxboot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 18); + static_assert(pkg1::KeyGeneration_Count == 19); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 78c40b216..6d0d6a384 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -261,6 +261,8 @@ namespace ams::nxboot { return ams::TargetFirmware_17_0_0; } else if (std::memcmp(package1 + 0x10, "20240207", 8) == 0) { return ams::TargetFirmware_18_0_0; + } else if (std::memcmp(package1 + 0x10, "20240808", 8) == 0) { + return ams::TargetFirmware_19_0_0; } break; default: diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index a7a380d97..99fea38bd 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -177,6 +177,9 @@ namespace ams::nxboot { FsVersion_18_1_0, FsVersion_18_1_0_Exfat, + FsVersion_19_0_0, + FsVersion_19_0_0_Exfat, + FsVersion_Count, }; @@ -266,6 +269,9 @@ namespace ams::nxboot { { 0xA3, 0x39, 0xF0, 0x1C, 0x95, 0xBF, 0xA7, 0x68 }, /* FsVersion_18_1_0 */ { 0x20, 0x4C, 0xBA, 0x86, 0xDE, 0x08, 0x44, 0x6A }, /* FsVersion_18_1_0_Exfat */ + + { 0xD9, 0x4C, 0x68, 0x15, 0xF8, 0xF5, 0x0A, 0x20 }, /* FsVersion_19_0_0 */ + { 0xED, 0xA8, 0x78, 0x68, 0xA4, 0x49, 0x07, 0x50 }, /* FsVersion_19_0_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -645,6 +651,16 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x195FD9, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x16FBE0, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_19_0_0: + AddPatch(fs_meta, 0x195C75, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x195E75, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x16F170, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_19_0_0_Exfat: + AddPatch(fs_meta, 0x1A14A5, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1A16A5, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } diff --git a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp index 0cfc43633..92aea986e 100644 --- a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp +++ b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp @@ -38,6 +38,7 @@ namespace ams::pkg1 { KeyGeneration_16_0_0 = 0x0F, KeyGeneration_17_0_0 = 0x10, KeyGeneration_18_0_0 = 0x11, + KeyGeneration_19_0_0 = 0x12, KeyGeneration_Count, diff --git a/libraries/libexosphere/include/exosphere/pkg2.hpp b/libraries/libexosphere/include/exosphere/pkg2.hpp index 8775d2ed9..d72ce1f03 100644 --- a/libraries/libexosphere/include/exosphere/pkg2.hpp +++ b/libraries/libexosphere/include/exosphere/pkg2.hpp @@ -24,7 +24,7 @@ namespace ams::pkg2 { constexpr inline int PayloadCount = 3; constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */ - constexpr inline int CurrentBootloaderVersion = 0x15; + constexpr inline int CurrentBootloaderVersion = 0x16; struct Package2Meta { using Magic = util::FourCC<'P','K','2','1'>; diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index 95c316d68..e20dddcc0 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,6 +177,7 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { + TargetFirmware_19_0_0, TargetFirmware_17_0_0, TargetFirmware_16_0_0, TargetFirmware_15_0_0, diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp index 091b19d3a..5e2d9b60f 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -21,7 +21,7 @@ namespace ams::fs::impl { #define ADD_ENUM_CASE(v) case v: return #v template<> const char *IdString::ToString(pkg1::KeyGeneration id) { - static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_18_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_19_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -41,7 +41,8 @@ namespace ams::fs::impl { case KeyGeneration_15_0_0: return "15.0.0-15.0.1"; case KeyGeneration_16_0_0: return "16.0.0-16.0.3"; case KeyGeneration_17_0_0: return "17.0.0-17.0.1"; - case KeyGeneration_18_0_0: return "18.0.0-"; + case KeyGeneration_18_0_0: return "18.0.0-18.1.0"; + case KeyGeneration_19_0_0: return "19.0.0-"; default: return "Unknown"; } } diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 0e06af0fb..978b1622e 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -16,11 +16,11 @@ #pragma once #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 -#define ATMOSPHERE_RELEASE_VERSION_MINOR 7 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 8 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 18 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 19 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 0dde6da81..484f76f8b 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -82,8 +82,9 @@ #define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_19_0_0 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_18_1_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_19_0_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -158,6 +159,7 @@ namespace ams { TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1, TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0, + TargetFirmware_19_0_0 = ATMOSPHERE_TARGET_FIRMWARE_19_0_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From 4acfac539c26095d498f28e35bee4adf7a2e5793 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 8 Oct 2024 12:24:41 -0700 Subject: [PATCH 136/238] erpt: add new IDs/categories --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 80 +++++++++++++------ utilities/erpt.py | 3 + 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index 92d6db7dc..c7e5eef6b 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -81,8 +81,8 @@ HANDLER(NetworkErrorInfo, 40 ) \ HANDLER(FileAccessPathInfo, 41 ) \ HANDLER(GameCardCIDInfo, 42 ) \ - HANDLER(NANDCIDInfo, 43 ) \ - HANDLER(MicroSDCIDInfo, 44 ) \ + HANDLER(NANDCIDInfoDeprecated, 43 ) \ + HANDLER(MicroSDCIDInfoDeprecated, 44 ) \ HANDLER(NANDSpeedModeInfo, 45 ) \ HANDLER(MicroSDSpeedModeInfo, 46 ) \ HANDLER(GameCardSpeedModeInfo, 47 ) \ @@ -112,7 +112,7 @@ HANDLER(FocusedAppletHistoryInfo, 71 ) \ HANDLER(CompositorInfo, 72 ) \ HANDLER(BatteryChargeInfo, 73 ) \ - HANDLER(NANDExtendedCsd, 74 ) \ + HANDLER(NANDExtendedCsdDeprecated, 74 ) \ HANDLER(NANDPatrolInfo, 75 ) \ HANDLER(NANDErrorInfo, 76 ) \ HANDLER(NANDDriverLog, 77 ) \ @@ -178,9 +178,12 @@ HANDLER(BuiltInWirelessOUIInfo, 137 ) \ HANDLER(WirelessAPOUIInfo, 138 ) \ HANDLER(EthernetAdapterOUIInfo, 139 ) \ - HANDLER(NANDTypeInfo, 140 ) \ + HANDLER(NANDTypeInfoDeprecated, 140 ) \ HANDLER(MicroSDTypeInfo, 141 ) \ - HANDLER(TestNx, 1000) + HANDLER(AttachmentFileInfo, 142 ) \ + HANDLER(TestNx, 1000) \ + HANDLER(NANDTypeInfo, 1001) \ + HANDLER(NANDExtendedCsd, 1002) \ #define AMS_ERPT_FOREACH_FIELD(HANDLER) \ HANDLER(TestU64, 0, Test, FieldType_NumericU64, FieldFlag_None ) \ @@ -280,8 +283,8 @@ HANDLER(CDNContentPath, 94, NetworkErrorInfo, FieldType_String, FieldFlag_None ) \ HANDLER(FileAccessPath, 95, FileAccessPathInfo, FieldType_String, FieldFlag_None ) \ HANDLER(GameCardCID, 96, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDCID, 97, NANDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(MicroSDCID, 98, MicroSDCIDInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDCIDDeprecated, 97, NANDCIDInfoDeprecated, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(MicroSDCIDDeprecated, 98, MicroSDCIDInfoDeprecated, FieldType_U8Array, FieldFlag_None ) \ HANDLER(NANDSpeedMode, 99, NANDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ HANDLER(MicroSDSpeedMode, 100, MicroSDSpeedModeInfo, FieldType_String, FieldFlag_None ) \ HANDLER(GameCardSpeedMode, 101, GameCardSpeedModeInfo, FieldType_String, FieldFlag_None ) \ @@ -373,9 +376,9 @@ HANDLER(FastBatteryChargingEnabled, 187, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(ControllerPowerSupplyAcquiredDeprecated, 188, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(OtgRequestedDeprecated, 189, BatteryChargeInfo, FieldType_Bool, FieldFlag_None ) \ - HANDLER(NANDPreEolInfo, 190, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypA, 191, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypB, 192, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDPreEolInfoDeprecated, 190, NANDExtendedCsdDeprecated, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypADeprecated, 191, NANDExtendedCsdDeprecated, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypBDeprecated, 192, NANDExtendedCsdDeprecated, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDPatrolCount, 193, NANDPatrolInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDNumActivationFailures, 194, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDNumActivationErrorCorrections, 195, NANDErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ @@ -446,21 +449,21 @@ HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(CpuDvfsTableClocks, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(CpuDvfsTableVoltages, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableClocks, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(GpuDvfsTableVoltages, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableClocks, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(EmcDvfsTableVoltages, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocksDeprecated, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltagesDeprecated, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocksDeprecated, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltagesDeprecated, 266, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocksDeprecated, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltagesDeprecated, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(PowerDomainEnableFlags, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(PowerDomainVoltages, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltagesDeprecated, 275, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(AccessPointRssi, 276, RadioStrengthInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(FuseInfo, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(FuseInfoDeprecated, 277, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(VideoLog, 278, VideoInfo, FieldType_String, FieldFlag_None ) \ HANDLER(GameCardDeviceId, 279, GameCardCIDInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(GameCardAsicReinitializeCount, 280, GameCardErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ @@ -830,9 +833,9 @@ HANDLER(RuntimeLimitedApplicationLicenseUpgrade, 644, RunningApplicationInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(ServiceProfileRevisionKey, 645, ServiceProfileInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(BluetoothAudioConnectionCount, 646, BluetoothAudioInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothHidPairingInfoCount, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothAudioPairingInfoCount, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ - HANDLER(BluetoothLePairingInfoCount, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCountDeprecated, 647, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCountDeprecated, 648, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCountDeprecated, 649, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(FatFsBisSystemFilePeakOpenCount, 650, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ HANDLER(FatFsBisSystemDirectoryPeakOpenCount, 651, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ HANDLER(FatFsBisUserFilePeakOpenCount, 652, FsProxyErrorInfo, FieldType_NumericU16, FieldFlag_None ) \ @@ -860,11 +863,24 @@ HANDLER(FatFsBisUserFatErrorNumber, 674, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(FatFsBisUserFatSafeErrorNumber, 675, FsProxyErrorInfo2, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(GpuCrashDump2, 676, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(NANDType, 677, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(NANDTypeDeprecated, 677, NANDTypeInfoDeprecated, FieldType_U8Array, FieldFlag_None ) \ HANDLER(MicroSDType, 678, MicroSDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(GameCardLastDeactivateReasonResult, 679, GameCardErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(GameCardLastDeactivateReason, 680, GameCardErrorInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(InvalidErrorCode, 681, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(AppletId, 682, ApplicationInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(PrevReportIdentifier, 683, ErrorInfoAuto, FieldType_String, FieldFlag_None ) \ + HANDLER(SyslogStartupTimeBase, 684, ErrorInfoAuto, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(NxdmpIsAttached, 685, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(ScreenshotIsAttached, 686, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SyslogIsAttached, 687, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(SaveSyslogResult, 688, AttachmentFileInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(EncryptionKeyGeneration, 689, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FsBufferManagerNonBlockingRetriedCount, 690, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(FsPooledBufferNonBlockingRetriedCount, 691, FsMemoryInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(LastConnectionTestDownloadSpeed64, 692, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(EncryptionKeyV1, 694, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \ HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -877,5 +893,21 @@ HANDLER(AdspExceptionArmModeRegisters, 1009, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionStackAddress, 1010, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackDump, 1011, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) + HANDLER(AdspExceptionReason, 1012, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(CpuDvfsTableClocks, 1013, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(CpuDvfsTableVoltages, 1014, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableClocks, 1015, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(GpuDvfsTableVoltages, 1016, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableClocks, 1017, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(EmcDvfsTableVoltages, 1018, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(PowerDomainEnableFlags, 1019, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(PowerDomainVoltages, 1020, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ + HANDLER(FuseInfo, 1021, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ + HANDLER(NANDType, 1022, NANDTypeInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(BluetoothHidPairingInfoCount, 1023, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothAudioPairingInfoCount, 1024, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(BluetoothLePairingInfoCount, 1025, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(NANDPreEolInfo, 1026, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypA, 1027, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) diff --git a/utilities/erpt.py b/utilities/erpt.py index 94d0919cd..fb697cb13 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -238,7 +238,10 @@ CATEGORIES = { 139 : 'EthernetAdapterOUIInfo', 140 : 'NANDTypeInfo', 141 : 'MicroSDTypeInfo', + 142 : 'AttachmentFileInfo', 1000 : 'TestNx', + 1001 : 'NANDTypeInfo', + 1002 : 'NANDExtendedCsd', } FIELD_TYPES = { From 77d17dc4ff62ce4c86bc66953a09f9fba8394d64 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 8 Oct 2024 16:12:56 -0700 Subject: [PATCH 137/238] emummc: update for 19.0.0 --- emummc/README.md | 2 +- emummc/source/FS/FS_offsets.c | 8 ++++ emummc/source/FS/FS_versions.h | 3 ++ emummc/source/FS/offsets/1900.h | 59 +++++++++++++++++++++++++++ emummc/source/FS/offsets/1900_exfat.h | 59 +++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 emummc/source/FS/offsets/1900.h create mode 100644 emummc/source/FS/offsets/1900_exfat.h diff --git a/emummc/README.md b/emummc/README.md index f01783ba5..cada2cdb5 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 18.1.0** +**1.0.0 - 19.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index b2059c092..64ac34562 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -73,6 +73,8 @@ #include "offsets/1800_exfat.h" #include "offsets/1810.h" #include "offsets/1810_exfat.h" +#include "offsets/1900.h" +#include "offsets/1900_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -157,6 +159,8 @@ DEFINE_OFFSET_STRUCT(_1800); DEFINE_OFFSET_STRUCT(_1800_EXFAT); DEFINE_OFFSET_STRUCT(_1810); DEFINE_OFFSET_STRUCT(_1810_EXFAT); +DEFINE_OFFSET_STRUCT(_1900); +DEFINE_OFFSET_STRUCT(_1900_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -274,6 +278,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1810)); case FS_VER_18_1_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1810_EXFAT)); + case FS_VER_19_0_0: + return &(GET_OFFSET_STRUCT_NAME(_1900)); + case FS_VER_19_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_1900_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index ec4f9ecf8..6eebac186 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -107,6 +107,9 @@ enum FS_VER FS_VER_18_1_0, FS_VER_18_1_0_EXFAT, + FS_VER_19_0_0, + FS_VER_19_0_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/1900.h b/emummc/source/FS/offsets/1900.h new file mode 100644 index 000000000..82ffd0f94 --- /dev/null +++ b/emummc/source/FS/offsets/1900.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1900_H__ +#define __FS_1900_H__ + +// Accessor vtable getters +#define FS_OFFSET_1900_SDMMC_ACCESSOR_GC 0x195C00 +#define FS_OFFSET_1900_SDMMC_ACCESSOR_SD 0x197F80 +#define FS_OFFSET_1900_SDMMC_ACCESSOR_NAND 0x1963B0 + +// Hooks +#define FS_OFFSET_1900_SDMMC_WRAPPER_READ 0x191A70 +#define FS_OFFSET_1900_SDMMC_WRAPPER_WRITE 0x191AD0 +#define FS_OFFSET_1900_RTLD 0x275F0 +#define FS_OFFSET_1900_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x50))) + +#define FS_OFFSET_1900_CLKRST_SET_MIN_V_CLK_RATE 0x1B3880 + +// Misc funcs +#define FS_OFFSET_1900_LOCK_MUTEX 0x18AC20 +#define FS_OFFSET_1900_UNLOCK_MUTEX 0x18AC70 + +#define FS_OFFSET_1900_SDMMC_WRAPPER_CONTROLLER_OPEN 0x191A30 +#define FS_OFFSET_1900_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x191A50 + +// Misc Data +#define FS_OFFSET_1900_SD_MUTEX 0xFE1408 +#define FS_OFFSET_1900_NAND_MUTEX 0xFDCB60 +#define FS_OFFSET_1900_ACTIVE_PARTITION 0xFDCBA0 +#define FS_OFFSET_1900_SDMMC_DAS_HANDLE 0xFC1908 + +// NOPs +#define FS_OFFSET_1900_SD_DAS_INIT 0x260C4 + +// Nintendo Paths +#define FS_OFFSET_1900_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00067FC8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00075D6C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007D1E8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00092818, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1900_H__ diff --git a/emummc/source/FS/offsets/1900_exfat.h b/emummc/source/FS/offsets/1900_exfat.h new file mode 100644 index 000000000..2bbf0c899 --- /dev/null +++ b/emummc/source/FS/offsets/1900_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_1900_EXFAT_H__ +#define __FS_1900_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_1900_EXFAT_SDMMC_ACCESSOR_GC 0x1A1430 +#define FS_OFFSET_1900_EXFAT_SDMMC_ACCESSOR_SD 0x1A37B0 +#define FS_OFFSET_1900_EXFAT_SDMMC_ACCESSOR_NAND 0x1A1BE0 + +// Hooks +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_READ 0x19D2A0 +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_WRITE 0x19D300 +#define FS_OFFSET_1900_EXFAT_RTLD 0x275F0 +#define FS_OFFSET_1900_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x50))) + +#define FS_OFFSET_1900_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1BF0B0 + +// Misc funcs +#define FS_OFFSET_1900_EXFAT_LOCK_MUTEX 0x196450 +#define FS_OFFSET_1900_EXFAT_UNLOCK_MUTEX 0x1964A0 + +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x19D260 +#define FS_OFFSET_1900_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x19D280 + +// Misc Data +#define FS_OFFSET_1900_EXFAT_SD_MUTEX 0xFF4408 +#define FS_OFFSET_1900_EXFAT_NAND_MUTEX 0xFEFB60 +#define FS_OFFSET_1900_EXFAT_ACTIVE_PARTITION 0xFEFBA0 +#define FS_OFFSET_1900_EXFAT_SDMMC_DAS_HANDLE 0xFCF908 + +// NOPs +#define FS_OFFSET_1900_EXFAT_SD_DAS_INIT 0x260C4 + +// Nintendo Paths +#define FS_OFFSET_1900_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x00067FC8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x00075D6C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0007D1E8, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00092818, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_1900_EXFAT_H__ From 5de551db29a92d5b88b4357499563242cc55c9a0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 11:04:43 -0700 Subject: [PATCH 138/238] kern: add InfoType_TransferMemoryHint --- .../mesosphere/kern_k_transfer_memory.hpp | 16 ++++++++++++++++ .../libmesosphere/source/svc/kern_svc_info.cpp | 13 +++++++++++++ .../include/vapours/svc/svc_types_common.hpp | 2 ++ 3 files changed, 31 insertions(+) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp index cd88f3abf..c34ceb8c3 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_transfer_memory.hpp @@ -48,6 +48,22 @@ namespace ams::kern { KProcess *GetOwner() const { return m_owner; } KProcessAddress GetSourceAddress() { return m_address; } size_t GetSize() const { return m_is_initialized ? GetReference(m_page_group).GetNumPages() * PageSize : 0; } + + constexpr uintptr_t GetHint() const { + /* Get memory size. */ + const size_t size = this->GetSize(); + + /* TODO: Is this architecture specific? */ + if (size >= 2_MB) { + return GetInteger(m_address) & (2_MB - 1); + } else if (size >= 64_KB) { + return GetInteger(m_address) & (64_KB - 1); + } else if (size >= 4_KB) { + return GetInteger(m_address) & (4_KB - 1); + } else { + return 0; + } + } }; } diff --git a/libraries/libmesosphere/source/svc/kern_svc_info.cpp b/libraries/libmesosphere/source/svc/kern_svc_info.cpp index e9153edbb..ec41ef59a 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_info.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_info.cpp @@ -314,6 +314,19 @@ namespace ams::kern::svc { *out = io_region->GetHint(); } break; + case ams::svc::InfoType_TransferMemoryHint: + { + /* Verify the sub-type is valid. */ + R_UNLESS(info_subtype == 0, svc::ResultInvalidCombination()); + + /* Get the transfer memory from its handle. */ + KScopedAutoObject transfer_memory = GetCurrentProcess().GetHandleTable().GetObject(handle); + R_UNLESS(transfer_memory.IsNotNull(), svc::ResultInvalidHandle()); + + /* Get the transfer memory's address hint. */ + *out = transfer_memory->GetHint(); + } + break; case ams::svc::InfoType_MesosphereMeta: { /* Verify the handle is invalid. */ diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index 5668cd2dd..0247f59b9 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -191,6 +191,8 @@ namespace ams::svc { InfoType_IsSvcPermitted = 26, InfoType_IoRegionHint = 27, InfoType_AliasRegionExtraSize = 28, + /* ... */ + InfoType_TransferMemoryHint = 34, InfoType_MesosphereMeta = 65000, InfoType_MesosphereCurrentProcess = 65001, From a0ad3ef9498e64d5d0e1a72b9c6e739e05af3ebc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 11:36:17 -0700 Subject: [PATCH 139/238] kern/svc: update WaitForAddress to support 64-bit WaitIfEqual --- .../arm64/kern_userspace_memory_access.hpp | 1 + .../mesosphere/kern_k_address_arbiter.hpp | 11 +-- .../include/mesosphere/kern_k_process.hpp | 2 +- .../arm64/kern_userspace_memory_access_asm.s | 14 ++++ .../arm64/svc/kern_svc_address_arbiter_asm.s | 67 +++++++++++++++++++ .../source/arch/arm64/svc/kern_svc_tables.cpp | 8 +++ .../source/kern_k_address_arbiter.cpp | 51 ++++++++++++++ .../source/svc/kern_svc_address_arbiter.cpp | 17 +++-- .../svc/svc_stratosphere_shims.hpp | 2 +- .../vapours/svc/svc_definition_macro.hpp | 2 +- .../include/vapours/svc/svc_types_common.hpp | 1 + 11 files changed, 163 insertions(+), 13 deletions(-) create mode 100644 libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp index 202be5f51..9e0c1844e 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp @@ -25,6 +25,7 @@ namespace ams::kern::arch::arm64 { static bool CopyMemoryFromUser(void *dst, const void *src, size_t size); static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size); static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src); static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src); static s32 CopyStringFromUser(void *dst, const void *src, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp index 4066de80d..f4ef74e6b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_arbiter.hpp @@ -39,14 +39,16 @@ namespace ams::kern { } } - Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s32 value, s64 timeout) { + Result WaitForAddress(uintptr_t addr, ams::svc::ArbitrationType type, s64 value, s64 timeout) { switch (type) { case ams::svc::ArbitrationType_WaitIfLessThan: - R_RETURN(this->WaitIfLessThan(addr, value, false, timeout)); + R_RETURN(this->WaitIfLessThan(addr, static_cast(value), false, timeout)); case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan: - R_RETURN(this->WaitIfLessThan(addr, value, true, timeout)); + R_RETURN(this->WaitIfLessThan(addr, static_cast(value), true, timeout)); case ams::svc::ArbitrationType_WaitIfEqual: - R_RETURN(this->WaitIfEqual(addr, value, timeout)); + R_RETURN(this->WaitIfEqual(addr, static_cast(value), timeout)); + case ams::svc::ArbitrationType_WaitIfEqual64: + R_RETURN(this->WaitIfEqual64(addr, value, timeout)); MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } } @@ -56,6 +58,7 @@ namespace ams::kern { Result SignalAndModifyByWaitingCountIfEqual(uintptr_t addr, s32 value, s32 count); Result WaitIfLessThan(uintptr_t addr, s32 value, bool decrement, s64 timeout); Result WaitIfEqual(uintptr_t addr, s32 value, s64 timeout); + Result WaitIfEqual64(uintptr_t addr, s64 value, s64 timeout); }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 3258d41e2..5a37e3a6b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -360,7 +360,7 @@ namespace ams::kern { R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count)); } - Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s32 value, s64 timeout) { + Result WaitAddressArbiter(uintptr_t address, ams::svc::ArbitrationType arb_type, s64 value, s64 timeout) { R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout)); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s index 5b1fd4a51..e697fde3c 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s @@ -126,6 +126,20 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: mov x0, #1 ret +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, %function +.balign 0x10 +_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv: + /* Just load and store a u64. */ + ldtr x2, [x1] + str x2, [x0] + + /* We're done. */ + mov x0, #1 + ret + /* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */ .section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits .global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s new file mode 100644 index 000000000..f82db4454 --- /dev/null +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_address_arbiter_asm.s @@ -0,0 +1,67 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* ams::kern::svc::CallWaitForAddress64From32() */ +.section .text._ZN3ams4kern3svc26CallWaitForAddress64From32Ev, "ax", %progbits +.global _ZN3ams4kern3svc26CallWaitForAddress64From32Ev +.type _ZN3ams4kern3svc26CallWaitForAddress64From32Ev, %function +_ZN3ams4kern3svc26CallWaitForAddress64From32Ev: + /* Save LR + callee-save registers. */ + str x30, [sp, #-16]! + stp x6, x7, [sp, #-16]! + + /* Gather the arguments into correct registers. */ + /* NOTE: This has to be manually implemented via asm, */ + /* in order to avoid breaking ABI with pre-19.0.0. */ + orr x2, x2, x5, lsl#32 + orr x3, x3, x4, lsl#32 + + /* Invoke the svc handler. */ + bl _ZN3ams4kern3svc22WaitForAddress64From32ENS_3svc7AddressENS2_15ArbitrationTypeEll + + /* Clean up registers. */ + mov x1, xzr + mov x2, xzr + mov x3, xzr + mov x4, xzr + mov x5, xzr + + ldp x6, x7, [sp], #0x10 + ldr x30, [sp], #0x10 + ret + +/* ams::kern::svc::CallWaitForAddress64() */ +.section .text._ZN3ams4kern3svc20CallWaitForAddress64Ev, "ax", %progbits +.global _ZN3ams4kern3svc20CallWaitForAddress64Ev +.type _ZN3ams4kern3svc20CallWaitForAddress64Ev, %function +_ZN3ams4kern3svc20CallWaitForAddress64Ev: + /* Save LR + FP. */ + stp x29, x30, [sp, #-16]! + + /* Invoke the svc handler. */ + bl _ZN3ams4kern3svc22WaitForAddress64From32ENS_3svc7AddressENS2_15ArbitrationTypeEll + + /* Clean up registers. */ + mov x1, xzr + mov x2, xzr + mov x3, xzr + mov x4, xzr + mov x5, xzr + mov x6, xzr + mov x7, xzr + + ldp x29, x30, [sp], #0x10 + ret diff --git a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp index cb9151823..cfc0cb7c5 100644 --- a/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp +++ b/libraries/libmesosphere/source/arch/arm64/svc/kern_svc_tables.cpp @@ -36,6 +36,10 @@ namespace ams::kern::svc { /* Declare special prototype for (unsupported) CallCallSecureMonitor64From32. */ void CallCallSecureMonitor64From32(); + /* Declare special prototypes for WaitForAddress. */ + void CallWaitForAddress64(); + void CallWaitForAddress64From32(); + namespace { #ifndef MESOSPHERE_USE_STUBBED_SVC_TABLES @@ -81,6 +85,8 @@ namespace ams::kern::svc { table[svc::SvcId_CallSecureMonitor] = CallCallSecureMonitor64From32; + table[svc::SvcId_WaitForAddress] = CallWaitForAddress64From32; + return table; }(); @@ -97,6 +103,8 @@ namespace ams::kern::svc { table[svc::SvcId_ReturnFromException] = CallReturnFromException64; + table[svc::SvcId_WaitForAddress] = CallWaitForAddress64; + return table; }(); diff --git a/libraries/libmesosphere/source/kern_k_address_arbiter.cpp b/libraries/libmesosphere/source/kern_k_address_arbiter.cpp index c084c9053..66c0c1645 100644 --- a/libraries/libmesosphere/source/kern_k_address_arbiter.cpp +++ b/libraries/libmesosphere/source/kern_k_address_arbiter.cpp @@ -23,6 +23,10 @@ namespace ams::kern { return UserspaceAccess::CopyMemoryFromUserSize32Bit(out, GetVoidPointer(address)); } + ALWAYS_INLINE bool ReadFromUser(s64 *out, KProcessAddress address) { + return UserspaceAccess::CopyMemoryFromUserSize64Bit(out, GetVoidPointer(address)); + } + ALWAYS_INLINE bool DecrementIfLessThan(s32 *out, KProcessAddress address, s32 value) { /* NOTE: If scheduler lock is not held here, interrupt disable is required. */ /* KScopedInterruptDisable di; */ @@ -279,4 +283,51 @@ namespace ams::kern { R_RETURN(cur_thread->GetWaitResult()); } + Result KAddressArbiter::WaitIfEqual64(uintptr_t addr, s64 value, s64 timeout) { + /* Prepare to wait. */ + KThread *cur_thread = GetCurrentThreadPointer(); + KHardwareTimer *timer; + ThreadQueueImplForKAddressArbiter wait_queue(std::addressof(m_tree)); + + { + KScopedSchedulerLockAndSleep slp(std::addressof(timer), cur_thread, timeout); + + /* Check that the thread isn't terminating. */ + if (cur_thread->IsTerminationRequested()) { + slp.CancelSleep(); + R_THROW(svc::ResultTerminationRequested()); + } + + /* Read the value from userspace. */ + s64 user_value; + if (!ReadFromUser(std::addressof(user_value), addr)) { + slp.CancelSleep(); + R_THROW(svc::ResultInvalidCurrentMemory()); + } + + /* Check that the value is equal. */ + if (value != user_value) { + slp.CancelSleep(); + R_THROW(svc::ResultInvalidState()); + } + + /* Check that the timeout is non-zero. */ + if (timeout == 0) { + slp.CancelSleep(); + R_THROW(svc::ResultTimedOut()); + } + + /* Set the arbiter. */ + cur_thread->SetAddressArbiter(std::addressof(m_tree), addr); + m_tree.insert(*cur_thread); + + /* Wait for the thread to finish. */ + wait_queue.SetHardwareTimer(timer); + cur_thread->BeginWait(std::addressof(wait_queue)); + } + + /* Get the wait result. */ + R_RETURN(cur_thread->GetWaitResult()); + } + } diff --git a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp index 68eb61e84..2b495ad45 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_address_arbiter.cpp @@ -41,17 +41,22 @@ namespace ams::kern::svc { case ams::svc::ArbitrationType_WaitIfLessThan: case ams::svc::ArbitrationType_DecrementAndWaitIfLessThan: case ams::svc::ArbitrationType_WaitIfEqual: + case ams::svc::ArbitrationType_WaitIfEqual64: return true; default: return false; } } - Result WaitForAddress(uintptr_t address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + Result WaitForAddress(uintptr_t address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { /* Validate input. */ - R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); - R_UNLESS(util::IsAligned(address, sizeof(int32_t)), svc::ResultInvalidAddress()); - R_UNLESS(IsValidArbitrationType(arb_type), svc::ResultInvalidEnumValue()); + R_UNLESS(AMS_LIKELY(!IsKernelAddress(address)), svc::ResultInvalidCurrentMemory()); + if (arb_type == ams::svc::ArbitrationType_WaitIfEqual64) { + R_UNLESS(util::IsAligned(address, sizeof(int64_t)), svc::ResultInvalidAddress()); + } else { + R_UNLESS(util::IsAligned(address, sizeof(int32_t)), svc::ResultInvalidAddress()); + } + R_UNLESS(IsValidArbitrationType(arb_type), svc::ResultInvalidEnumValue()); /* Convert timeout from nanoseconds to ticks. */ s64 timeout; @@ -85,7 +90,7 @@ namespace ams::kern::svc { /* ============================= 64 ABI ============================= */ - Result WaitForAddress64(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + Result WaitForAddress64(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { R_RETURN(WaitForAddress(address, arb_type, value, timeout_ns)); } @@ -95,7 +100,7 @@ namespace ams::kern::svc { /* ============================= 64From32 ABI ============================= */ - Result WaitForAddress64From32(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + Result WaitForAddress64From32(ams::svc::Address address, ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { R_RETURN(WaitForAddress(address, arb_type, value, timeout_ns)); } diff --git a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp index b724ce5f1..d68a56f33 100644 --- a/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp +++ b/libraries/libstratosphere/include/stratosphere/svc/svc_stratosphere_shims.hpp @@ -231,7 +231,7 @@ R_RETURN(::svcGetThreadContext3(reinterpret_cast<::ThreadContext *>(out_context.GetPointerUnsafe()), thread_handle)); } - ALWAYS_INLINE Result WaitForAddress(::ams::svc::Address address, ::ams::svc::ArbitrationType arb_type, int32_t value, int64_t timeout_ns) { + ALWAYS_INLINE Result WaitForAddress(::ams::svc::Address address, ::ams::svc::ArbitrationType arb_type, int64_t value, int64_t timeout_ns) { R_RETURN(::svcWaitForAddress(reinterpret_cast(static_cast(address)), arb_type, value, timeout_ns)); } diff --git a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp index 0f1c57783..7e4121aa3 100644 --- a/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_definition_macro.hpp @@ -67,7 +67,7 @@ HANDLER(0x31, Result, GetResourceLimitCurrentValue, OUTPUT(int64_t, out_current_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ HANDLER(0x32, Result, SetThreadActivity, INPUT(::ams::svc::Handle, thread_handle), INPUT(::ams::svc::ThreadActivity, thread_activity)) \ HANDLER(0x33, Result, GetThreadContext3, OUTPTR(::ams::svc::ThreadContext, out_context), INPUT(::ams::svc::Handle, thread_handle)) \ - HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int32_t, value), INPUT(int64_t, timeout_ns)) \ + HANDLER(0x34, Result, WaitForAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::ArbitrationType, arb_type), INPUT(int64_t, value), INPUT(int64_t, timeout_ns)) \ HANDLER(0x35, Result, SignalToAddress, INPUT(::ams::svc::Address, address), INPUT(::ams::svc::SignalType, signal_type), INPUT(int32_t, value), INPUT(int32_t, count)) \ HANDLER(0x36, void, SynchronizePreemptionState) \ HANDLER(0x37, Result, GetResourceLimitPeakValue, OUTPUT(int64_t, out_peak_value), INPUT(::ams::svc::Handle, resource_limit_handle), INPUT(::ams::svc::LimitableResource, which)) \ diff --git a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp index 0247f59b9..21ab685d0 100644 --- a/libraries/libvapours/include/vapours/svc/svc_types_common.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_types_common.hpp @@ -263,6 +263,7 @@ namespace ams::svc { ArbitrationType_WaitIfLessThan = 0, ArbitrationType_DecrementAndWaitIfLessThan = 1, ArbitrationType_WaitIfEqual = 2, + ArbitrationType_WaitIfEqual64 = 3, }; enum YieldType : s64 { From 70bf8330701dc9147fc88cb7c72d026885d7cde7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 12:03:21 -0700 Subject: [PATCH 140/238] kern: KAddressSpaceInfo now takes CreateProcessFlags in getters --- .../mesosphere/kern_k_address_space_info.hpp | 4 +-- .../source/kern_k_address_space_info.cpp | 26 +++++++++++--- .../source/kern_k_initial_process_reader.cpp | 35 ++++++++++--------- .../source/kern_k_page_table_base.cpp | 4 +-- .../source/svc/kern_svc_process.cpp | 14 ++++---- 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp index 9e20dd254..8af8404cc 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp @@ -37,8 +37,8 @@ namespace ams::kern { size_t m_size; Type m_type; public: - static uintptr_t GetAddressSpaceStart(size_t width, Type type); - static size_t GetAddressSpaceSize(size_t width, Type type); + static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type); + static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type); static void SetAddressSpaceSize(size_t width, Type type, size_t size); diff --git a/libraries/libmesosphere/source/kern_k_address_space_info.cpp b/libraries/libmesosphere/source/kern_k_address_space_info.cpp index ef585eba8..b23f6e929 100644 --- a/libraries/libmesosphere/source/kern_k_address_space_info.cpp +++ b/libraries/libmesosphere/source/kern_k_address_space_info.cpp @@ -37,6 +37,24 @@ namespace ams::kern { { 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, }, }; + constexpr u8 FlagsToAddressSpaceWidthTable[4] = { + 32, 36, 32, 39 + }; + + constexpr size_t GetAddressSpaceWidth(ams::svc::CreateProcessFlag flags) { + /* Convert the input flags to an array index. */ + const size_t idx = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask) >> ams::svc::CreateProcessFlag_AddressSpaceShift; + MESOSPHERE_ABORT_UNLESS(idx < sizeof(FlagsToAddressSpaceWidthTable)); + + /* Return the width. */ + return FlagsToAddressSpaceWidthTable[idx]; + } + + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32Bit) == 32); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated) == 36); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) == 32); + static_assert(GetAddressSpaceWidth(ams::svc::CreateProcessFlag_AddressSpace64Bit) == 39); + KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) { for (auto &info : AddressSpaceInfos) { if (info.GetWidth() == width && info.GetType() == type) { @@ -48,12 +66,12 @@ namespace ams::kern { } - uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) { - return GetAddressSpaceInfo(width, type).GetAddress(); + uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { + return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress(); } - size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) { - return GetAddressSpaceInfo(width, type).GetSize(); + size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { + return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize(); } void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) { diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index c5ef13ac5..9c91889f9 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -193,40 +193,25 @@ namespace ams::kern { R_UNLESS(this->Is64Bit(), svc::ResultInvalidCombination()); } - using ASType = KAddressSpaceInfo::Type; - const uintptr_t start_address = rx_address; const uintptr_t end_address = bss_size > 0 ? bss_address + bss_size : rw_address + rw_size; - const size_t as_width = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? 39 : 36) : 32; - const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; - const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(as_width, as_type); - const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(as_width, as_type); - const uintptr_t map_end = map_start + map_size; MESOSPHERE_ABORT_UNLESS(start_address == 0); /* Default fields in parameter to zero. */ *out = {}; /* Set fields in parameter. */ - out->code_address = map_start + start_address; + out->code_address = 0; out->code_num_pages = util::AlignUp(end_address - start_address, PageSize) / PageSize; out->program_id = m_kip_header.GetProgramId(); out->version = m_kip_header.GetVersion(); out->flags = 0; out->reslimit = ams::svc::InvalidHandle; out->system_resource_num_pages = 0; - MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize)); /* Copy name field. */ m_kip_header.GetName(out->name, sizeof(out->name)); - /* Apply ASLR, if needed. */ - if (enable_aslr) { - const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment); - out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment; - out->flags |= ams::svc::CreateProcessFlag_EnableAslr; - } - /* Apply other flags. */ if (this->Is64Bit()) { out->flags |= ams::svc::CreateProcessFlag_Is64Bit; @@ -236,10 +221,28 @@ namespace ams::kern { } else { out->flags |= ams::svc::CreateProcessFlag_AddressSpace32Bit; } + if (enable_aslr) { + out->flags |= ams::svc::CreateProcessFlag_EnableAslr; + } /* All initial processes should disable device address space merge. */ out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; + /* Set and check code address. */ + using ASType = KAddressSpaceInfo::Type; + const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; + const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(out->flags), as_type); + const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(out->flags), as_type); + const uintptr_t map_end = map_start + map_size; + out->code_address = map_start + start_address; + MESOSPHERE_ABORT_UNLESS((out->code_address / PageSize) + out->code_num_pages <= (map_end / PageSize)); + + /* Apply ASLR, if needed. */ + if (enable_aslr) { + const size_t choices = (map_end / KernelAslrAlignment) - (util::AlignUp(out->code_address + out->code_num_pages * PageSize, KernelAslrAlignment) / KernelAslrAlignment); + out->code_address += KSystemControl::GenerateRandomRange(0, choices) * KernelAslrAlignment; + } + R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 2e90d924e..613dc0dbb 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -141,10 +141,10 @@ namespace ams::kern { /* Define helpers. */ auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type); + return KAddressSpaceInfo::GetAddressSpaceStart(flags, type); }; auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type); + return KAddressSpaceInfo::GetAddressSpaceSize(flags, type); }; /* Default to zero alias region extra size. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 76e36302b..5141a2c31 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -110,8 +110,8 @@ namespace ams::kern::svc { case ams::svc::CreateProcessFlag_AddressSpace32Bit: case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: { - map_start = KAddressSpaceInfo::GetAddressSpaceStart(32, KAddressSpaceInfo::Type_MapSmall); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(32, KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; @@ -120,8 +120,8 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(36, KAddressSpaceInfo::Type_MapSmall); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(36, KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } break; @@ -130,10 +130,10 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(39, KAddressSpaceInfo::Type_Map39Bit); - map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Map39Bit); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit); + map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit); - map_size = KAddressSpaceInfo::GetAddressSpaceSize(39, KAddressSpaceInfo::Type_Heap); + map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Heap); } break; default: From 753cf74bf2d0b1cf1353120be0053c17a92f5b67 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 12:44:11 -0700 Subject: [PATCH 141/238] kern: eliminate use of KMemoryInfo, shuffle KMemoryBlock fields --- .../mesosphere/kern_k_memory_block.hpp | 27 +- .../mesosphere/kern_k_page_table_base.hpp | 2 +- .../source/kern_k_memory_block_manager.cpp | 130 ++++---- .../source/kern_k_page_table_base.cpp | 296 ++++++++---------- 4 files changed, 196 insertions(+), 259 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index f021391e0..2847de337 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -200,7 +200,8 @@ namespace ams::kern { KMemoryBlockDisableMergeAttribute_DeviceLeft = (1u << 1), KMemoryBlockDisableMergeAttribute_IpcLeft = (1u << 2), KMemoryBlockDisableMergeAttribute_Locked = (1u << 3), - KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 4), + /* ... */ + KMemoryBlockDisableMergeAttribute_DeviceRight = (1u << 5), KMemoryBlockDisableMergeAttribute_AllLeft = KMemoryBlockDisableMergeAttribute_Normal | KMemoryBlockDisableMergeAttribute_DeviceLeft | KMemoryBlockDisableMergeAttribute_IpcLeft | KMemoryBlockDisableMergeAttribute_Locked, KMemoryBlockDisableMergeAttribute_AllRight = KMemoryBlockDisableMergeAttribute_DeviceRight, @@ -288,18 +289,18 @@ namespace ams::kern { class KMemoryBlock : public util::IntrusiveRedBlackTreeBaseNode { private: - u16 m_device_disable_merge_left_count; - u16 m_device_disable_merge_right_count; - KProcessAddress m_address; - size_t m_num_pages; - KMemoryState m_memory_state; - u16 m_ipc_lock_count; - u16 m_device_use_count; - u16 m_ipc_disable_merge_count; KMemoryPermission m_permission; KMemoryPermission m_original_permission; KMemoryAttribute m_attribute; KMemoryBlockDisableMergeAttribute m_disable_merge_attribute; + KProcessAddress m_address; + u32 m_num_pages; + KMemoryState m_memory_state; + u16 m_ipc_lock_count; + u16 m_ipc_disable_merge_count; + u16 m_device_use_count; + u16 m_device_disable_merge_left_count; + u16 m_device_disable_merge_right_count; public: static constexpr ALWAYS_INLINE int Compare(const KMemoryBlock &lhs, const KMemoryBlock &rhs) { if (lhs.GetAddress() < rhs.GetAddress()) { @@ -343,6 +344,10 @@ namespace ams::kern { return m_ipc_disable_merge_count; } + constexpr u16 GetDeviceUseCount() const { + return m_device_use_count; + } + constexpr KMemoryPermission GetPermission() const { return m_permission; } @@ -374,7 +379,7 @@ namespace ams::kern { public: explicit KMemoryBlock() { /* ... */ } - constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) + constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_device_disable_merge_left_count(), m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None), @@ -383,7 +388,7 @@ namespace ams::kern { /* ... */ } - constexpr void Initialize(KProcessAddress addr, size_t np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { + constexpr void Initialize(KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) { MESOSPHERE_ASSERT_THIS(); m_device_disable_merge_left_count = 0; m_device_disable_merge_right_count = 0; diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 99a27c6f9..8da4311df 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -318,7 +318,7 @@ namespace ams::kern { R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr)); } - Result CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const; + Result CheckMemoryState(KMemoryBlockManager::const_iterator it, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const; Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const; Result CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const; Result CheckMemoryState(size_t *out_blocks_needed, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr = DefaultMemoryIgnoreAttr) const { diff --git a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp index 4ba4a566a..2c5bd962d 100644 --- a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp @@ -54,11 +54,11 @@ namespace ams::kern { return "Unknown "; } - constexpr const char *GetMemoryPermissionString(const KMemoryInfo &info) { - if (info.m_state == KMemoryState_Free) { + constexpr const char *GetMemoryPermissionString(const KMemoryBlock &block) { + if (block.GetState() == KMemoryState_Free) { return " "; } else { - switch (info.m_permission) { + switch (block.GetPermission()) { case KMemoryPermission_UserReadExecute: return "r-x"; case KMemoryPermission_UserRead: @@ -71,19 +71,19 @@ namespace ams::kern { } } - void DumpMemoryInfo(const KMemoryInfo &info) { - const char *state = GetMemoryStateName(info.m_state); - const char *perm = GetMemoryPermissionString(info); - const uintptr_t start = info.GetAddress(); - const uintptr_t end = info.GetLastAddress(); - const size_t kb = info.GetSize() / 1_KB; + void DumpMemoryBlock(const KMemoryBlock &block) { + const char *state = GetMemoryStateName(block.GetState()); + const char *perm = GetMemoryPermissionString(block); + const uintptr_t start = GetInteger(block.GetAddress()); + const uintptr_t end = GetInteger(block.GetLastAddress()); + const size_t kb = block.GetSize() / 1_KB; - const char l = (info.m_attribute & KMemoryAttribute_Locked) ? 'L' : '-'; - const char i = (info.m_attribute & KMemoryAttribute_IpcLocked) ? 'I' : '-'; - const char d = (info.m_attribute & KMemoryAttribute_DeviceShared) ? 'D' : '-'; - const char u = (info.m_attribute & KMemoryAttribute_Uncached) ? 'U' : '-'; + const char l = (block.GetAttribute() & KMemoryAttribute_Locked) ? 'L' : '-'; + const char i = (block.GetAttribute() & KMemoryAttribute_IpcLocked) ? 'I' : '-'; + const char d = (block.GetAttribute() & KMemoryAttribute_DeviceShared) ? 'D' : '-'; + const char u = (block.GetAttribute() & KMemoryAttribute_Uncached) ? 'U' : '-'; - MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, info.m_ipc_lock_count, info.m_device_use_count); + MESOSPHERE_LOG("0x%10lx - 0x%10lx (%9zu KB) %s %s %c%c%c%c [%d, %d]\n", start, end, kb, perm, state, l, i, d, u, block.GetIpcLockCount(), block.GetDeviceUseCount()); } } @@ -123,15 +123,14 @@ namespace ams::kern { const KProcessAddress region_end = region_start + region_num_pages * PageSize; const KProcessAddress region_last = region_end - 1; for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend(); it++) { - const KMemoryInfo info = it->GetMemoryInfo(); - if (region_last < info.GetAddress()) { + if (region_last < it->GetAddress()) { break; } - if (info.m_state != KMemoryState_Free) { + if (it->GetState() != KMemoryState_Free) { continue; } - KProcessAddress area = (info.GetAddress() <= GetInteger(region_start)) ? region_start : info.GetAddress(); + KProcessAddress area = (it->GetAddress() <= GetInteger(region_start)) ? region_start : it->GetAddress(); area += guard_pages * PageSize; const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset; @@ -140,7 +139,7 @@ namespace ams::kern { const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize; const KProcessAddress area_last = area_end - 1; - if (info.GetAddress() <= GetInteger(area) && area < area_last && area_last <= region_last && GetInteger(area_last) <= info.GetLastAddress()) { + if (GetInteger(it->GetAddress()) <= GetInteger(area) && area < area_last && area_last <= region_last && GetInteger(area_last) <= GetInteger(it->GetLastAddress())) { return area; } } @@ -171,7 +170,7 @@ namespace ams::kern { it = prev; } - if (address + num_pages * PageSize < it->GetMemoryInfo().GetEndAddress()) { + if (address + num_pages * PageSize < it->GetEndAddress()) { break; } } @@ -189,43 +188,39 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); if (it->HasProperties(state, perm, attr)) { /* If we already have the right properties, just advance. */ - if (cur_address + remaining_size < cur_info.GetEndAddress()) { + if (cur_address + remaining_size < it->GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; - cur_address = cur_info.GetEndAddress(); + remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; + cur_address = it->GetEndAddress(); } } else { /* If we need to, create a new block before and insert it. */ - if (cur_info.GetAddress() != GetInteger(cur_address)) { + if (it->GetAddress() != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Update block state. */ it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); } it++; } @@ -245,42 +240,38 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); if (it->HasProperties(test_state, test_perm, test_attr) && !it->HasProperties(state, perm, attr)) { /* If we need to, create a new block before and insert it. */ - if (cur_info.GetAddress() != GetInteger(cur_address)) { + if (it->GetAddress() != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Update block state. */ it->Update(state, perm, attr, it->GetAddress() == address, set_disable_attr, clear_disable_attr); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); } else { /* If we already have the right properties, just advance. */ - if (cur_address + remaining_size < cur_info.GetEndAddress()) { + if (cur_address + remaining_size < it->GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; - cur_address = cur_info.GetEndAddress(); + remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; + cur_address = it->GetEndAddress(); } } it++; @@ -302,34 +293,30 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); /* If we need to, create a new block before and insert it. */ - if (cur_info.m_address != GetInteger(cur_address)) { + if (it->GetAddress() != cur_address) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { /* If we need to, create a new block after and insert it. */ KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Call the locked update function. */ - (std::addressof(*it)->*lock_func)(perm, cur_info.GetAddress() == address, cur_info.GetEndAddress() == end_address); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + (std::addressof(*it)->*lock_func)(perm, it->GetAddress() == address, it->GetEndAddress() == end_address); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); it++; } @@ -347,43 +334,39 @@ namespace ams::kern { while (remaining_pages > 0) { const size_t remaining_size = remaining_pages * PageSize; - KMemoryInfo cur_info = it->GetMemoryInfo(); if ((it->GetAttribute() & mask) != attr) { /* If we need to, create a new block before and insert it. */ - if (cur_info.GetAddress() != GetInteger(cur_address)) { + if (it->GetAddress() != GetInteger(cur_address)) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address); it = m_memory_block_tree.insert(*new_block); it++; - cur_info = it->GetMemoryInfo(); - cur_address = cur_info.GetAddress(); + cur_address = it->GetAddress(); } /* If we need to, create a new block after and insert it. */ - if (cur_info.GetSize() > remaining_size) { + if (it->GetSize() > remaining_size) { KMemoryBlock *new_block = allocator->Allocate(); it->Split(new_block, cur_address + remaining_size); it = m_memory_block_tree.insert(*new_block); - - cur_info = it->GetMemoryInfo(); } /* Update block state. */ it->UpdateAttribute(mask, attr); - cur_address += cur_info.GetSize(); - remaining_pages -= cur_info.GetNumPages(); + cur_address += it->GetSize(); + remaining_pages -= it->GetNumPages(); } else { /* If we already have the right attributes, just advance. */ - if (cur_address + remaining_size < cur_info.GetEndAddress()) { + if (cur_address + remaining_size < it->GetEndAddress()) { remaining_pages = 0; cur_address += remaining_size; } else { - remaining_pages = (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize; - cur_address = cur_info.GetEndAddress(); + remaining_pages = (cur_address + remaining_size - it->GetEndAddress()) / PageSize; + cur_address = it->GetEndAddress(); } } it++; @@ -401,8 +384,6 @@ namespace ams::kern { auto it = m_memory_block_tree.cbegin(); auto prev = it++; while (it != m_memory_block_tree.cend()) { - const KMemoryInfo prev_info = prev->GetMemoryInfo(); - const KMemoryInfo cur_info = it->GetMemoryInfo(); /* Sequential blocks which can be merged should be merged. */ if (prev->CanMergeWith(*it)) { @@ -410,17 +391,17 @@ namespace ams::kern { } /* Sequential blocks should be sequential. */ - if (prev_info.GetEndAddress() != cur_info.GetAddress()) { + if (prev->GetEndAddress() != it->GetAddress()) { return false; } /* If the block is ipc locked, it must have a count. */ - if ((cur_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && cur_info.m_ipc_lock_count == 0) { + if ((it->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && it->GetIpcLockCount() == 0) { return false; } /* If the block is device shared, it must have a count. */ - if ((cur_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && cur_info.m_device_use_count == 0) { + if ((it->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && it->GetDeviceUseCount() == 0) { return false; } @@ -430,14 +411,13 @@ namespace ams::kern { /* Our loop will miss checking the last block, potentially, so check it. */ if (prev != m_memory_block_tree.cend()) { - const KMemoryInfo prev_info = prev->GetMemoryInfo(); /* If the block is ipc locked, it must have a count. */ - if ((prev_info.m_attribute & KMemoryAttribute_IpcLocked) != 0 && prev_info.m_ipc_lock_count == 0) { + if ((prev->GetAttribute() & KMemoryAttribute_IpcLocked) != 0 && prev->GetIpcLockCount() == 0) { return false; } /* If the block is device shared, it must have a count. */ - if ((prev_info.m_attribute & KMemoryAttribute_DeviceShared) != 0 && prev_info.m_device_use_count == 0) { + if ((prev->GetAttribute() & KMemoryAttribute_DeviceShared) != 0 && prev->GetDeviceUseCount() == 0) { return false; } } @@ -450,7 +430,7 @@ namespace ams::kern { void KMemoryBlockManager::DumpBlocks() const { /* Dump each block. */ for (const auto &block : m_memory_block_tree) { - DumpMemoryInfo(block.GetMemoryInfo()); + DumpMemoryBlock(block); } } } diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 613dc0dbb..95bc983ca 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -664,11 +664,11 @@ namespace ams::kern { } } - Result KPageTableBase::CheckMemoryState(const KMemoryInfo &info, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const { + Result KPageTableBase::CheckMemoryState(KMemoryBlockManager::const_iterator it, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr) const { /* Validate the states match expectation. */ - R_UNLESS((info.m_state & state_mask) == state, svc::ResultInvalidCurrentMemory()); - R_UNLESS((info.m_permission & perm_mask) == perm, svc::ResultInvalidCurrentMemory()); - R_UNLESS((info.m_attribute & attr_mask) == attr, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetState() & state_mask) == state, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetPermission() & perm_mask) == perm, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetAttribute() & attr_mask) == attr, svc::ResultInvalidCurrentMemory()); R_SUCCEED(); } @@ -679,28 +679,26 @@ namespace ams::kern { /* Get information about the first block. */ const KProcessAddress last_addr = addr + size - 1; KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr); - KMemoryInfo info = it->GetMemoryInfo(); /* If the start address isn't aligned, we need a block. */ - const size_t blocks_for_start_align = (util::AlignDown(GetInteger(addr), PageSize) != info.GetAddress()) ? 1 : 0; + const size_t blocks_for_start_align = (util::AlignDown(GetInteger(addr), PageSize) != it->GetAddress()) ? 1 : 0; while (true) { /* Validate against the provided masks. */ - R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); + R_TRY(this->CheckMemoryState(it, state_mask, state, perm_mask, perm, attr_mask, attr)); /* Break once we're done. */ - if (last_addr <= info.GetLastAddress()) { + if (last_addr <= it->GetLastAddress()) { break; } /* Advance our iterator. */ it++; MESOSPHERE_ASSERT(it != m_memory_block_manager.cend()); - info = it->GetMemoryInfo(); } /* If the end address isn't aligned, we need a block. */ - const size_t blocks_for_end_align = (util::AlignUp(GetInteger(addr) + size, PageSize) != info.GetEndAddress()) ? 1 : 0; + const size_t blocks_for_end_align = (util::AlignUp(GetInteger(addr) + size, PageSize) != it->GetEndAddress()) ? 1 : 0; if (out_blocks_needed != nullptr) { *out_blocks_needed = blocks_for_start_align + blocks_for_end_align; @@ -712,31 +710,27 @@ namespace ams::kern { Result KPageTableBase::CheckMemoryState(KMemoryState *out_state, KMemoryPermission *out_perm, KMemoryAttribute *out_attr, size_t *out_blocks_needed, KMemoryBlockManager::const_iterator it, KProcessAddress last_addr, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, u32 ignore_attr) const { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - /* Get information about the first block. */ - KMemoryInfo info = it->GetMemoryInfo(); - /* Validate all blocks in the range have correct state. */ - const KMemoryState first_state = info.m_state; - const KMemoryPermission first_perm = info.m_permission; - const KMemoryAttribute first_attr = info.m_attribute; + const KMemoryState first_state = it->GetState(); + const KMemoryPermission first_perm = it->GetPermission(); + const KMemoryAttribute first_attr = it->GetAttribute(); while (true) { /* Validate the current block. */ - R_UNLESS(info.m_state == first_state, svc::ResultInvalidCurrentMemory()); - R_UNLESS(info.m_permission == first_perm, svc::ResultInvalidCurrentMemory()); - R_UNLESS((info.m_attribute | ignore_attr) == (first_attr | ignore_attr), svc::ResultInvalidCurrentMemory()); + R_UNLESS(it->GetState() == first_state, svc::ResultInvalidCurrentMemory()); + R_UNLESS(it->GetPermission() == first_perm, svc::ResultInvalidCurrentMemory()); + R_UNLESS((it->GetAttribute() | ignore_attr) == (first_attr | ignore_attr), svc::ResultInvalidCurrentMemory()); /* Validate against the provided masks. */ - R_TRY(this->CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); + R_TRY(this->CheckMemoryState(it, state_mask, state, perm_mask, perm, attr_mask, attr)); /* Break once we're done. */ - if (last_addr <= info.GetLastAddress()) { + if (last_addr <= it->GetLastAddress()) { break; } /* Advance our iterator. */ it++; MESOSPHERE_ASSERT(it != m_memory_block_manager.cend()); - info = it->GetMemoryInfo(); } /* Write output state. */ @@ -752,7 +746,7 @@ namespace ams::kern { /* If the end address isn't aligned, we need a block. */ if (out_blocks_needed != nullptr) { - const size_t blocks_for_end_align = (util::AlignDown(GetInteger(last_addr), PageSize) + PageSize != info.GetEndAddress()) ? 1 : 0; + const size_t blocks_for_end_align = (util::AlignDown(GetInteger(last_addr), PageSize) + PageSize != it->GetEndAddress()) ? 1 : 0; *out_blocks_needed = blocks_for_end_align; } @@ -1176,17 +1170,14 @@ namespace ams::kern { { KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(dst_address); while (true) { - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Check if the memory has code flag. */ - if ((info.GetState() & KMemoryState_FlagCode) != 0) { + if ((it->GetState() & KMemoryState_FlagCode) != 0) { any_code_pages = true; break; } /* Check if we're done. */ - if (dst_address + size - 1 <= info.GetLastAddress()) { + if (dst_address + size - 1 <= it->GetLastAddress()) { break; } @@ -1355,14 +1346,13 @@ namespace ams::kern { const size_t random_offset = KSystemControl::GenerateRandomRange(0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) * alignment; const KProcessAddress candidate = util::AlignDown(GetInteger(region_start + random_offset), alignment) + offset; - KMemoryInfo info; - ams::svc::PageInfo page_info; - MESOSPHERE_R_ABORT_UNLESS(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), candidate)); + KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate); + MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end()); - if (info.m_state != KMemoryState_Free) { continue; } + if (it->GetState() != KMemoryState_Free) { continue; } if (!(region_start <= candidate)) { continue; } - if (!(info.GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) { continue; } - if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= info.GetLastAddress())) { continue; } + if (!(it->GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) { continue; } + if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= it->GetLastAddress())) { continue; } if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= region_start + region_num_pages * PageSize - 1)) { continue; } address = candidate; @@ -1393,10 +1383,8 @@ namespace ams::kern { /* Iterate, counting blocks with the desired state. */ size_t total_size = 0; for (KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(m_address_space_start); it != m_memory_block_manager.end(); ++it) { - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - if (info.GetState() == state) { - total_size += info.GetSize(); + if (it->GetState() == state) { + total_size += it->GetSize(); } } @@ -1488,17 +1476,14 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Determine the range to map. */ - KProcessAddress map_address = std::max(info.GetAddress(), GetInteger(start_address)); - const KProcessAddress map_end_address = std::min(info.GetEndAddress(), GetInteger(end_address)); + KProcessAddress map_address = std::max(GetInteger(it->GetAddress()), GetInteger(start_address)); + const KProcessAddress map_end_address = std::min(GetInteger(it->GetEndAddress()), GetInteger(end_address)); MESOSPHERE_ABORT_UNLESS(map_end_address != map_address); /* Determine if we should disable head merge. */ - const bool disable_head_merge = info.GetAddress() >= GetInteger(start_address) && (info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Normal) != 0; - const KPageProperties map_properties = { info.GetPermission(), false, false, disable_head_merge ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; + const bool disable_head_merge = it->GetAddress() >= GetInteger(start_address) && (it->GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Normal) != 0; + const KPageProperties map_properties = { it->GetPermission(), false, false, disable_head_merge ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; /* While we have pages to map, map them. */ size_t map_pages = (map_end_address - map_address) / PageSize; @@ -1527,7 +1512,7 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } @@ -2032,19 +2017,18 @@ namespace ams::kern { address = util::AlignDown(GetInteger(address), PageSize); /* Verify that we can query the address. */ - KMemoryInfo info; - ams::svc::PageInfo page_info; - R_TRY(this->QueryInfoImpl(std::addressof(info), std::addressof(page_info), address)); + KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address); + R_UNLESS(it != m_memory_block_manager.end(), svc::ResultInvalidCurrentMemory()); /* Check the memory state. */ - R_TRY(this->CheckMemoryState(info, KMemoryState_FlagCanQueryPhysical, KMemoryState_FlagCanQueryPhysical, KMemoryPermission_UserReadExecute, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(it, KMemoryState_FlagCanQueryPhysical, KMemoryState_FlagCanQueryPhysical, KMemoryPermission_UserReadExecute, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); /* Prepare to traverse. */ KPhysicalAddress phys_addr; size_t phys_size; - KProcessAddress virt_addr = info.GetAddress(); - KProcessAddress end_addr = info.GetEndAddress(); + KProcessAddress virt_addr = it->GetAddress(); + KProcessAddress end_addr = it->GetEndAddress(); /* Perform traversal. */ { @@ -3854,27 +3838,25 @@ namespace ams::kern { /* Iterate, mapping as needed. */ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(aligned_src_start); while (true) { - const KMemoryInfo info = it->GetMemoryInfo(); - /* Validate the current block. */ - R_TRY(this->CheckMemoryState(info, test_state, test_state, test_perm, test_perm, test_attr_mask, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(it, test_state, test_state, test_perm, test_perm, test_attr_mask, KMemoryAttribute_None)); - if (mapping_src_start < mapping_src_end && GetInteger(mapping_src_start) < info.GetEndAddress() && info.GetAddress() < GetInteger(mapping_src_end)) { - const auto cur_start = info.GetAddress() >= GetInteger(mapping_src_start) ? info.GetAddress() : GetInteger(mapping_src_start); - const auto cur_end = mapping_src_last >= info.GetLastAddress() ? info.GetEndAddress() : GetInteger(mapping_src_end); + if (mapping_src_start < mapping_src_end && GetInteger(mapping_src_start) < GetInteger(it->GetEndAddress()) && GetInteger(it->GetAddress()) < GetInteger(mapping_src_end)) { + const auto cur_start = it->GetAddress() >= GetInteger(mapping_src_start) ? GetInteger(it->GetAddress()) : GetInteger(mapping_src_start); + const auto cur_end = mapping_src_last >= GetInteger(it->GetLastAddress()) ? GetInteger(it->GetEndAddress()) : GetInteger(mapping_src_end); const size_t cur_size = cur_end - cur_start; - if (info.GetAddress() < GetInteger(mapping_src_start)) { + if (GetInteger(it->GetAddress()) < GetInteger(mapping_src_start)) { ++blocks_needed; } - if (mapping_src_last < info.GetLastAddress()) { + if (mapping_src_last < GetInteger(it->GetLastAddress())) { ++blocks_needed; } /* Set the permissions on the block, if we need to. */ - if ((info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != src_perm) { - const DisableMergeAttribute head_body_attr = (GetInteger(mapping_src_start) >= info.GetAddress()) ? DisableMergeAttribute_DisableHeadAndBody : DisableMergeAttribute_None; - const DisableMergeAttribute tail_attr = (cur_end == GetInteger(mapping_src_end)) ? DisableMergeAttribute_DisableTail : DisableMergeAttribute_None; + if ((it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != src_perm) { + const DisableMergeAttribute head_body_attr = (GetInteger(mapping_src_start) >= GetInteger(it->GetAddress())) ? DisableMergeAttribute_DisableHeadAndBody : DisableMergeAttribute_None; + const DisableMergeAttribute tail_attr = (cur_end == GetInteger(mapping_src_end)) ? DisableMergeAttribute_DisableTail : DisableMergeAttribute_None; const KPageProperties properties = { src_perm, false, false, static_cast(head_body_attr | tail_attr) }; R_TRY(this->Operate(page_list, cur_start, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, false)); } @@ -3884,7 +3866,7 @@ namespace ams::kern { } /* If the block is at the end, we're done. */ - if (aligned_src_last <= info.GetLastAddress()) { + if (aligned_src_last <= GetInteger(it->GetLastAddress())) { break; } @@ -4248,56 +4230,50 @@ namespace ams::kern { const auto mapped_last = mapped_end - 1; /* Get current and next iterators. */ - KMemoryBlockManager::const_iterator start_it = m_memory_block_manager.FindIterator(mapping_start); - KMemoryBlockManager::const_iterator next_it = start_it; + KMemoryBlockManager::const_iterator cur_it = m_memory_block_manager.FindIterator(mapping_start); + KMemoryBlockManager::const_iterator next_it = cur_it; ++next_it; - /* Get the current block info. */ - KMemoryInfo cur_info = start_it->GetMemoryInfo(); - /* Create tracking variables. */ - KProcessAddress cur_address = cur_info.GetAddress(); - size_t cur_size = cur_info.GetSize(); - bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission(); - bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1; - bool first = cur_info.GetIpcDisableMergeCount() == 1 && (cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; + KProcessAddress cur_address = cur_it->GetAddress(); + size_t cur_size = cur_it->GetSize(); + bool cur_perm_eq = cur_it->GetPermission() == cur_it->GetOriginalPermission(); + bool cur_needs_set_perm = !cur_perm_eq && cur_it->GetIpcLockCount() == 1; + bool first = cur_it->GetIpcDisableMergeCount() == 1 && (cur_it->GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; while ((GetInteger(cur_address) + cur_size - 1) < mapped_last) { /* Check that we have a next block. */ MESOSPHERE_ABORT_UNLESS(next_it != m_memory_block_manager.end()); - /* Get the next info. */ - const KMemoryInfo next_info = next_it->GetMemoryInfo(); - /* Check if we can consolidate the next block's permission set with the current one. */ - const bool next_perm_eq = next_info.GetPermission() == next_info.GetOriginalPermission(); - const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1; - if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) { + const bool next_perm_eq = next_it->GetPermission() == next_it->GetOriginalPermission(); + const bool next_needs_set_perm = !next_perm_eq && next_it->GetIpcLockCount() == 1; + if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_it->GetOriginalPermission() == next_it->GetOriginalPermission()) { /* We can consolidate the reprotection for the current and next block into a single call. */ - cur_size += next_info.GetSize(); + cur_size += next_it->GetSize(); } else { /* We have to operate on the current block. */ if ((cur_needs_set_perm || first) && !cur_perm_eq) { - const KPageProperties properties = { cur_info.GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, true)); } /* Advance. */ - cur_address = next_info.GetAddress(); - cur_size = next_info.GetSize(); + cur_address = next_it->GetAddress(); + cur_size = next_it->GetSize(); first = false; } /* Advance. */ - cur_info = next_info; cur_perm_eq = next_perm_eq; cur_needs_set_perm = next_needs_set_perm; - ++next_it; + + cur_it = next_it++; } /* Process the last block. */ if ((first || cur_needs_set_perm) && !cur_perm_eq) { - const KPageProperties properties = { cur_info.GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableAndMergeHeadBodyTail : DisableMergeAttribute_None }; MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, true)); } } @@ -4306,41 +4282,37 @@ namespace ams::kern { /* Iterate, reprotecting as needed. */ { /* Get current and next iterators. */ - KMemoryBlockManager::const_iterator start_it = m_memory_block_manager.FindIterator(mapping_start); - KMemoryBlockManager::const_iterator next_it = start_it; + KMemoryBlockManager::const_iterator cur_it = m_memory_block_manager.FindIterator(mapping_start); + KMemoryBlockManager::const_iterator next_it = cur_it; ++next_it; /* Validate the current block. */ - KMemoryInfo cur_info = start_it->GetMemoryInfo(); - MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(cur_info, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); + MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(cur_it, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); /* Create tracking variables. */ - KProcessAddress cur_address = cur_info.GetAddress(); - size_t cur_size = cur_info.GetSize(); - bool cur_perm_eq = cur_info.GetPermission() == cur_info.GetOriginalPermission(); - bool cur_needs_set_perm = !cur_perm_eq && cur_info.GetIpcLockCount() == 1; - bool first = cur_info.GetIpcDisableMergeCount() == 1 && (cur_info.GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; + KProcessAddress cur_address = cur_it->GetAddress(); + size_t cur_size = cur_it->GetSize(); + bool cur_perm_eq = cur_it->GetPermission() == cur_it->GetOriginalPermission(); + bool cur_needs_set_perm = !cur_perm_eq && cur_it->GetIpcLockCount() == 1; + bool first = cur_it->GetIpcDisableMergeCount() == 1 && (cur_it->GetDisableMergeAttribute() & KMemoryBlockDisableMergeAttribute_Locked) == 0; while ((cur_address + cur_size - 1) < mapping_last) { /* Check that we have a next block. */ MESOSPHERE_ABORT_UNLESS(next_it != m_memory_block_manager.end()); - /* Get the next info. */ - const KMemoryInfo next_info = next_it->GetMemoryInfo(); - /* Validate the next block. */ - MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(next_info, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); + MESOSPHERE_R_ABORT_UNLESS(this->CheckMemoryState(next_it, test_state, test_state, KMemoryPermission_None, KMemoryPermission_None, test_attr_mask | KMemoryAttribute_IpcLocked, KMemoryAttribute_IpcLocked)); /* Check if we can consolidate the next block's permission set with the current one. */ - const bool next_perm_eq = next_info.GetPermission() == next_info.GetOriginalPermission(); - const bool next_needs_set_perm = !next_perm_eq && next_info.GetIpcLockCount() == 1; - if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_info.GetOriginalPermission() == next_info.GetOriginalPermission()) { + const bool next_perm_eq = next_it->GetPermission() == next_it->GetOriginalPermission(); + const bool next_needs_set_perm = !next_perm_eq && next_it->GetIpcLockCount() == 1; + if (cur_perm_eq == next_perm_eq && cur_needs_set_perm == next_needs_set_perm && cur_it->GetOriginalPermission() == next_it->GetOriginalPermission()) { /* We can consolidate the reprotection for the current and next block into a single call. */ - cur_size += next_info.GetSize(); + cur_size += next_it->GetSize(); } else { /* We have to operate on the current block. */ if ((cur_needs_set_perm || first) && !cur_perm_eq) { - const KPageProperties properties = { cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.GetPermission(), false, false, first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None }; + const KPageProperties properties = { cur_needs_set_perm ? cur_it->GetOriginalPermission() : cur_it->GetPermission(), false, false, first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None }; R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, false)); } @@ -4348,24 +4320,24 @@ namespace ams::kern { mapped_size += cur_size; /* Advance. */ - cur_address = next_info.GetAddress(); - cur_size = next_info.GetSize(); + cur_address = next_it->GetAddress(); + cur_size = next_it->GetSize(); first = false; } /* Advance. */ - cur_info = next_info; cur_perm_eq = next_perm_eq; cur_needs_set_perm = next_needs_set_perm; - ++next_it; + + cur_it = next_it++; } /* Process the last block. */ - const auto lock_count = cur_info.GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); + const auto lock_count = cur_it->GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); if ((first || cur_needs_set_perm || (lock_count == 1)) && !cur_perm_eq) { const DisableMergeAttribute head_body_attr = first ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None; const DisableMergeAttribute tail_attr = lock_count == 1 ? DisableMergeAttribute_EnableTail : DisableMergeAttribute_None; - const KPageProperties properties = { cur_needs_set_perm ? cur_info.GetOriginalPermission() : cur_info.GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; + const KPageProperties properties = { cur_needs_set_perm ? cur_it->GetOriginalPermission() : cur_it->GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; R_TRY(this->Operate(updater.GetPageList(), cur_address, cur_size / PageSize, Null, false, properties, OperationType_ChangePermissions, false)); } } @@ -4398,38 +4370,36 @@ namespace ams::kern { /* Iterate over blocks, fixing permissions. */ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(address); while (true) { - const KMemoryInfo info = it->GetMemoryInfo(); - - const auto cur_start = info.GetAddress() >= GetInteger(src_map_start) ? info.GetAddress() : GetInteger(src_map_start); - const auto cur_end = src_map_last <= info.GetLastAddress() ? src_map_end : info.GetEndAddress(); + const auto cur_start = it->GetAddress() >= GetInteger(src_map_start) ? it->GetAddress() : GetInteger(src_map_start); + const auto cur_end = src_map_last <= it->GetLastAddress() ? src_map_end : it->GetEndAddress(); /* If we can, fix the protections on the block. */ - if ((info.GetIpcLockCount() == 0 && (info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) || - (info.GetIpcLockCount() != 0 && (info.GetOriginalPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm)) + if ((it->GetIpcLockCount() == 0 && (it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) || + (it->GetIpcLockCount() != 0 && (it->GetOriginalPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm)) { /* Check if we actually need to fix the protections on the block. */ - if (cur_end == src_map_end || info.GetAddress() <= GetInteger(src_map_start) || (info.GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) { - const bool start_nc = (info.GetAddress() == GetInteger(src_map_start)) ? ((info.GetDisableMergeAttribute() & (KMemoryBlockDisableMergeAttribute_Locked | KMemoryBlockDisableMergeAttribute_IpcLeft)) == 0) : info.GetAddress() <= GetInteger(src_map_start); + if (cur_end == src_map_end || it->GetAddress() <= GetInteger(src_map_start) || (it->GetPermission() & KMemoryPermission_IpcLockChangeMask) != prot_perm) { + const bool start_nc = (it->GetAddress() == GetInteger(src_map_start)) ? ((it->GetDisableMergeAttribute() & (KMemoryBlockDisableMergeAttribute_Locked | KMemoryBlockDisableMergeAttribute_IpcLeft)) == 0) : it->GetAddress() <= GetInteger(src_map_start); const DisableMergeAttribute head_body_attr = start_nc ? DisableMergeAttribute_EnableHeadAndBody : DisableMergeAttribute_None; DisableMergeAttribute tail_attr; - if (cur_end == src_map_end && info.GetEndAddress() == src_map_end) { + if (cur_end == src_map_end && it->GetEndAddress() == src_map_end) { auto next_it = it; ++next_it; - const auto lock_count = info.GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); + const auto lock_count = it->GetIpcLockCount() + (next_it != m_memory_block_manager.end() ? (next_it->GetIpcDisableMergeCount() - next_it->GetIpcLockCount()) : 0); tail_attr = lock_count == 0 ? DisableMergeAttribute_EnableTail : DisableMergeAttribute_None; } else { tail_attr = DisableMergeAttribute_None; } - const KPageProperties properties = { info.GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; + const KPageProperties properties = { it->GetPermission(), false, false, static_cast(head_body_attr | tail_attr) }; MESOSPHERE_R_ABORT_UNLESS(this->Operate(page_list, cur_start, (cur_end - cur_start) / PageSize, Null, false, properties, OperationType_ChangePermissions, true)); } } /* If we're past the end of the region, we're done. */ - if (src_map_last <= info.GetLastAddress()) { + if (src_map_last <= it->GetLastAddress()) { break; } @@ -4468,24 +4438,21 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { - if (info.GetState() != KMemoryState_Free) { + if (last_address <= it->GetLastAddress()) { + if (it->GetState() != KMemoryState_Free) { mapped_size += (last_address + 1 - cur_address); } break; } /* Track the memory if it's mapped. */ - if (info.GetState() != KMemoryState_Free) { - mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; + if (it->GetState() != KMemoryState_Free) { + mapped_size += it->GetEndAddress() - cur_address; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4527,21 +4494,18 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - - const bool is_free = info.GetState() == KMemoryState_Free; + const bool is_free = it->GetState() == KMemoryState_Free; if (is_free) { - if (info.GetAddress() < GetInteger(address)) { + if (it->GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } - if (last_address < info.GetLastAddress()) { + if (last_address < it->GetLastAddress()) { ++num_allocator_blocks; } } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { if (!is_free) { checked_mapped_size += (last_address + 1 - cur_address); } @@ -4550,11 +4514,11 @@ namespace ams::kern { /* Track the memory if it's mapped. */ if (!is_free) { - checked_mapped_size += KProcessAddress(info.GetEndAddress()) - cur_address; + checked_mapped_size += it->GetEndAddress() - cur_address; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4594,26 +4558,23 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* If the memory state is free, we mapped it and need to unmap it. */ - if (info.GetState() == KMemoryState_Free) { + if (it->GetState() == KMemoryState_Free) { /* Determine the range to unmap. */ const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; - const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_unmap_address + 1 - cur_address) / PageSize; + const size_t cur_pages = std::min(it->GetEndAddress() - cur_address, last_unmap_address + 1 - cur_address) / PageSize; /* Unmap. */ MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_pages, Null, false, unmap_properties, OperationType_Unmap, true)); } /* Check if we're done. */ - if (last_unmap_address <= info.GetLastAddress()) { + if (last_unmap_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } } @@ -4632,14 +4593,11 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* If it's unmapped, we need to map it. */ - if (info.GetState() == KMemoryState_Free) { + if (it->GetState() == KMemoryState_Free) { /* Determine the range to map. */ const KPageProperties map_properties = { KMemoryPermission_UserReadWrite, false, false, cur_address == this->GetAliasRegionStart() ? DisableMergeAttribute_DisableHead : DisableMergeAttribute_None }; - size_t map_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; + size_t map_pages = std::min(it->GetEndAddress() - cur_address, last_address + 1 - cur_address) / PageSize; /* While we have pages to map, map them. */ { @@ -4680,12 +4638,12 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4737,26 +4695,23 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* Verify the memory's state. */ - const bool is_normal = info.GetState() == KMemoryState_Normal && info.GetAttribute() == 0; - const bool is_free = info.GetState() == KMemoryState_Free; + const bool is_normal = it->GetState() == KMemoryState_Normal && it->GetAttribute() == 0; + const bool is_free = it->GetState() == KMemoryState_Free; R_UNLESS(is_normal || is_free, svc::ResultInvalidCurrentMemory()); if (is_normal) { - R_UNLESS(info.GetAttribute() == KMemoryAttribute_None, svc::ResultInvalidCurrentMemory()); + R_UNLESS(it->GetAttribute() == KMemoryAttribute_None, svc::ResultInvalidCurrentMemory()); if (map_start_address == Null) { map_start_address = cur_address; } - map_last_address = (last_address >= info.GetLastAddress()) ? info.GetLastAddress() : last_address; + map_last_address = (last_address >= it->GetLastAddress()) ? it->GetLastAddress() : last_address; - if (info.GetAddress() < GetInteger(address)) { + if (it->GetAddress() < GetInteger(address)) { ++num_allocator_blocks; } - if (last_address < info.GetLastAddress()) { + if (last_address < it->GetLastAddress()) { ++num_allocator_blocks; } @@ -4764,12 +4719,12 @@ namespace ams::kern { } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } @@ -4802,26 +4757,23 @@ namespace ams::kern { /* Check that the iterator is valid. */ MESOSPHERE_ASSERT(it != m_memory_block_manager.end()); - /* Get the memory info. */ - const KMemoryInfo info = it->GetMemoryInfo(); - /* If the memory state is normal, we need to unmap it. */ - if (info.GetState() == KMemoryState_Normal) { + if (it->GetState() == KMemoryState_Normal) { /* Determine the range to unmap. */ const KPageProperties unmap_properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; - const size_t cur_pages = std::min(KProcessAddress(info.GetEndAddress()) - cur_address, last_address + 1 - cur_address) / PageSize; + const size_t cur_pages = std::min(it->GetEndAddress() - cur_address, last_address + 1 - cur_address) / PageSize; /* Unmap. */ MESOSPHERE_R_ABORT_UNLESS(this->Operate(updater.GetPageList(), cur_address, cur_pages, Null, false, unmap_properties, OperationType_Unmap, false)); } /* Check if we're done. */ - if (last_address <= info.GetLastAddress()) { + if (last_address <= it->GetLastAddress()) { break; } /* Advance. */ - cur_address = info.GetEndAddress(); + cur_address = it->GetEndAddress(); ++it; } From 126cb8bbdfef05b9e5852bea609062657d3a411b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 12:51:49 -0700 Subject: [PATCH 142/238] kern: fix KMemoryBlock ctor reorder warn --- .../include/mesosphere/kern_k_memory_block.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp index 2847de337..57876fbcb 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block.hpp @@ -380,10 +380,9 @@ namespace ams::kern { explicit KMemoryBlock() { /* ... */ } constexpr KMemoryBlock(util::ConstantInitializeTag, KProcessAddress addr, u32 np, KMemoryState ms, KMemoryPermission p, KMemoryAttribute attr) - : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_device_disable_merge_left_count(), - m_device_disable_merge_right_count(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), - m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p), m_original_permission(KMemoryPermission_None), - m_attribute(attr), m_disable_merge_attribute() + : util::IntrusiveRedBlackTreeBaseNode(util::ConstantInitialize), m_permission(p), m_original_permission(KMemoryPermission_None), + m_attribute(attr), m_disable_merge_attribute(), m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0), + m_ipc_disable_merge_count(), m_device_use_count(0), m_device_disable_merge_left_count(), m_device_disable_merge_right_count() { /* ... */ } From c3fa42d9581371a01581c2cc3ef82fbfa67628a5 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 12:52:07 -0700 Subject: [PATCH 143/238] kern: clear gicd/gicc pointers in KInterruptController::Finalize --- .../source/arch/arm/kern_generic_interrupt_controller.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc index 864da44a5..ef363c0cf 100644 --- a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc +++ b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc @@ -79,6 +79,12 @@ namespace ams::kern::arch::arm { /* Setup all interrupt lines. */ SetupInterruptLines(core_id); + + /* Clear pointers, if needed. */ + if (core_id == 0) { + m_gicd = nullptr; + m_gicc = nullptr; + } } void KInterruptController::SaveCoreLocal(LocalState *state) const { From a72e39d657b65e9ef3a7f0e1dac367603b664cc8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 14:04:15 -0700 Subject: [PATCH 144/238] kern: allocate all TTBR0 pages during init, use procidx as asid --- .../arch/arm64/kern_k_page_table.hpp | 25 ++++- .../arch/arm64/kern_k_process_page_table.hpp | 8 +- .../arm64/kern_k_supervisor_page_table.hpp | 3 +- .../include/mesosphere/kern_k_process.hpp | 2 +- .../source/arch/arm64/kern_k_page_table.cpp | 103 ++---------------- .../nintendo/nx/kern_k_sleep_manager.cpp | 4 +- .../libmesosphere/source/kern_k_process.cpp | 4 +- mesosphere/kernel/kernel.ld | 2 + .../source/arch/arm64/init/kern_init_core.cpp | 31 ++++++ 9 files changed, 72 insertions(+), 110 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 14aba9913..370211b2b 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -93,9 +93,13 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(alignment < L1BlockSize); return KPageTable::GetBlockSize(static_cast(KPageTable::GetBlockType(alignment) + 1)); } + public: + /* TODO: How should this size be determined. Does the KProcess slab count need to go in a header as a define? */ + static constexpr size_t NumTtbr0Entries = 81; + private: + static constinit inline const volatile u64 s_ttbr0_entries[NumTtbr0Entries] = {}; private: KPageTableManager *m_manager; - u64 m_ttbr; u8 m_asid; protected: Result OperateImpl(PageLinkedList *page_list, KProcessAddress virt_addr, size_t num_pages, KPhysicalAddress phys_addr, bool is_pa_valid, const KPageProperties properties, OperationType operation, bool reuse_ll); @@ -168,17 +172,28 @@ namespace ams::kern::arch::arm64 { return entry; } public: - constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_ttbr(), m_asid() { /* ... */ } + constexpr explicit KPageTable(util::ConstantInitializeTag) : KPageTableBase(util::ConstantInitialize), m_manager(), m_asid() { /* ... */ } explicit KPageTable() { /* ... */ } static NOINLINE void Initialize(s32 core_id); - ALWAYS_INLINE void Activate(u32 proc_id) { - cpu::SwitchProcess(m_ttbr, proc_id); + static const volatile u64 &GetTtbr0Entry(size_t index) { return s_ttbr0_entries[index]; } + + static ALWAYS_INLINE u64 GetKernelTtbr0() { + return s_ttbr0_entries[0]; + } + + static ALWAYS_INLINE void ActivateKernel() { + /* Activate, using asid 0 and process id = 0xFFFFFFFF */ + cpu::SwitchProcess(GetKernelTtbr0(), 0xFFFFFFFF); + } + + static ALWAYS_INLINE void ActivateProcess(size_t proc_idx, u32 proc_id) { + cpu::SwitchProcess(s_ttbr0_entries[proc_idx + 1], proc_id); } NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); - NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit); + NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); Result Finalize(); private: Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 640b9e5e5..3ad3c96a1 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -23,13 +23,13 @@ namespace ams::kern::arch::arm64 { private: KPageTable m_page_table; public: - void Activate(u64 id) { + void Activate(size_t process_index, u64 id) { /* Activate the page table with the specified contextidr. */ - m_page_table.Activate(id); + m_page_table.ActivateProcess(process_index, id); } - Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit)); + Result Initialize(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { + R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit, process_index)); } void Finalize() { m_page_table.Finalize(); } diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp index 73d886d84..0c0602289 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_supervisor_page_table.hpp @@ -29,8 +29,7 @@ namespace ams::kern::arch::arm64 { NOINLINE void Initialize(s32 core_id); void Activate() { - /* Activate, using process id = 0xFFFFFFFF */ - m_page_table.Activate(0xFFFFFFFF); + m_page_table.ActivateKernel(); } void ActivateForInit() { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 5a37e3a6b..c4ab7f2a5 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -374,7 +374,7 @@ namespace ams::kern { /* Update the current page table. */ if (next_process) { - next_process->GetPageTable().Activate(next_process->GetProcessId()); + next_process->GetPageTable().Activate(next_process->GetSlabIndex(), next_process->GetProcessId()); } else { Kernel::GetKernelPageTable().Activate(); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 55e4fc52b..c1b0c76b4 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -85,77 +85,6 @@ namespace ams::kern::arch::arm64 { return (static_cast(asid) << 48) | (static_cast(GetInteger(table))); } - class KPageTableAsidManager { - private: - using WordType = u32; - static constexpr u8 ReservedAsids[] = { 0 }; - static constexpr size_t NumReservedAsids = util::size(ReservedAsids); - static constexpr size_t BitsPerWord = BITSIZEOF(WordType); - static constexpr size_t AsidCount = 0x100; - static constexpr size_t NumWords = AsidCount / BitsPerWord; - static constexpr WordType FullWord = ~WordType(0u); - private: - WordType m_state[NumWords]; - KLightLock m_lock; - u8 m_hint; - private: - constexpr bool TestImpl(u8 asid) const { - return m_state[asid / BitsPerWord] & (1u << (asid % BitsPerWord)); - } - constexpr void ReserveImpl(u8 asid) { - MESOSPHERE_ASSERT(!this->TestImpl(asid)); - m_state[asid / BitsPerWord] |= (1u << (asid % BitsPerWord)); - } - - constexpr void ReleaseImpl(u8 asid) { - MESOSPHERE_ASSERT(this->TestImpl(asid)); - m_state[asid / BitsPerWord] &= ~(1u << (asid % BitsPerWord)); - } - - constexpr u8 FindAvailable() const { - for (size_t i = 0; i < util::size(m_state); i++) { - if (m_state[i] == FullWord) { - continue; - } - const WordType clear_bit = (m_state[i] + 1) ^ (m_state[i]); - return BitsPerWord * i + BitsPerWord - 1 - ClearLeadingZero(clear_bit); - } - if (m_state[util::size(m_state)-1] == FullWord) { - MESOSPHERE_PANIC("Unable to reserve ASID"); - } - __builtin_unreachable(); - } - - static constexpr ALWAYS_INLINE WordType ClearLeadingZero(WordType value) { - return __builtin_clzll(value) - (BITSIZEOF(unsigned long long) - BITSIZEOF(WordType)); - } - public: - constexpr KPageTableAsidManager() : m_state(), m_lock(), m_hint() { - for (size_t i = 0; i < NumReservedAsids; i++) { - this->ReserveImpl(ReservedAsids[i]); - } - } - - u8 Reserve() { - KScopedLightLock lk(m_lock); - - if (this->TestImpl(m_hint)) { - m_hint = this->FindAvailable(); - } - - this->ReserveImpl(m_hint); - - return m_hint++; - } - - void Release(u8 asid) { - KScopedLightLock lk(m_lock); - this->ReleaseImpl(asid); - } - }; - - KPageTableAsidManager g_asid_manager; - } ALWAYS_INLINE void KPageTable::NoteUpdated() const { @@ -184,6 +113,7 @@ namespace ams::kern::arch::arm64 { this->OnKernelTableSinglePageUpdated(virt_addr); } + void KPageTable::Initialize(s32 core_id) { /* Nothing actually needed here. */ MESOSPHERE_UNUSED(core_id); @@ -194,38 +124,29 @@ namespace ams::kern::arch::arm64 { m_asid = 0; m_manager = Kernel::GetSystemSystemResource().GetPageTableManagerPointer(); - /* Allocate a page for ttbr. */ - /* NOTE: It is a postcondition of page table manager allocation that the page is all-zero. */ - const u64 asid_tag = (static_cast(m_asid) << 48ul); - const KVirtualAddress page = m_manager->Allocate(); - MESOSPHERE_ASSERT(page != Null); - m_ttbr = GetInteger(KPageTableBase::GetLinearMappedPhysicalAddress(page)) | asid_tag; - /* Initialize the base page table. */ MESOSPHERE_R_ABORT_UNLESS(KPageTableBase::InitializeForKernel(true, table, start, end)); R_SUCCEED(); } - Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit) { - /* Get an ASID */ - m_asid = g_asid_manager.Reserve(); - ON_RESULT_FAILURE { g_asid_manager.Release(m_asid); }; + Result KPageTable::InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index) { + /* Determine our ASID */ + m_asid = process_index + 1; + MESOSPHERE_ABORT_UNLESS(0 < m_asid && m_asid < util::size(s_ttbr0_entries)); /* Set our manager. */ m_manager = system_resource->GetPageTableManagerPointer(); - /* Allocate a new table, and set our ttbr value. */ - const KVirtualAddress new_table = m_manager->Allocate(); - R_UNLESS(new_table != Null, svc::ResultOutOfResource()); - m_ttbr = EncodeTtbr(GetPageTablePhysicalAddress(new_table), m_asid); - ON_RESULT_FAILURE_2 { m_manager->Free(new_table); }; + /* Get the virtual address of our L1 table. */ + const KPhysicalAddress ttbr0_phys = KPhysicalAddress(s_ttbr0_entries[m_asid] & UINT64_C(0xFFFFFFFFFFFE)); + const KVirtualAddress ttbr0_virt = KMemoryLayout::GetLinearVirtualAddress(ttbr0_phys); /* Initialize our base table. */ const size_t as_width = GetAddressSpaceWidth(flags); const KProcessAddress as_start = 0; const KProcessAddress as_end = (1ul << as_width); - R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(new_table), as_start, as_end, code_address, code_size, system_resource, resource_limit)); + R_TRY(KPageTableBase::InitializeForProcess(flags, from_back, pool, GetVoidPointer(ttbr0_virt), as_start, as_end, code_address, code_size, system_resource, resource_limit)); /* Note that we've updated the table (since we created it). */ this->NoteUpdated(); @@ -329,20 +250,16 @@ namespace ams::kern::arch::arm64 { } } - /* Free the L1 table. */ + /* Clear the L1 table. */ { const KVirtualAddress l1_table = reinterpret_cast(impl.Finalize()); ClearPageTable(l1_table); - this->GetPageTableManager().Free(l1_table); } /* Perform inherited finalization. */ KPageTableBase::Finalize(); } - /* Release our asid. */ - g_asid_manager.Release(m_asid); - R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp index bb782d390..5e5983c86 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp @@ -31,7 +31,6 @@ namespace ams::kern::board::nintendo::nx { /* Struct representing registers saved on wake/sleep. */ class SavedSystemRegisters { private: - u64 ttbr0_el1; u64 elr_el1; u64 sp_el0; u64 spsr_el1; @@ -90,7 +89,6 @@ namespace ams::kern::board::nintendo::nx { void SavedSystemRegisters::Save() { /* Save system registers. */ - this->ttbr0_el1 = cpu::GetTtbr0El1(); this->tpidr_el0 = cpu::GetTpidrEl0(); this->elr_el1 = cpu::GetElrEl1(); this->sp_el0 = cpu::GetSpEl0(); @@ -405,7 +403,7 @@ namespace ams::kern::board::nintendo::nx { cpu::EnsureInstructionConsistency(); /* Restore system registers. */ - cpu::SetTtbr0El1 (this->ttbr0_el1); + cpu::SetTtbr0El1 (KPageTable::GetKernelTtbr0()); cpu::SetTpidrEl0 (this->tpidr_el0); cpu::SetElrEl1 (this->elr_el1); cpu::SetSpEl0 (this->sp_el0); diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 789bdbc09..96d82f975 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -299,7 +299,7 @@ namespace ams::kern { /* Setup page table. */ { const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; - R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit)); + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, params.code_num_pages * PageSize, m_system_resource, res_limit, this->GetSlabIndex())); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; @@ -378,7 +378,7 @@ namespace ams::kern { /* Setup page table. */ { const bool from_back = (params.flags & ams::svc::CreateProcessFlag_EnableAslr) == 0; - R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit)); + R_TRY(m_page_table.Initialize(static_cast(params.flags), from_back, pool, params.code_address, code_size, m_system_resource, res_limit, this->GetSlabIndex())); } ON_RESULT_FAILURE_2 { m_page_table.Finalize(); }; diff --git a/mesosphere/kernel/kernel.ld b/mesosphere/kernel/kernel.ld index 779488a35..bcd658572 100644 --- a/mesosphere/kernel/kernel.ld +++ b/mesosphere/kernel/kernel.ld @@ -125,6 +125,8 @@ SECTIONS .gnu.version_r : { *(.gnu.version_r) } :rodata .note.gnu.build-id : { *(.note.gnu.build-id) } :rodata + __rodata_end = .; + /* =========== DATA section =========== */ . = ALIGN(0x1000); __data_start = . ; diff --git a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp index faf34576d..10a000c6d 100644 --- a/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp +++ b/mesosphere/kernel/source/arch/arm64/init/kern_init_core.cpp @@ -15,6 +15,9 @@ */ #include +extern "C" void __rodata_start(); +extern "C" void __rodata_end(); + extern "C" void __bin_start__(); extern "C" void __bin_end__(); @@ -220,6 +223,31 @@ namespace ams::kern::init { }; static_assert(kern::arch::arm64::init::IsInitialPageAllocator); + void SetupAllTtbr0Entries(KInitialPageTable &init_pt, KInitialPageAllocator &allocator) { + /* Validate that the ttbr0 array is in rodata. */ + const uintptr_t rodata_start = reinterpret_cast(__rodata_start); + const uintptr_t rodata_end = reinterpret_cast(__rodata_end); + MESOSPHERE_INIT_ABORT_UNLESS(rodata_start < rodata_end); + MESOSPHERE_INIT_ABORT_UNLESS(rodata_start <= reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(0)))); + MESOSPHERE_INIT_ABORT_UNLESS(reinterpret_cast(std::addressof(KPageTable::GetTtbr0Entry(KPageTable::NumTtbr0Entries))) < rodata_end); + + /* Allocate pages for all ttbr0 entries. */ + for (size_t i = 0; i < KPageTable::NumTtbr0Entries; ++i) { + /* Allocate a page. */ + KPhysicalAddress page = allocator.Allocate(PageSize); + MESOSPHERE_INIT_ABORT_UNLESS(page != Null); + + /* Check that the page is allowed to be a ttbr0 entry. */ + MESOSPHERE_INIT_ABORT_UNLESS((GetInteger(page) & UINT64_C(0xFFFF000000000001)) == 0); + + /* Get the physical address of the ttbr0 entry. */ + const auto ttbr0_phys_ptr = init_pt.GetPhysicalAddress(KVirtualAddress(std::addressof(KPageTable::GetTtbr0Entry(i)))); + + /* Set the entry to the newly allocated page. */ + *reinterpret_cast(GetInteger(ttbr0_phys_ptr)) = (static_cast(i) << 48) | GetInteger(page); + } + } + void FinalizeIdentityMapping(KInitialPageTable &init_pt, KInitialPageAllocator &allocator, u64 phys_to_virt_offset) { /* Create an allocator for identity mapping finalization. */ KInitialPageAllocatorForFinalizeIdentityMapping finalize_allocator(allocator, phys_to_virt_offset); @@ -591,6 +619,9 @@ namespace ams::kern::init { /* Create page table object for use during remaining initialization. */ KInitialPageTable init_pt; + /* Setup all ttbr0 pages. */ + SetupAllTtbr0Entries(init_pt, g_initial_page_allocator); + /* Unmap the identity mapping. */ FinalizeIdentityMapping(init_pt, g_initial_page_allocator, g_phase2_linear_region_phys_to_virt_diff); From 3394a88a1a088d145d462789b9fd2c640c69282e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 15:12:25 -0700 Subject: [PATCH 145/238] kern: fix debug build --- .../source/arch/arm64/kern_k_debug.cpp | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp index 89587597b..87d7bf307 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_debug.cpp @@ -15,6 +15,28 @@ */ #include +/* */ +namespace ams::rocrt { + + constexpr inline const u32 ModuleHeaderVersion = util::FourCC<'M','O','D','0'>::Code; + + struct ModuleHeader { + u32 signature; + u32 dynamic_offset; + u32 bss_start_offset; + u32 bss_end_offset; + u32 exception_info_start_offset; + u32 exception_info_end_offset; + u32 module_offset; + }; + + struct ModuleHeaderLocation { + u32 pad; + u32 header_offset; + }; + +} + namespace ams::kern::arch::arm64 { namespace { @@ -657,7 +679,7 @@ namespace ams::kern::arch::arm64 { return PrintAddressWithModuleName(address, has_module_name, module_name, base_address); } - dyn_address = module.start_address + mod_offset + temp_32; + dyn_address = base_address + mod_offset + temp_32; } /* Locate tables inside .dyn. */ From 743634c3fda97f3114a0ea8da03957a61ba8f0a8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 15:12:46 -0700 Subject: [PATCH 146/238] kern: move KTargetSystem into .rodata, split init/verify --- .../nintendo/nx/kern_k_system_control.hpp | 1 + .../mesosphere/kern_k_system_control_base.hpp | 1 + .../mesosphere/kern_k_target_system.hpp | 49 +++++++++-------- .../nintendo/nx/kern_k_system_control.cpp | 53 +++++++++++++++---- .../source/kern_k_system_control_base.cpp | 29 +++------- .../source/kern_kernel_instantiations.cpp | 4 ++ 6 files changed, 83 insertions(+), 54 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp index a0cfce5a1..8e1829849 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_system_control.hpp @@ -45,6 +45,7 @@ namespace ams::kern::board::nintendo::nx { }; public: /* Initialization. */ + static NOINLINE void ConfigureKTargetSystem(); static NOINLINE void InitializePhase1(); static NOINLINE void InitializePhase2(); static NOINLINE u32 GetCreateProcessMemoryPool(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp index bb1c1ff0f..ab3a18c5b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp @@ -69,6 +69,7 @@ namespace ams::kern { static NOINLINE void InitializePhase1Base(u64 seed); public: /* Initialization. */ + static NOINLINE void ConfigureKTargetSystem(); static NOINLINE void InitializePhase1(); static NOINLINE void InitializePhase2(); static NOINLINE u32 GetCreateProcessMemoryPool(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp index 87b72c0fa..24220bed0 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp @@ -24,29 +24,36 @@ namespace ams::kern { friend class KSystemControlBase; friend class KSystemControl; private: - static inline constinit bool s_is_debug_mode; - static inline constinit bool s_enable_debug_logging; - static inline constinit bool s_enable_user_exception_handlers; - static inline constinit bool s_enable_debug_memory_fill; - static inline constinit bool s_enable_user_pmu_access; - static inline constinit bool s_enable_kernel_debugging; - static inline constinit bool s_enable_dynamic_resource_limits; + struct KTargetSystemData { + bool is_debug_mode; + bool enable_debug_logging; + bool enable_user_exception_handlers; + bool enable_debug_memory_fill; + bool enable_user_pmu_access; + bool enable_kernel_debugging; + bool enable_dynamic_resource_limits; + }; private: - static ALWAYS_INLINE void SetIsDebugMode(bool en) { s_is_debug_mode = en; } - static ALWAYS_INLINE void EnableDebugLogging(bool en) { s_enable_debug_logging = en; } - static ALWAYS_INLINE void EnableUserExceptionHandlers(bool en) { s_enable_user_exception_handlers = en; } - static ALWAYS_INLINE void EnableDebugMemoryFill(bool en) { s_enable_debug_memory_fill = en; } - static ALWAYS_INLINE void EnableUserPmuAccess(bool en) { s_enable_user_pmu_access = en; } - static ALWAYS_INLINE void EnableKernelDebugging(bool en) { s_enable_kernel_debugging = en; } - static ALWAYS_INLINE void EnableDynamicResourceLimits(bool en) { s_enable_dynamic_resource_limits = en; } + static inline constinit bool s_is_initialized = false; + static inline constinit const volatile KTargetSystemData s_data = { + .is_debug_mode = true, + .enable_debug_logging = true, + .enable_user_exception_handlers = true, + .enable_debug_memory_fill = true, + .enable_user_pmu_access = true, + .enable_kernel_debugging = true, + .enable_dynamic_resource_limits = false, + }; + private: + static ALWAYS_INLINE void SetInitialized() { s_is_initialized = true; } public: - static ALWAYS_INLINE bool IsDebugMode() { return s_is_debug_mode; } - static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_enable_debug_logging; } - static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_enable_user_exception_handlers; } - static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_enable_debug_memory_fill; } - static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_enable_user_pmu_access; } - static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_enable_kernel_debugging; } - static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_enable_dynamic_resource_limits; } + static ALWAYS_INLINE bool IsDebugMode() { return s_is_initialized && s_data.is_debug_mode; } + static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_is_initialized && s_data.enable_debug_logging; } + static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_is_initialized && s_data.enable_user_exception_handlers; } + static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_is_initialized && s_data.enable_debug_memory_fill; } + static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_is_initialized && s_data.enable_user_pmu_access; } + static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_is_initialized && s_data.enable_kernel_debugging; } + static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_is_initialized && s_data.enable_dynamic_resource_limits; } }; } \ No newline at end of file diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index 52a894d1c..8050f78e0 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -26,7 +26,7 @@ namespace ams::kern::board::nintendo::nx { constexpr size_t SecureSizeMax = util::AlignDown(512_MB - 1, SecureAlignment); /* Global variables for panic. */ - constinit bool g_call_smc_on_panic; + constinit const volatile bool g_call_smc_on_panic = false; /* Global variables for secure memory. */ constinit KSpinLock g_secure_applet_lock; @@ -401,34 +401,67 @@ namespace ams::kern::board::nintendo::nx { } /* System Initialization. */ - void KSystemControl::InitializePhase1() { + void KSystemControl::ConfigureKTargetSystem() { /* Configure KTargetSystem. */ + volatile auto *ts = const_cast(std::addressof(KTargetSystem::s_data)); { /* Set IsDebugMode. */ { - KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode)); + ts->is_debug_mode = GetConfigBool(smc::ConfigItem::IsDebugMode); /* If debug mode, we want to initialize uart logging. */ - KTargetSystem::EnableDebugLogging(KTargetSystem::IsDebugMode()); + ts->enable_debug_logging = ts->is_debug_mode; } /* Set Kernel Configuration. */ { const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; - KTargetSystem::EnableDebugMemoryFill(kernel_config.Get()); - KTargetSystem::EnableUserExceptionHandlers(kernel_config.Get()); - KTargetSystem::EnableDynamicResourceLimits(!kernel_config.Get()); - KTargetSystem::EnableUserPmuAccess(kernel_config.Get()); + ts->enable_debug_memory_fill = kernel_config.Get(); + ts->enable_user_exception_handlers = kernel_config.Get(); + ts->enable_dynamic_resource_limits = !kernel_config.Get(); + ts->enable_user_pmu_access = kernel_config.Get(); - g_call_smc_on_panic = kernel_config.Get(); + /* Configure call smc on panic. */ + *const_cast(std::addressof(g_call_smc_on_panic)) = kernel_config.Get(); } /* Set Kernel Debugging. */ { /* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */ /* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */ - KTargetSystem::EnableKernelDebugging(GetConfigBool(smc::ConfigItem::DisableProgramVerification)); + ts->enable_kernel_debugging = GetConfigBool(smc::ConfigItem::DisableProgramVerification); + } + } + } + + void KSystemControl::InitializePhase1() { + /* Enable KTargetSystem. */ + KTargetSystem::SetInitialized(); + + /* Check KTargetSystem was configured correctly. */ + { + /* Check IsDebugMode. */ + { + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDebugMode() == GetConfigBool(smc::ConfigItem::IsDebugMode)); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDebugLoggingEnabled() == GetConfigBool(smc::ConfigItem::IsDebugMode)); + } + + /* Check Kernel Configuration. */ + { + const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; + + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDebugMemoryFillEnabled() == kernel_config.Get()); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsUserExceptionHandlersEnabled() == kernel_config.Get()); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled() == !kernel_config.Get()); + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsUserPmuAccessEnabled() == kernel_config.Get()); + + MESOSPHERE_ABORT_UNLESS(g_call_smc_on_panic == kernel_config.Get()); + } + + /* Check Kernel Debugging. */ + { + MESOSPHERE_ABORT_UNLESS(KTargetSystem::IsKernelDebuggingEnabled() == GetConfigBool(smc::ConfigItem::DisableProgramVerification)); } } diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index fe0b56996..025ec4f9c 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -124,31 +124,14 @@ namespace ams::kern { } /* System Initialization. */ + void KSystemControlBase::ConfigureKTargetSystem() { + /* By default, use the default config set in the KTargetSystem header. */ + } + void KSystemControlBase::InitializePhase1() { - /* Configure KTargetSystem. */ + /* Enable KTargetSystem. */ { - /* Set IsDebugMode. */ - { - KTargetSystem::SetIsDebugMode(true); - - /* If debug mode, we want to initialize uart logging. */ - KTargetSystem::EnableDebugLogging(true); - } - - /* Set Kernel Configuration. */ - { - KTargetSystem::EnableDebugMemoryFill(false); - KTargetSystem::EnableUserExceptionHandlers(true); - KTargetSystem::EnableDynamicResourceLimits(true); - KTargetSystem::EnableUserPmuAccess(false); - } - - /* Set Kernel Debugging. */ - { - /* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */ - /* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */ - KTargetSystem::EnableKernelDebugging(true); - } + KTargetSystem::SetInitialized(); } /* Initialize random and resource limit. */ diff --git a/mesosphere/kernel/source/kern_kernel_instantiations.cpp b/mesosphere/kernel/source/kern_kernel_instantiations.cpp index 6adff0754..d01ddd151 100644 --- a/mesosphere/kernel/source/kern_kernel_instantiations.cpp +++ b/mesosphere/kernel/source/kern_kernel_instantiations.cpp @@ -111,4 +111,8 @@ namespace ams::kern { KThread &Kernel::GetMainThread(s32 core_id) { return g_main_threads.m_arr[core_id]; } KThread &Kernel::GetIdleThread(s32 core_id) { return g_idle_threads.m_arr[core_id]; } + __attribute__((constructor)) void ConfigureKTargetSystem() { + KSystemControl::ConfigureKTargetSystem(); + } + } From 00716576cd5cd575841c18d39c223a7049cc8f74 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 15:20:32 -0700 Subject: [PATCH 147/238] kern: simplify KProcess max memory calculation --- libraries/libmesosphere/source/kern_k_process.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 96d82f975..24c6baef5 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -220,18 +220,8 @@ namespace ams::kern { m_running_thread_switch_counts[i] = 0; } - /* Set max memory based on address space type. */ - switch ((params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask)) { - case ams::svc::CreateProcessFlag_AddressSpace32Bit: - case ams::svc::CreateProcessFlag_AddressSpace64BitDeprecated: - case ams::svc::CreateProcessFlag_AddressSpace64Bit: - m_max_process_memory = m_page_table.GetHeapRegionSize(); - break; - case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: - m_max_process_memory = m_page_table.GetHeapRegionSize() + m_page_table.GetAliasRegionSize(); - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } + /* Set max memory. */ + m_max_process_memory = m_page_table.GetHeapRegionSize(); /* Generate random entropy. */ KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy)); From 2855b8ee355057a2fd42ff3e64c4ea79abf4bdc3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 16:50:20 -0700 Subject: [PATCH 148/238] kern/strat: update for new DebugFlags capability semantics --- config_templates/exosphere.ini | 2 +- .../arch/arm64/kern_k_process_page_table.hpp | 4 +- .../mesosphere/kern_k_capabilities.hpp | 11 ++- .../include/mesosphere/kern_k_debug_base.hpp | 5 ++ .../mesosphere/kern_k_page_table_base.hpp | 4 +- .../include/mesosphere/kern_k_process.hpp | 4 + .../source/kern_k_capabilities.cpp | 7 ++ .../source/kern_k_debug_base.cpp | 81 ++++--------------- .../source/kern_k_page_table_base.cpp | 38 ++++++--- .../source/svc/kern_svc_debug.cpp | 23 +++++- .../source/svc/kern_svc_process.cpp | 3 + .../source/svc/kern_svc_thread.cpp | 47 ++++++----- stratosphere/creport/creport.json | 1 + stratosphere/dmnt.gen2/dmnt.gen2.json | 1 + stratosphere/fatal/fatal.json | 1 + .../loader/source/ldr_capabilities.cpp | 19 ++++- stratosphere/pm/pm.json | 1 + 17 files changed, 142 insertions(+), 110 deletions(-) diff --git a/config_templates/exosphere.ini b/config_templates/exosphere.ini index e8dc82377..8df772ccf 100644 --- a/config_templates/exosphere.ini +++ b/config_templates/exosphere.ini @@ -1,6 +1,6 @@ # Key: debugmode, default: 1. # Desc: Controls whether kernel is debug mode. -# Disabling this may break Atmosphere's debugger in a future release. +# Disabling this will break Atmosphere. # Key: debugmode_user, default: 0. # Desc: Controls whether userland is debug mode. diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp index 3ad3c96a1..e18a6fbc8 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_process_page_table.hpp @@ -154,8 +154,8 @@ namespace ams::kern::arch::arm64 { R_RETURN(m_page_table.InvalidateCurrentProcessDataCache(address, size)); } - Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { - R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size)); + Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod) { + R_RETURN(m_page_table.ReadDebugMemory(buffer, address, size, force_debug_prod)); } Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp index 7c2f5dbcd..2c74b835c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_capabilities.hpp @@ -168,9 +168,10 @@ namespace ams::kern { struct DebugFlags { using IdBits = Field<0, CapabilityId + 1>; - DEFINE_FIELD(AllowDebug, IdBits, 1, bool); - DEFINE_FIELD(ForceDebug, AllowDebug, 1, bool); - DEFINE_FIELD(Reserved, ForceDebug, 13); + DEFINE_FIELD(AllowDebug, IdBits, 1, bool); + DEFINE_FIELD(ForceDebugProd, AllowDebug, 1, bool); + DEFINE_FIELD(ForceDebug, ForceDebugProd, 1, bool); + DEFINE_FIELD(Reserved, ForceDebug, 12); }; #undef DEFINE_FIELD @@ -255,6 +256,10 @@ namespace ams::kern { return m_debug_capabilities.Get(); } + constexpr bool CanForceDebugProd() const { + return m_debug_capabilities.Get(); + } + constexpr bool CanForceDebug() const { return m_debug_capabilities.Get(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp index 6c8fe54f7..6978b9152 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_debug_base.hpp @@ -32,6 +32,7 @@ namespace ams::kern { KLightLock m_lock; KProcess::State m_old_process_state; bool m_is_attached; + bool m_is_force_debug_prod; public: explicit KDebugBase() { /* ... */ } protected: @@ -62,6 +63,10 @@ namespace ams::kern { return m_is_attached; } + ALWAYS_INLINE bool IsForceDebugProd() const { + return m_is_force_debug_prod; + } + ALWAYS_INLINE bool OpenProcess() { return m_process_holder.Open(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp index 8da4311df..7b2c722e1 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_page_table_base.hpp @@ -328,6 +328,8 @@ namespace ams::kern { R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr)); } + bool CanReadWriteDebugMemory(KProcessAddress addr, size_t size, bool force_debug_prod); + Result LockMemoryAndOpen(KPageGroup *out_pg, KPhysicalAddress *out_paddr, KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, KMemoryPermission new_perm, u32 lock_attr); Result UnlockMemory(KProcessAddress addr, size_t size, u32 state_mask, u32 state, u32 perm_mask, u32 perm, u32 attr_mask, u32 attr, KMemoryPermission new_perm, u32 lock_attr, const KPageGroup *pg); @@ -421,7 +423,7 @@ namespace ams::kern { Result InvalidateProcessDataCache(KProcessAddress address, size_t size); Result InvalidateCurrentProcessDataCache(KProcessAddress address, size_t size); - Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size); + Result ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod); Result ReadDebugIoMemory(void *buffer, KProcessAddress address, size_t size, KMemoryState state); Result WriteDebugMemory(KProcessAddress address, const void *buffer, size_t size); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index c4ab7f2a5..849f73dab 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -206,6 +206,10 @@ namespace ams::kern { return m_capabilities.IsPermittedDebug(); } + constexpr bool CanForceDebugProd() const { + return m_capabilities.CanForceDebugProd(); + } + constexpr bool CanForceDebug() const { return m_capabilities.CanForceDebug(); } diff --git a/libraries/libmesosphere/source/kern_k_capabilities.cpp b/libraries/libmesosphere/source/kern_k_capabilities.cpp index feb245eda..ba0359262 100644 --- a/libraries/libmesosphere/source/kern_k_capabilities.cpp +++ b/libraries/libmesosphere/source/kern_k_capabilities.cpp @@ -262,7 +262,14 @@ namespace ams::kern { /* Validate. */ R_UNLESS(cap.Get() == 0, svc::ResultReservedUsed()); + u32 total = 0; + if (cap.Get()) { ++total; } + if (cap.Get()) { ++total; } + if (cap.Get()) { ++total; } + R_UNLESS(total <= 1, svc::ResultInvalidCombination()); + m_debug_capabilities.Set(cap.Get()); + m_debug_capabilities.Set(cap.Get()); m_debug_capabilities.Set(cap.Get()); R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/kern_k_debug_base.cpp b/libraries/libmesosphere/source/kern_k_debug_base.cpp index 418d804f3..635673cd2 100644 --- a/libraries/libmesosphere/source/kern_k_debug_base.cpp +++ b/libraries/libmesosphere/source/kern_k_debug_base.cpp @@ -27,7 +27,8 @@ namespace ams::kern { void KDebugBase::Initialize() { /* Clear the continue flags. */ - m_continue_flags = 0; + m_continue_flags = 0; + m_is_force_debug_prod = GetCurrentProcess().CanForceDebugProd(); } bool KDebugBase::Is64Bit() const { @@ -120,8 +121,11 @@ namespace ams::kern { /* Read the memory. */ if (info.GetSvcState() != ams::svc::MemoryState_Io) { /* The memory is normal memory. */ - R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size)); + R_TRY(target_pt.ReadDebugMemory(GetVoidPointer(buffer), cur_address, cur_size, this->IsForceDebugProd())); } else { + /* Only allow IO memory to be read if not force debug prod. */ + R_UNLESS(!this->IsForceDebugProd(), svc::ResultInvalidCurrentMemory()); + /* The memory is IO memory. */ R_TRY(target_pt.ReadDebugIoMemory(GetVoidPointer(buffer), cur_address, cur_size, info.GetState())); } @@ -269,6 +273,9 @@ namespace ams::kern { switch (state) { case KProcess::State_Created: case KProcess::State_Running: + /* Created and running processes can only be debugged if the debugger is not ForceDebugProd. */ + R_UNLESS(!this->IsForceDebugProd(), svc::ResultInvalidState()); + break; case KProcess::State_Crashed: break; case KProcess::State_CreatedAttached: @@ -408,69 +415,6 @@ namespace ams::kern { /* Get the process pointer. */ KProcess * const target = this->GetProcessUnsafe(); - /* Detach from the process. */ - { - /* Lock both ourselves and the target process. */ - KScopedLightLock state_lk(target->GetStateLock()); - KScopedLightLock list_lk(target->GetListLock()); - KScopedLightLock this_lk(m_lock); - - /* Check that we're still attached. */ - if (this->IsAttached()) { - /* Lock the scheduler. */ - KScopedSchedulerLock sl; - - /* Get the process's state. */ - const KProcess::State state = target->GetState(); - - /* Check that the process is in a state where we can terminate it. */ - R_UNLESS(state != KProcess::State_Created, svc::ResultInvalidState()); - R_UNLESS(state != KProcess::State_CreatedAttached, svc::ResultInvalidState()); - - /* Decide on a new state for the process. */ - KProcess::State new_state; - if (state == KProcess::State_RunningAttached) { - /* If the process is running, transition it accordingly. */ - new_state = KProcess::State_Running; - } else if (state == KProcess::State_DebugBreak) { - /* If the process is debug breaked, transition it accordingly. */ - new_state = KProcess::State_Crashed; - - /* Suspend all the threads in the process. */ - { - auto end = target->GetThreadList().end(); - for (auto it = target->GetThreadList().begin(); it != end; ++it) { - /* Request that we suspend the thread. */ - it->RequestSuspend(KThread::SuspendType_Debug); - } - } - } else { - /* Otherwise, don't transition. */ - new_state = state; - } - - #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP) - /* Clear single step on all threads. */ - { - auto end = target->GetThreadList().end(); - for (auto it = target->GetThreadList().begin(); it != end; ++it) { - it->ClearHardwareSingleStep(); - } - } - #endif - - /* Detach from the process. */ - target->ClearDebugObject(new_state); - m_is_attached = false; - - /* Close the initial reference opened to our process. */ - this->CloseProcess(); - - /* Clear our continue flags. */ - m_continue_flags = 0; - } - } - /* Terminate the process. */ target->Terminate(); @@ -962,7 +906,12 @@ namespace ams::kern { case ams::svc::DebugException_UndefinedInstruction: { MESOSPHERE_ASSERT(info->info.exception.exception_data_count == 1); - out->info.exception.specific.undefined_instruction.insn = info->info.exception.exception_data[0]; + /* Only save the instruction if the caller is not force debug prod. */ + if (this->IsForceDebugProd()) { + out->info.exception.specific.undefined_instruction.insn = 0; + } else { + out->info.exception.specific.undefined_instruction.insn = info->info.exception.exception_data[0]; + } } break; case ams::svc::DebugException_BreakPoint: diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 95bc983ca..2a9402ecc 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -2695,18 +2695,37 @@ namespace ams::kern { R_RETURN(cpu::InvalidateDataCache(GetVoidPointer(address), size)); } - Result KPageTableBase::ReadDebugMemory(void *buffer, KProcessAddress address, size_t size) { + bool KPageTableBase::CanReadWriteDebugMemory(KProcessAddress address, size_t size, bool force_debug_prod) { + /* Check pre-conditions. */ + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + + /* If the memory is debuggable and user-readable, we can perform the access. */ + if (R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_NotMapped | KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None))) { + return true; + } + + /* If we're in debug mode, and the process isn't force debug prod, check if the memory is debuggable and kernel-readable and user-executable. */ + if (KTargetSystem::IsDebugMode() && !force_debug_prod) { + if (R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_KernelRead | KMemoryPermission_UserExecute, KMemoryPermission_KernelRead | KMemoryPermission_UserExecute, KMemoryAttribute_None, KMemoryAttribute_None))) { + return true; + } + } + + /* If neither of the above checks passed, we can't access the memory. */ + return false; + } + + Result KPageTableBase::ReadDebugMemory(void *buffer, KProcessAddress address, size_t size, bool force_debug_prod) { /* Lightly validate the region is in range. */ R_UNLESS(this->Contains(address, size), svc::ResultInvalidCurrentMemory()); /* Lock the table. */ KScopedLightLock lk(m_general_lock); - /* Require that the memory either be user readable or debuggable. */ - const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); + /* Require that the memory either be user-readable-and-mapped or debug-accessible. */ + const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_NotMapped | KMemoryPermission_UserRead, KMemoryPermission_UserRead, KMemoryAttribute_None, KMemoryAttribute_None)); if (!can_read) { - const bool can_debug = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_None, KMemoryAttribute_None)); - R_UNLESS(can_debug, svc::ResultInvalidCurrentMemory()); + R_UNLESS(this->CanReadWriteDebugMemory(address, size, force_debug_prod), svc::ResultInvalidCurrentMemory()); } /* Get the impl. */ @@ -2788,11 +2807,10 @@ namespace ams::kern { /* Lock the table. */ KScopedLightLock lk(m_general_lock); - /* Require that the memory either be user writable or debuggable. */ - const bool can_read = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); - if (!can_read) { - const bool can_debug = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_FlagCanDebug, KMemoryState_FlagCanDebug, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_None, KMemoryAttribute_None)); - R_UNLESS(can_debug, svc::ResultInvalidCurrentMemory()); + /* Require that the memory either be user-writable-and-mapped or debug-accessible. */ + const bool can_write = R_SUCCEEDED(this->CheckMemoryStateContiguous(address, size, KMemoryState_None, KMemoryState_None, KMemoryPermission_NotMapped | KMemoryPermission_UserReadWrite, KMemoryPermission_UserReadWrite, KMemoryAttribute_None, KMemoryAttribute_None)); + if (!can_write) { + R_UNLESS(this->CanReadWriteDebugMemory(address, size, false), svc::ResultInvalidCurrentMemory()); } /* Get the impl. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp index 369885355..986654ce4 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_debug.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_debug.cpp @@ -24,6 +24,9 @@ namespace ams::kern::svc { constexpr inline int32_t MaximumDebuggableThreadCount = 0x60; Result DebugActiveProcess(ams::svc::Handle *out_handle, uint64_t process_id) { + /* Check that the SVC can be used. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the process from its id. */ KProcess *process = KProcess::GetProcessFromId(process_id); R_UNLESS(process != nullptr, svc::ResultInvalidProcessId()); @@ -32,9 +35,8 @@ namespace ams::kern::svc { ON_SCOPE_EXIT { process->Close(); }; /* Check that the debugging is allowed. */ - if (!process->IsPermittedDebug()) { - R_UNLESS(GetCurrentProcess().CanForceDebug(), svc::ResultInvalidState()); - } + const bool allowable = process->IsPermittedDebug() || GetCurrentProcess().CanForceDebug() || GetCurrentProcess().CanForceDebugProd(); + R_UNLESS(allowable, svc::ResultInvalidState()); /* Disallow debugging one's own processs, to prevent softlocks. */ R_UNLESS(process != GetCurrentProcessPointer(), svc::ResultInvalidState()); @@ -92,6 +94,9 @@ namespace ams::kern::svc { template Result GetDebugEvent(KUserPointer out_info, ams::svc::Handle debug_handle) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); @@ -164,6 +169,9 @@ namespace ams::kern::svc { } Result GetDebugThreadContext(KUserPointer out_context, ams::svc::Handle debug_handle, uint64_t thread_id, uint32_t context_flags) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Validate the context flags. */ R_UNLESS((context_flags | ams::svc::ThreadContextFlag_All) == ams::svc::ThreadContextFlag_All, svc::ResultInvalidEnumValue()); @@ -220,6 +228,9 @@ namespace ams::kern::svc { } Result QueryDebugProcessMemory(ams::svc::MemoryInfo *out_memory_info, ams::svc::PageInfo *out_page_info, ams::svc::Handle debug_handle, uintptr_t address) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); @@ -261,6 +272,9 @@ namespace ams::kern::svc { } Result ReadDebugProcessMemory(uintptr_t buffer, ams::svc::Handle debug_handle, uintptr_t address, size_t size) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Validate address / size. */ R_UNLESS(size > 0, svc::ResultInvalidSize()); R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory()); @@ -306,6 +320,9 @@ namespace ams::kern::svc { } Result GetDebugThreadParam(uint64_t *out_64, uint32_t *out_32, ams::svc::Handle debug_handle, uint64_t thread_id, ams::svc::DebugThreadParam param) { + /* Only allow invoking the svc on development hardware or if force debug prod. */ + R_UNLESS(KTargetSystem::IsDebugMode() || GetCurrentProcess().CanForceDebugProd(), svc::ResultNotImplemented()); + /* Get the debug object. */ KScopedAutoObject debug = GetCurrentProcess().GetHandleTable().GetObject(debug_handle); R_UNLESS(debug.IsNotNull(), svc::ResultInvalidHandle()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 5141a2c31..98c8740f2 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -71,6 +71,9 @@ namespace ams::kern::svc { } Result GetProcessList(int32_t *out_num_processes, KUserPointer out_process_ids, int32_t max_out_count) { + /* Only allow invoking the svc on development hardware. */ + R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultNotImplemented()); + /* Validate that the out count is valid. */ R_UNLESS((0 <= max_out_count && max_out_count <= static_cast(std::numeric_limits::max() / sizeof(u64))), svc::ResultOutOfRange()); diff --git a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp index 99c8c37a8..6f74dd145 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_thread.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_thread.cpp @@ -217,6 +217,9 @@ namespace ams::kern::svc { } Result GetThreadList(int32_t *out_num_threads, KUserPointer out_thread_ids, int32_t max_out_count, ams::svc::Handle debug_handle) { + /* Only allow invoking the svc on development hardware. */ + R_UNLESS(KTargetSystem::IsDebugMode(), svc::ResultNotImplemented()); + /* Validate that the out count is valid. */ R_UNLESS((0 <= max_out_count && max_out_count <= static_cast(std::numeric_limits::max() / sizeof(u64))), svc::ResultOutOfRange()); @@ -225,30 +228,34 @@ namespace ams::kern::svc { R_UNLESS(GetCurrentProcess().GetPageTable().Contains(KProcessAddress(out_thread_ids.GetUnsafePointer()), max_out_count * sizeof(u64)), svc::ResultInvalidCurrentMemory()); } - if (debug_handle == ams::svc::InvalidHandle) { - /* If passed invalid handle, we should return the global thread list. */ - R_TRY(KThread::GetThreadList(out_num_threads, out_thread_ids, max_out_count)); + /* Get the handle table. */ + auto &handle_table = GetCurrentProcess().GetHandleTable(); + + /* Try to get as a debug object. */ + KScopedAutoObject debug = handle_table.GetObject(debug_handle); + if (debug.IsNotNull()) { + /* Check that the debug object has a process. */ + R_UNLESS(debug->IsAttached(), svc::ResultProcessTerminated()); + R_UNLESS(debug->OpenProcess(), svc::ResultProcessTerminated()); + ON_SCOPE_EXIT { debug->CloseProcess(); }; + + /* Get the thread list. */ + R_TRY(debug->GetProcessUnsafe()->GetThreadList(out_num_threads, out_thread_ids, max_out_count)); } else { - /* Get the handle table. */ - auto &handle_table = GetCurrentProcess().GetHandleTable(); - - /* Try to get as a debug object. */ - KScopedAutoObject debug = handle_table.GetObject(debug_handle); - if (debug.IsNotNull()) { - /* Check that the debug object has a process. */ - R_UNLESS(debug->IsAttached(), svc::ResultProcessTerminated()); - R_UNLESS(debug->OpenProcess(), svc::ResultProcessTerminated()); - ON_SCOPE_EXIT { debug->CloseProcess(); }; - - /* Get the thread list. */ - R_TRY(debug->GetProcessUnsafe()->GetThreadList(out_num_threads, out_thread_ids, max_out_count)); - } else { - /* Try to get as a process. */ - KScopedAutoObject process = handle_table.GetObjectWithoutPseudoHandle(debug_handle); - R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle()); + /* Only allow getting as a process (or global) if the caller does not have ForceDebugProd. */ + R_UNLESS(!GetCurrentProcess().CanForceDebugProd(), svc::ResultInvalidHandle()); + /* Try to get as a process. */ + KScopedAutoObject process = handle_table.GetObjectWithoutPseudoHandle(debug_handle); + if (process.IsNotNull()) { /* Get the thread list. */ R_TRY(process->GetThreadList(out_num_threads, out_thread_ids, max_out_count)); + } else { + /* If the object is not a process, the caller may want the global thread list. */ + R_UNLESS(debug_handle == ams::svc::InvalidHandle, svc::ResultInvalidHandle()); + + /* If passed invalid handle, we should return the global thread list. */ + R_TRY(KThread::GetThreadList(out_num_threads, out_thread_ids, max_out_count)); } } diff --git a/stratosphere/creport/creport.json b/stratosphere/creport/creport.json index cdd28371d..99859c3d2 100644 --- a/stratosphere/creport/creport.json +++ b/stratosphere/creport/creport.json @@ -110,6 +110,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } } diff --git a/stratosphere/dmnt.gen2/dmnt.gen2.json b/stratosphere/dmnt.gen2/dmnt.gen2.json index 918f1262c..e0d970789 100644 --- a/stratosphere/dmnt.gen2/dmnt.gen2.json +++ b/stratosphere/dmnt.gen2/dmnt.gen2.json @@ -105,6 +105,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } }] diff --git a/stratosphere/fatal/fatal.json b/stratosphere/fatal/fatal.json index 45b718089..aef307a68 100644 --- a/stratosphere/fatal/fatal.json +++ b/stratosphere/fatal/fatal.json @@ -104,6 +104,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } }] diff --git a/stratosphere/loader/source/ldr_capabilities.cpp b/stratosphere/loader/source/ldr_capabilities.cpp index 6835267b3..cd93d855f 100644 --- a/stratosphere/loader/source/ldr_capabilities.cpp +++ b/stratosphere/loader/source/ldr_capabilities.cpp @@ -308,10 +308,19 @@ namespace ams::ldr { ); DEFINE_CAPABILITY_CLASS(DebugFlags, - DEFINE_CAPABILITY_FIELD(AllowDebug, IdBits, 1, bool); - DEFINE_CAPABILITY_FIELD(ForceDebug, AllowDebug, 1, bool); + DEFINE_CAPABILITY_FIELD(AllowDebug, IdBits, 1, bool); + DEFINE_CAPABILITY_FIELD(ForceDebugProd, AllowDebug, 1, bool); + DEFINE_CAPABILITY_FIELD(ForceDebug, ForceDebugProd, 1, bool); bool IsValid(const util::BitPack32 *kac, size_t kac_count) const { + u32 total = 0; + if (this->GetAllowDebug()) { ++total; } + if (this->GetForceDebugProd()) { ++total; } + if (this->GetForceDebug()) { ++total; } + if (total > 1) { + return false; + } + for (size_t i = 0; i < kac_count; i++) { if (GetCapabilityId(kac[i]) == Id) { const auto restriction = Decode(kac[i]); @@ -319,12 +328,14 @@ namespace ams::ldr { return (restriction.GetValue() & this->GetValue()) == this->GetValue(); } } + return false; } - static constexpr util::BitPack32 Encode(bool allow_debug, bool force_debug) { + static constexpr util::BitPack32 Encode(bool allow_debug, bool force_debug_prod, bool force_debug) { util::BitPack32 encoded{IdBitsValue}; encoded.Set(allow_debug); + encoded.Set(force_debug_prod); encoded.Set(force_debug); return encoded; } @@ -406,7 +417,7 @@ namespace ams::ldr { kac[i] = CapabilityApplicationType::Encode(flags & ProgramInfoFlag_ApplicationTypeMask); break; case CapabilityId::DebugFlags: - kac[i] = CapabilityDebugFlags::Encode((flags & ProgramInfoFlag_AllowDebug) != 0, CapabilityDebugFlags::Decode(cap).GetForceDebug()); + kac[i] = CapabilityDebugFlags::Encode((flags & ProgramInfoFlag_AllowDebug) != 0, CapabilityDebugFlags::Decode(cap).GetForceDebugProd(), CapabilityDebugFlags::Decode(cap).GetForceDebug()); break; default: break; diff --git a/stratosphere/pm/pm.json b/stratosphere/pm/pm.json index 005504b72..4ffe5e94e 100644 --- a/stratosphere/pm/pm.json +++ b/stratosphere/pm/pm.json @@ -85,6 +85,7 @@ "type": "debug_flags", "value": { "allow_debug": false, + "force_debug_prod": false, "force_debug": true } } From ff38a32a9bcf855e767a8b2f85552d5ca2738e22 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 17:42:02 -0700 Subject: [PATCH 149/238] kern/ldr: add support for --x executables --- .../arch/arm64/kern_k_page_table.hpp | 21 +++++++++----- .../arm64/kern_userspace_memory_access.hpp | 11 +++++++ .../arch/arm64/kern_exception_handlers.cpp | 29 ++----------------- .../arm64/kern_userspace_memory_access_asm.s | 15 ++++++++++ .../source/kern_k_page_table_base.cpp | 5 ++++ .../source/svc/kern_svc_process_memory.cpp | 1 + .../include/stratosphere/ldr/ldr_types.hpp | 1 + .../os_process_memory_impl.os.horizon.cpp | 1 + .../loader/source/ldr_process_creation.cpp | 10 +++---- 9 files changed, 54 insertions(+), 40 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 370211b2b..2ccd4b72a 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -109,6 +109,9 @@ namespace ams::kern::arch::arm64 { KPageTableManager &GetPageTableManager() const { return *m_manager; } private: constexpr PageTableEntry GetEntryTemplate(const KPageProperties properties) const { + /* Check that the property is not kernel execute. */ + MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_KernelExecute) == 0); + /* Set basic attributes. */ PageTableEntry entry{PageTableEntry::ExtensionFlag_Valid}; entry.SetPrivilegedExecuteNever(true); @@ -122,22 +125,24 @@ namespace ams::kern::arch::arm64 { /* Set page attribute. */ if (properties.io) { MESOSPHERE_ABORT_UNLESS(!properties.uncached); - MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); + MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0); entry.SetPageAttribute(PageTableEntry::PageAttribute_Device_nGnRnE) .SetUserExecuteNever(true); } else if (properties.uncached) { - MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); + MESOSPHERE_ABORT_UNLESS((properties.perm & KMemoryPermission_UserExecute) == 0); - entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable); + entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemoryNotCacheable) + .SetUserExecuteNever(true); } else { entry.SetPageAttribute(PageTableEntry::PageAttribute_NormalMemory); - } - /* Set user execute never bit. */ - if (properties.perm != KMemoryPermission_UserReadExecute) { - MESOSPHERE_ABORT_UNLESS((properties.perm & (KMemoryPermission_KernelExecute | KMemoryPermission_UserExecute)) == 0); - entry.SetUserExecuteNever(true); + if ((properties.perm & KMemoryPermission_UserExecute) != 0) { + /* Check that the permission is either r--/--x or r--/r-x. */ + MESOSPHERE_ABORT_UNLESS((properties.perm & ~ams::svc::MemoryPermission_Read) == (KMemoryPermission_KernelRead | KMemoryPermission_UserExecute)); + } else { + entry.SetUserExecuteNever(true); + } } /* Set AP[1] based on perm. */ diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp index 9e0c1844e..6afabe51c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp @@ -21,7 +21,18 @@ namespace ams::kern::arch::arm64 { void UserspaceAccessFunctionAreaBegin(); class UserspaceAccess { + private: + static bool CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src); public: + static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) { + /* Check that the address is within the valid userspace range. */ + if (const uintptr_t src_uptr = reinterpret_cast(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) { + return false; + } + + return CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(dst, src); + } + static bool CopyMemoryFromUser(void *dst, const void *src, size_t size); static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size); static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index d55e217e3..0fc25c741 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -100,6 +100,8 @@ namespace ams::kern::arch::arm64 { u32 insn_value = 0; if (UserspaceAccess::CopyMemoryFromUser(std::addressof(insn_value), reinterpret_cast(context->pc), sizeof(insn_value))) { insn = insn_value; + } else if (KTargetSystem::IsDebugMode() && (context->pc & 3) == 0 && UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccess(std::addressof(insn_value), reinterpret_cast(context->pc))) { + insn = insn_value; } else { insn = 0; } @@ -112,33 +114,6 @@ namespace ams::kern::arch::arm64 { bool should_process_user_exception = KTargetSystem::IsUserExceptionHandlersEnabled(); const u64 ec = (esr >> 26) & 0x3F; - switch (ec) { - case EsrEc_Unknown: - case EsrEc_IllegalExecution: - case EsrEc_Svc32: - case EsrEc_Svc64: - case EsrEc_PcAlignmentFault: - case EsrEc_SpAlignmentFault: - case EsrEc_SErrorInterrupt: - case EsrEc_BreakPointEl0: - case EsrEc_SoftwareStepEl0: - case EsrEc_WatchPointEl0: - case EsrEc_BkptInstruction: - case EsrEc_BrkInstruction: - break; - default: - { - /* If the fault address's state is KMemoryState_Code and the user can't read the address, force processing exception. */ - KMemoryInfo info; - ams::svc::PageInfo pi; - if (R_SUCCEEDED(cur_process.GetPageTable().QueryInfo(std::addressof(info), std::addressof(pi), far))) { - if (info.GetState() == KMemoryState_Code && ((info.GetPermission() & KMemoryPermission_UserRead) != KMemoryPermission_UserRead)) { - should_process_user_exception = true; - } - } - } - break; - } /* In the event that we return from this exception, we want SPSR.SS set so that we advance an instruction if single-stepping. */ #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s index e697fde3c..01104deb9 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s @@ -154,6 +154,21 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv: mov x0, #1 ret +/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, %function +.balign 0x10 +_ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv: + /* Just load and store a u32. */ + /* NOTE: This is done with supervisor access permissions. */ + ldr w2, [x1] + str w2, [x0] + + /* We're done. */ + mov x0, #1 + ret + /* ams::kern::arch::arm64::UserspaceAccess::CopyStringFromUser(void *dst, const void *src, size_t size) */ .section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits .global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 2a9402ecc..d141490ef 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1787,6 +1787,11 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); + /* If we're creating an executable mapping, take and immediately release the scheduler lock. This will force a reschedule. */ + if (is_x) { + KScopedSchedulerLock sl; + } + /* Perform mapping operation. */ const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; const auto operation = was_x ? OperationType_ChangePermissionsAndRefreshAndFlush : OperationType_ChangePermissions; diff --git a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp index 91d799d78..41420ca06 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process_memory.cpp @@ -27,6 +27,7 @@ namespace ams::kern::svc { case ams::svc::MemoryPermission_Read: case ams::svc::MemoryPermission_ReadWrite: case ams::svc::MemoryPermission_ReadExecute: + case ams::svc::MemoryPermission_Execute: return true; default: return false; diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index 325d2a35d..e81be6b7d 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -226,6 +226,7 @@ namespace ams::ldr { MetaFlag_OptimizeMemoryAllocation = (1 << 4), MetaFlag_DisableDeviceAddressSpaceMerge = (1 << 5), MetaFlag_EnableAliasRegionExtraSize = (1 << 6), + MetaFlag_PreventCodeReads = (1 << 7), }; enum AddressSpaceType { diff --git a/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp index de7b241a6..686cc6995 100644 --- a/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_process_memory_impl.os.horizon.cpp @@ -27,6 +27,7 @@ namespace ams::os::impl { case os::MemoryPermission_ReadOnly: return svc::MemoryPermission_Read; case os::MemoryPermission_ReadWrite: return svc::MemoryPermission_ReadWrite; case os::MemoryPermission_ReadExecute: return svc::MemoryPermission_ReadExecute; + case os::MemoryPermission_ExecuteOnly: return svc::MemoryPermission_Execute; AMS_UNREACHABLE_DEFAULT_CASE(); } } diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index a7d657897..c1daeeb9f 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -555,7 +555,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size) { + Result LoadAutoLoadModule(os::NativeHandle process_handle, fs::FileHandle file, const NsoHeader *nso_header, uintptr_t nso_address, size_t nso_size, bool prevent_code_reads) { /* Map and read data from file. */ { /* Map the process memory. */ @@ -594,7 +594,7 @@ namespace ams::ldr { const size_t ro_size = util::AlignUp(nso_header->ro_size, os::MemoryPageSize); const size_t rw_size = util::AlignUp(nso_header->rw_size + nso_header->bss_size, os::MemoryPageSize); if (text_size) { - R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->text_dst_offset, text_size, os::MemoryPermission_ReadExecute)); + R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->text_dst_offset, text_size, prevent_code_reads ? os::MemoryPermission_ExecuteOnly : os::MemoryPermission_ReadExecute)); } if (ro_size) { R_TRY(os::SetProcessMemoryPermission(process_handle, nso_address + nso_header->ro_dst_offset, ro_size, os::MemoryPermission_ReadOnly)); @@ -606,7 +606,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadAutoLoadModules(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const ArgumentStore::Entry *argument) { + Result LoadAutoLoadModules(const ProcessInfo *process_info, const NsoHeader *nso_headers, const bool *has_nso, const ArgumentStore::Entry *argument, bool prevent_code_reads) { /* Load each NSO. */ for (size_t i = 0; i < Nso_Count; i++) { if (has_nso[i]) { @@ -614,7 +614,7 @@ namespace ams::ldr { R_TRY(fs::OpenFile(std::addressof(file), GetNsoPath(i), fs::OpenMode_Read)); ON_SCOPE_EXIT { fs::CloseFile(file); }; - R_TRY(LoadAutoLoadModule(process_info->process_handle, file, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i])); + R_TRY(LoadAutoLoadModule(process_info->process_handle, file, nso_headers + i, process_info->nso_address[i], process_info->nso_size[i], prevent_code_reads)); } } @@ -658,7 +658,7 @@ namespace ams::ldr { ON_RESULT_FAILURE { svc::CloseHandle(process_handle); }; /* Load all auto load modules. */ - R_RETURN(LoadAutoLoadModules(out, nso_headers, has_nso, argument)); + R_RETURN(LoadAutoLoadModules(out, nso_headers, has_nso, argument, (meta->npdm->flags & ldr::Npdm::MetaFlag_PreventCodeReads) != 0)); } } From 912b84c4e3a3d5c69809543b8685069d0e119869 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 21:36:49 -0700 Subject: [PATCH 150/238] kern: add minimum alignment support to KMemoryManager --- .../nintendo/nx/kern_k_memory_layout.hpp | 4 +++ .../mesosphere/kern_k_memory_manager.hpp | 9 +++-- .../source/kern_k_memory_manager.cpp | 33 +++++++++++++++++-- .../libmesosphere/source/kern_k_process.cpp | 1 - libraries/libmesosphere/source/kern_main.cpp | 3 +- .../source/svc/kern_svc_physical_memory.cpp | 18 +++++----- .../source/svc/kern_svc_process.cpp | 6 ++-- 7 files changed, 58 insertions(+), 16 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp index b12e8d02e..4e82780b0 100644 --- a/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp +++ b/libraries/libmesosphere/include/mesosphere/board/nintendo/nx/kern_k_memory_layout.hpp @@ -24,4 +24,8 @@ namespace ams::kern { constexpr inline size_t MainMemorySize = 4_GB; constexpr inline size_t MainMemorySizeMax = 8_GB; + constexpr inline u32 MinimumMemoryManagerAlignmentShifts[] = { + 0, 0, 0, 0 + }; + } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp index bd596dfd0..99ef1f6b5 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_manager.hpp @@ -164,6 +164,7 @@ namespace ams::kern { size_t m_num_managers; u64 m_optimized_process_ids[Pool_Count]; bool m_has_optimized_process[Pool_Count]; + s32 m_min_heap_indexes[Pool_Count]; private: Impl &GetManager(KPhysicalAddress address) { return m_managers[KMemoryLayout::GetPhysicalLinearRegion(address).GetAttributes()]; @@ -188,12 +189,12 @@ namespace ams::kern { Result AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index); public: KMemoryManager() - : m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process() + : m_pool_locks(), m_pool_managers_head(), m_pool_managers_tail(), m_managers(), m_num_managers(), m_optimized_process_ids(), m_has_optimized_process(), m_min_heap_indexes() { /* ... */ } - NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size); + NOINLINE void Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts); NOINLINE Result InitializeOptimizedMemory(u64 process_id, Pool pool); NOINLINE void FinalizeOptimizedMemory(u64 process_id, Pool pool); @@ -299,6 +300,10 @@ namespace ams::kern { manager->DumpFreeList(); } } + + size_t GetMinimumAlignment(Pool pool) { + return KPageHeap::GetBlockSize(m_min_heap_indexes[pool]); + } public: static size_t CalculateManagementOverheadSize(size_t region_size) { return Impl::CalculateManagementOverheadSize(region_size); diff --git a/libraries/libmesosphere/source/kern_k_memory_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_manager.cpp index fa533387c..aa5f5bdcc 100644 --- a/libraries/libmesosphere/source/kern_k_memory_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_manager.cpp @@ -35,7 +35,7 @@ namespace ams::kern { } - void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size) { + void KMemoryManager::Initialize(KVirtualAddress management_region, size_t management_region_size, const u32 *min_align_shifts) { /* Clear the management region to zero. */ const KVirtualAddress management_region_end = management_region + management_region_size; std::memset(GetVoidPointer(management_region), 0, management_region_size); @@ -154,6 +154,17 @@ namespace ams::kern { for (size_t i = 0; i < m_num_managers; ++i) { m_managers[i].SetInitialUsedHeapSize(reserved_sizes[i]); } + + /* Determine the min heap size for all pools. */ + for (size_t i = 0; i < Pool_Count; ++i) { + /* Determine the min alignment for the pool in pages. */ + const size_t min_align_pages = 1 << min_align_shifts[i]; + + /* Determine a heap index. */ + if (const auto heap_index = KPageHeap::GetAlignedBlockIndex(min_align_pages, min_align_pages); heap_index >= 0) { + m_min_heap_indexes[i] = heap_index; + } + } } Result KMemoryManager::InitializeOptimizedMemory(u64 process_id, Pool pool) { @@ -192,8 +203,19 @@ namespace ams::kern { return Null; } - /* Lock the pool that we're allocating from. */ + /* Determine the pool and direction we're allocating from. */ const auto [pool, dir] = DecodeOption(option); + + /* Check that we're allocating a correctly aligned number of pages. */ + const size_t min_align_pages = KPageHeap::GetBlockNumPages(m_min_heap_indexes[pool]); + if (!util::IsAligned(num_pages, min_align_pages)) { + return Null; + } + + /* Update our alignment. */ + align_pages = std::max(align_pages, min_align_pages); + + /* Lock the pool that we're allocating from. */ KScopedLightLock lk(m_pool_locks[pool]); /* Choose a heap based on our page size request. */ @@ -226,6 +248,13 @@ namespace ams::kern { } Result KMemoryManager::AllocatePageGroupImpl(KPageGroup *out, size_t num_pages, Pool pool, Direction dir, bool unoptimized, bool random, s32 min_heap_index) { + /* Check that we're allocating a correctly aligned number of pages. */ + const size_t min_align_pages = KPageHeap::GetBlockNumPages(m_min_heap_indexes[pool]); + R_UNLESS(util::IsAligned(num_pages, min_align_pages), svc::ResultInvalidSize()); + + /* Adjust our min heap index to the pool minimum if needed. */ + min_heap_index = std::max(min_heap_index, m_min_heap_indexes[pool]); + /* Choose a heap based on our page size request. */ const s32 heap_index = KPageHeap::GetBlockIndex(num_pages); R_UNLESS(0 <= heap_index, svc::ResultOutOfMemory()); diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 24c6baef5..19a9fd85e 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -924,7 +924,6 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(m_main_thread_stack_size == 0); /* Ensure that we're allocating a valid stack. */ - stack_size = util::AlignUp(stack_size, PageSize); R_UNLESS(stack_size + m_code_size <= m_max_process_memory, svc::ResultOutOfMemory()); R_UNLESS(stack_size + m_code_size >= m_code_size, svc::ResultOutOfMemory()); diff --git a/libraries/libmesosphere/source/kern_main.cpp b/libraries/libmesosphere/source/kern_main.cpp index 0f1782c2a..160bb495d 100644 --- a/libraries/libmesosphere/source/kern_main.cpp +++ b/libraries/libmesosphere/source/kern_main.cpp @@ -56,8 +56,9 @@ namespace ams::kern { { const auto &management_region = KMemoryLayout::GetPoolManagementRegion(); MESOSPHERE_ABORT_UNLESS(management_region.GetEndAddress() != 0); + static_assert(util::size(MinimumMemoryManagerAlignmentShifts) == KMemoryManager::Pool_Count); - Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize()); + Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize(), MinimumMemoryManagerAlignmentShifts); } /* Copy the Initial Process Binary to safe memory. */ diff --git a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp index fc5414905..e2237877d 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_physical_memory.cpp @@ -48,10 +48,11 @@ namespace ams::kern::svc { Result MapPhysicalMemory(uintptr_t address, size_t size) { /* Validate address / size. */ - R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress()); - R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); - R_UNLESS(size > 0, svc::ResultInvalidSize()); - R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); + const size_t min_alignment = Kernel::GetMemoryManager().GetMinimumAlignment(GetCurrentProcess().GetMemoryPool()); + R_UNLESS(util::IsAligned(address, min_alignment), svc::ResultInvalidAddress()); + R_UNLESS(util::IsAligned(size, min_alignment), svc::ResultInvalidSize()); + R_UNLESS(size > 0, svc::ResultInvalidSize()); + R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); /* Verify that the process has system resource. */ auto &process = GetCurrentProcess(); @@ -69,10 +70,11 @@ namespace ams::kern::svc { Result UnmapPhysicalMemory(uintptr_t address, size_t size) { /* Validate address / size. */ - R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress()); - R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize()); - R_UNLESS(size > 0, svc::ResultInvalidSize()); - R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); + const size_t min_alignment = Kernel::GetMemoryManager().GetMinimumAlignment(GetCurrentProcess().GetMemoryPool()); + R_UNLESS(util::IsAligned(address, min_alignment), svc::ResultInvalidAddress()); + R_UNLESS(util::IsAligned(size, min_alignment), svc::ResultInvalidSize()); + R_UNLESS(size > 0, svc::ResultInvalidSize()); + R_UNLESS((address < address + size), svc::ResultInvalidMemoryRegion()); /* Verify that the process has system resource. */ auto &process = GetCurrentProcess(); diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 98c8740f2..27ff14b4f 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -296,7 +296,9 @@ namespace ams::kern::svc { Result StartProcess(ams::svc::Handle process_handle, int32_t priority, int32_t core_id, uint64_t main_thread_stack_size) { /* Validate stack size. */ - R_UNLESS(main_thread_stack_size == static_cast(main_thread_stack_size), svc::ResultOutOfMemory()); + const uint64_t aligned_stack_size = util::AlignUp(main_thread_stack_size, Kernel::GetMemoryManager().GetMinimumAlignment(GetCurrentProcess().GetMemoryPool())); + R_UNLESS(aligned_stack_size >= main_thread_stack_size, svc::ResultOutOfMemory()); + R_UNLESS(aligned_stack_size == static_cast(aligned_stack_size), svc::ResultOutOfMemory()); /* Get the target process. */ KScopedAutoObject process = GetCurrentProcess().GetHandleTable().GetObject(process_handle); @@ -314,7 +316,7 @@ namespace ams::kern::svc { process->SetIdealCoreId(core_id); /* Run the process. */ - R_RETURN(process->Run(priority, static_cast(main_thread_stack_size))); + R_RETURN(process->Run(priority, static_cast(aligned_stack_size))); } Result TerminateProcess(ams::svc::Handle process_handle) { From 3b03b9603c65960c15e738aea5a5ffe9a25305cf Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 21:46:15 -0700 Subject: [PATCH 151/238] kern: specify allowable ipc client memory attr via inverted-whitelist, not blacklist --- libraries/libmesosphere/source/kern_k_page_table_base.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index d141490ef..4ebaad0bd 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -3834,15 +3834,15 @@ namespace ams::kern { switch (dst_state) { case KMemoryState_Ipc: test_state = KMemoryState_FlagCanUseIpc; - test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_DeviceShared | KMemoryAttribute_Locked; + test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_IpcLocked)); break; case KMemoryState_NonSecureIpc: test_state = KMemoryState_FlagCanUseNonSecureIpc; - test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_Locked; + test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_IpcLocked)); break; case KMemoryState_NonDeviceIpc: test_state = KMemoryState_FlagCanUseNonDeviceIpc; - test_attr_mask = KMemoryAttribute_Uncached | KMemoryAttribute_Locked; + test_attr_mask = KMemoryAttribute_All & (~(KMemoryAttribute_PermissionLocked | KMemoryAttribute_DeviceShared | KMemoryAttribute_IpcLocked)); break; default: R_THROW(svc::ResultInvalidCombination()); From 23ba31da1f61f249da590b045efda3f1e36ee6f7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 21:49:38 -0700 Subject: [PATCH 152/238] kern: add note that N ifdef'd out calling HandleException() for EL1 faults --- .../kernel/source/arch/arm64/kern_exception_handlers_asm.s | 1 + 1 file changed, 1 insertion(+) diff --git a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s index d81eb7e89..a3a877b7e 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s @@ -444,6 +444,7 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: ERET_WITH_SPECULATION_BARRIER 2: /* The exception wasn't an triggered by copying memory from userspace. */ + /* NOTE: The following is, as of 19.0.0, now ifdef'd out on NX non-debug kernel. */ ldr x0, [sp, #8] ldr x1, [sp, #16] From 9cfd5355685a359652f612b332fa8d4241590241 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 9 Oct 2024 22:01:45 -0700 Subject: [PATCH 153/238] kern: invoke supervisor mode thread functions from C++ context with valid stack frame --- .../source/arch/arm64/kern_k_thread_context.cpp | 9 +++++++++ .../kernel/source/arch/arm64/kern_k_thread_context_asm.s | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp index b3cef6755..76e91cff7 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_thread_context.cpp @@ -21,6 +21,15 @@ namespace ams::kern::arch::arm64 { void UserModeThreadStarter(); void SupervisorModeThreadStarter(); + void InvokeSupervisorModeThread(uintptr_t argument, uintptr_t entrypoint) { + /* Invoke the function. */ + using SupervisorModeFunctionType = void (*)(uintptr_t); + reinterpret_cast(entrypoint)(argument); + + /* Wait forever. */ + AMS_INFINITE_LOOP(); + } + void OnThreadStart() { MESOSPHERE_ASSERT(!KInterruptManager::AreInterruptsEnabled()); /* Send KDebug event for this thread's creation. */ diff --git a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s index 362adc712..4b4b1bd3a 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_k_thread_context_asm.s @@ -76,6 +76,9 @@ _ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv: /* v */ /* | u64 argument | u64 entrypoint | KThread::StackParameters (size 0x30) | */ + /* Clear the link register. */ + mov x30, #0 + /* Load the argument and entrypoint. */ ldp x0, x1, [sp], #0x10 @@ -84,4 +87,6 @@ _ZN3ams4kern4arch5arm6427SupervisorModeThreadStarterEv: /* Mask I bit in DAIF */ msr daifclr, #2 - br x1 + + /* Invoke the function (by calling ams::kern::arch::arm64::InvokeSupervisorModeThread(argument, entrypoint)). */ + b _ZN3ams4kern4arch5arm6426InvokeSupervisorModeThreadEmm From 624f8d0d8dcec8500e71d333b7574fdfc65f18d4 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 01:40:28 -0700 Subject: [PATCH 154/238] ro: support NROs with read-only first page --- .../include/stratosphere/ro/ro_types.hpp | 17 +++++++++++++++-- stratosphere/ro/source/impl/ro_nro_utils.cpp | 8 ++++++-- stratosphere/ro/source/impl/ro_nro_utils.hpp | 2 +- stratosphere/ro/source/impl/ro_service_impl.cpp | 8 +++++--- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp index 886b771da..4a1ce2684 100644 --- a/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ro/ro_types.hpp @@ -135,14 +135,15 @@ namespace ams::ro { class NroHeader { public: static constexpr u32 Magic = util::FourCC<'N','R','O','0'>::Code; + static constexpr u32 FlagAlignedHeader = 1; private: u32 m_entrypoint_insn; u32 m_mod_offset; u8 m_reserved_08[0x8]; u32 m_magic; - u8 m_reserved_14[0x4]; + u8 m_version; u32 m_size; - u8 m_reserved_1C[0x4]; + u32 m_flags; u32 m_text_offset; u32 m_text_size; u32 m_ro_offset; @@ -158,10 +159,22 @@ namespace ams::ro { return m_magic == Magic; } + u32 GetVersion() const { + return m_version; + } + u32 GetSize() const { return m_size; } + u32 GetFlags() const { + return m_flags; + } + + bool IsAlignedHeader() const { + return m_flags & FlagAlignedHeader; + } + u32 GetTextOffset() const { return m_text_offset; } diff --git a/stratosphere/ro/source/impl/ro_nro_utils.cpp b/stratosphere/ro/source/impl/ro_nro_utils.cpp index 588a26387..3f01a1c99 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.cpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.cpp @@ -51,11 +51,15 @@ namespace ams::ro::impl { R_SUCCEED(); } - Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size) { - const u64 rx_offset = 0; + Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size, bool is_aligned_header) { + const u64 rx_offset = is_aligned_header ? os::MemoryPageSize : 0; const u64 ro_offset = rx_offset + rx_size; const u64 rw_offset = ro_offset + ro_size; + if (is_aligned_header) { + R_TRY(os::SetProcessMemoryPermission(process_handle, base_address, os::MemoryPageSize, os::MemoryPermission_ReadOnly)); + } + R_TRY(os::SetProcessMemoryPermission(process_handle, base_address + rx_offset, rx_size, os::MemoryPermission_ReadExecute)); R_TRY(os::SetProcessMemoryPermission(process_handle, base_address + ro_offset, ro_size, os::MemoryPermission_ReadOnly)); R_TRY(os::SetProcessMemoryPermission(process_handle, base_address + rw_offset, rw_size, os::MemoryPermission_ReadWrite)); diff --git a/stratosphere/ro/source/impl/ro_nro_utils.hpp b/stratosphere/ro/source/impl/ro_nro_utils.hpp index df018c872..9ea2f7b32 100644 --- a/stratosphere/ro/source/impl/ro_nro_utils.hpp +++ b/stratosphere/ro/source/impl/ro_nro_utils.hpp @@ -21,7 +21,7 @@ namespace ams::ro::impl { /* Utilities for working with NROs. */ Result MapNro(u64 *out_base_address, os::NativeHandle process_handle, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size); - Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size); + Result SetNroPerms(os::NativeHandle process_handle, u64 base_address, u64 rx_size, u64 ro_size, u64 rw_size, bool is_aligned_header); Result UnmapNro(os::NativeHandle process_handle, u64 base_address, u64 nro_heap_address, u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size); } \ No newline at end of file diff --git a/stratosphere/ro/source/impl/ro_service_impl.cpp b/stratosphere/ro/source/impl/ro_service_impl.cpp index 0be672f37..0eee275eb 100644 --- a/stratosphere/ro/source/impl/ro_service_impl.cpp +++ b/stratosphere/ro/source/impl/ro_service_impl.cpp @@ -247,7 +247,7 @@ namespace ams::ro::impl { R_THROW(ro::ResultNotAuthorized()); } - Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) { + Result ValidateNro(ModuleId *out_module_id, u64 *out_rx_size, u64 *out_ro_size, u64 *out_rw_size, bool *out_aligned_header, u64 base_address, u64 expected_nro_size, u64 expected_bss_size) { /* Map the NRO. */ void *mapped_memory = nullptr; R_TRY_CATCH(os::MapProcessMemory(std::addressof(mapped_memory), m_process_handle, base_address, expected_nro_size, ro::impl::GenerateSecureRandom)) { @@ -306,6 +306,7 @@ namespace ams::ro::impl { *out_rx_size = text_size; *out_ro_size = ro_size; *out_rw_size = rw_size; + *out_aligned_header = header->IsAlignedHeader(); R_SUCCEED(); } @@ -557,10 +558,11 @@ namespace ams::ro::impl { /* Validate the NRO (parsing region extents). */ u64 rx_size = 0, ro_size = 0, rw_size = 0; - R_TRY(context->ValidateNro(std::addressof(nro_info->module_id), std::addressof(rx_size), std::addressof(ro_size), std::addressof(rw_size), nro_info->base_address, nro_size, bss_size)); + bool aligned_header = false; + R_TRY(context->ValidateNro(std::addressof(nro_info->module_id), std::addressof(rx_size), std::addressof(ro_size), std::addressof(rw_size), std::addressof(aligned_header), nro_info->base_address, nro_size, bss_size)); /* Set NRO perms. */ - R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size)); + R_TRY(SetNroPerms(context->GetProcessHandle(), nro_info->base_address, rx_size, ro_size, rw_size + bss_size, aligned_header)); context->SetNroInfoInUse(nro_info, true); nro_info->code_size = rx_size + ro_size; From 77d239265d289959ce60337ededd69746c2f56c2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 02:37:18 -0700 Subject: [PATCH 155/238] ns_mitm: update to support new 19.0.0 command --- .../include/stratosphere/hos/hos_types.hpp | 1 + .../ams_mitm/source/ns_mitm/ns_shim.c | 27 +++++++++++++++++++ .../ams_mitm/source/ns_mitm/ns_shim.h | 1 + .../source/ns_mitm/ns_web_mitm_service.cpp | 5 ++++ .../source/ns_mitm/ns_web_mitm_service.hpp | 10 ++++--- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 597cc0876..a096237a8 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -84,6 +84,7 @@ namespace ams::hos { Version_17_0_1 = ::ams::TargetFirmware_17_0_1, Version_18_0_0 = ::ams::TargetFirmware_18_0_0, Version_18_1_0 = ::ams::TargetFirmware_18_1_0, + Version_19_0_0 = ::ams::TargetFirmware_19_0_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c index 4b6d1b8cd..569ac2f61 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.c @@ -48,6 +48,29 @@ static Result _nsGetApplicationContentPath(Service *s, void* out, size_t out_siz ); } +static Result _nsGetApplicationContentPath2(Service *s, void* out_path, size_t out_size, u64* out_program_id, u8 *out_attr, u64 app_id, NcmContentType content_type) { + const struct { + u8 content_type; + u64 app_id; + } in = { content_type, app_id }; + + struct { + u8 attr; + u64 program_id; + } out; + + Result rc = serviceDispatchInOut(s, 2524, in, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { out_path, out_size } }, + ); + if (R_SUCCEEDED(rc)) { + *out_program_id = out.program_id; + *out_attr = out.attr; + } + + return rc; +} + static Result _nsResolveApplicationContentPath(Service* s, u64 app_id, NcmContentType content_type) { const struct { u8 content_type; @@ -93,6 +116,10 @@ Result nswebGetRunningApplicationProgramId(NsDocumentInterface* doc, u64* out_pr return _nsGetRunningApplicationProgramId(&doc->s, out_program_id, app_id); } +Result nswebGetApplicationContentPath2(NsDocumentInterface* doc, void* out, size_t out_size, u64* out_program_id, u8 *out_attr, u64 app_id, NcmContentType content_type) { + return _nsGetApplicationContentPath2(&doc->s, out, out_size, out_program_id, out_attr, app_id, content_type); +} + void nsDocumentInterfaceClose(NsDocumentInterface* doc) { serviceClose(&doc->s); } diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h index afb8125d3..9cfd2774d 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_shim.h @@ -25,6 +25,7 @@ Result nsamGetRunningApplicationProgramIdFwd(Service* s, u64* out_program_id, u6 Result nswebGetApplicationContentPath(NsDocumentInterface* doc, void* out, size_t out_size, u8 *out_attr, u64 app_id, NcmContentType content_type); Result nswebResolveApplicationContentPath(NsDocumentInterface* doc, u64 app_id, NcmContentType content_type); Result nswebGetRunningApplicationProgramId(NsDocumentInterface* doc, u64* out_program_id, u64 app_id); +Result nswebGetApplicationContentPath2(NsDocumentInterface* doc, void* out, size_t out_size, u64* out_program_id, u8 *out_attr, u64 app_id, NcmContentType content_type); void nsDocumentInterfaceClose(NsDocumentInterface* doc); diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp index 9568f9108..5613d267e 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.cpp @@ -38,6 +38,11 @@ namespace ams::mitm::ns { R_RETURN(nswebGetRunningApplicationProgramId(m_srv.get(), reinterpret_cast(out.GetPointer()), static_cast(application_id))); } + Result NsDocumentService::GetApplicationContentPath2(const sf::OutBuffer &out_path, sf::Out out_program_id, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type) { + static_assert(sizeof(*out_attr.GetPointer()) == sizeof(u8)); + R_RETURN(nswebGetApplicationContentPath2(m_srv.get(), out_path.GetPointer(), out_path.GetSize(), reinterpret_cast(out_program_id.GetPointer()), reinterpret_cast(out_attr.GetPointer()), static_cast(application_id), static_cast(content_type))); + } + Result NsWebMitmService::GetDocumentInterface(sf::Out> out) { /* Open a document interface. */ NsDocumentInterface doc; diff --git a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp index b08669e59..e9adbe46d 100644 --- a/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp +++ b/stratosphere/ams_mitm/source/ns_mitm/ns_web_mitm_service.hpp @@ -18,10 +18,11 @@ #include "ns_shim.h" -#define AMS_NS_DOCUMENT_MITM_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 21, Result, GetApplicationContentPath, (const sf::OutBuffer &out_path, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type), (out_path, out_attr, application_id, content_type)) \ - AMS_SF_METHOD_INFO(C, H, 23, Result, ResolveApplicationContentPath, (ncm::ProgramId application_id, u8 content_type), (application_id, content_type)) \ - AMS_SF_METHOD_INFO(C, H, 92, Result, GetRunningApplicationProgramId, (sf::Out out, ncm::ProgramId application_id), (out, application_id), hos::Version_6_0_0) +#define AMS_NS_DOCUMENT_MITM_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 21, Result, GetApplicationContentPath, (const sf::OutBuffer &out_path, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type), (out_path, out_attr, application_id, content_type)) \ + AMS_SF_METHOD_INFO(C, H, 23, Result, ResolveApplicationContentPath, (ncm::ProgramId application_id, u8 content_type), (application_id, content_type)) \ + AMS_SF_METHOD_INFO(C, H, 92, Result, GetRunningApplicationProgramId, (sf::Out out, ncm::ProgramId application_id), (out, application_id), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 2524, Result, GetApplicationContentPath2, (const sf::OutBuffer &out_path, sf::Out out_program_id, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type), (out_path, out_program_id, out_attr, application_id, content_type), hos::Version_19_0_0) AMS_SF_DEFINE_INTERFACE(ams::mitm::ns::impl, IDocumentInterface, AMS_NS_DOCUMENT_MITM_INTERFACE_INFO, 0x0F9B1C00) @@ -47,6 +48,7 @@ namespace ams::mitm::ns { Result GetApplicationContentPath(const sf::OutBuffer &out_path, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type); Result ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type); Result GetRunningApplicationProgramId(sf::Out out, ncm::ProgramId application_id); + Result GetApplicationContentPath2(const sf::OutBuffer &out_path, sf::Out out_program_id, sf::Out out_attr, ncm::ProgramId application_id, u8 content_type); }; static_assert(impl::IsIDocumentInterface); From a80d5b5c8631010773cb069ef0cda7eaaae0c4c1 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 02:44:19 -0700 Subject: [PATCH 156/238] pm: add new 19.0.0 commands This is functionally correct, but I have no idea what these are meant to represent. These functions are completely unused on NX. --- .../stratosphere/pm/impl/pm_boot_mode_interface.hpp | 8 +++++--- .../libvapours/include/vapours/results/pm_results.hpp | 1 + stratosphere/pm/source/pm_boot_mode_service.cpp | 11 +++++++++++ stratosphere/pm/source/pm_boot_mode_service.hpp | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp index a34f2272d..66faf57e2 100644 --- a/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/pm/impl/pm_boot_mode_interface.hpp @@ -19,8 +19,10 @@ #include #include -#define AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, void, GetBootMode, (sf::Out out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 1, void, SetMaintenanceBoot, (), ()) +#define AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, void, GetBootMode, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 1, void, SetMaintenanceBoot, (), ()) \ + AMS_SF_METHOD_INFO(C, H, 2, void, GetUnknown, (sf::Out out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, SetUnknown, (u32 val), (val)) AMS_SF_DEFINE_INTERFACE(ams::pm::impl, IBootModeInterface, AMS_PM_I_BOOT_MODE_INTERFACE_INTERFACE_INFO, 0x96D01649) diff --git a/libraries/libvapours/include/vapours/results/pm_results.hpp b/libraries/libvapours/include/vapours/results/pm_results.hpp index 4c9e51ad5..4e4c0e24b 100644 --- a/libraries/libvapours/include/vapours/results/pm_results.hpp +++ b/libraries/libvapours/include/vapours/results/pm_results.hpp @@ -27,5 +27,6 @@ namespace ams::pm { R_DEFINE_ERROR_RESULT(DebugHookInUse, 4); R_DEFINE_ERROR_RESULT(ApplicationRunning, 5); R_DEFINE_ERROR_RESULT(InvalidSize, 6); + R_DEFINE_ERROR_RESULT(Unknown7, 7); } diff --git a/stratosphere/pm/source/pm_boot_mode_service.cpp b/stratosphere/pm/source/pm_boot_mode_service.cpp index ff389fe75..a1a762d34 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.cpp +++ b/stratosphere/pm/source/pm_boot_mode_service.cpp @@ -22,6 +22,7 @@ namespace ams::pm { /* Global bootmode. */ constinit BootMode g_boot_mode = BootMode::Normal; + constinit u32 g_unknown = 0; } @@ -47,4 +48,14 @@ namespace ams::pm { pm::bm::SetMaintenanceBoot(); } + void BootModeService::GetUnknown(sf::Out out) { + out.SetValue(g_unknown); + } + + Result BootModeService::SetUnknown(u32 val) { + R_UNLESS(val <= 3, pm::ResultUnknown7()); + g_unknown = val; + R_SUCCEED(); + } + } diff --git a/stratosphere/pm/source/pm_boot_mode_service.hpp b/stratosphere/pm/source/pm_boot_mode_service.hpp index c650e9b47..b47536ed7 100644 --- a/stratosphere/pm/source/pm_boot_mode_service.hpp +++ b/stratosphere/pm/source/pm_boot_mode_service.hpp @@ -22,6 +22,8 @@ namespace ams::pm { public: void GetBootMode(sf::Out out); void SetMaintenanceBoot(); + void GetUnknown(sf::Out out); + Result SetUnknown(u32 val); }; static_assert(pm::impl::IsIBootModeInterface); From 7aa0bed869c7ed642d5503c6c80e3dc337bc56bd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 03:45:09 -0700 Subject: [PATCH 157/238] ldr: ProgramInfo is 0x410 now, and fix debug flags for hbl --- .../include/stratosphere/ldr/ldr_types.hpp | 3 ++- .../source/ldr/ldr_pm_api.os.horizon.cpp | 2 ++ stratosphere/loader/source/ldr_capabilities.cpp | 14 ++++++++++++++ stratosphere/loader/source/ldr_capabilities.hpp | 2 ++ stratosphere/loader/source/ldr_main.cpp | 2 +- stratosphere/loader/source/ldr_meta.cpp | 4 ++++ 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index e81be6b7d..7d1a94aa1 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -34,9 +34,10 @@ namespace ams::ldr { u32 aci_sac_size; u32 acid_fac_size; u32 aci_fah_size; + u8 unused_20[0x10]; u8 ac_buffer[0x3E0]; }; - static_assert(util::is_pod::value && sizeof(ProgramInfo) == 0x400, "ProgramInfo definition!"); + static_assert(util::is_pod::value && sizeof(ProgramInfo) == 0x410, "ProgramInfo definition!"); enum ProgramInfoFlag { ProgramInfoFlag_SystemModule = (0 << 0), diff --git a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp index 8441977f5..2e00417de 100644 --- a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp +++ b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp @@ -24,6 +24,7 @@ namespace ams::ldr::pm { } Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) { + static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); R_RETURN(ldrPmGetProgramInfo(reinterpret_cast(std::addressof(loc)), reinterpret_cast(out))); } @@ -42,6 +43,7 @@ namespace ams::ldr::pm { Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); + static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(std::addressof(loc)))); } diff --git a/stratosphere/loader/source/ldr_capabilities.cpp b/stratosphere/loader/source/ldr_capabilities.cpp index cd93d855f..b3bc25e65 100644 --- a/stratosphere/loader/source/ldr_capabilities.cpp +++ b/stratosphere/loader/source/ldr_capabilities.cpp @@ -425,6 +425,20 @@ namespace ams::ldr { } } + void FixDebugCapabilityForHbl(util::BitPack32 *kac, size_t count) { + for (size_t i = 0; i < count; ++i) { + const auto cap = kac[i]; + switch (GetCapabilityId(cap)) { + case CapabilityId::DebugFlags: + /* 19.0.0+ disallows more than one flag set; we are always DebugMode for kernel, so ForceDebug is the most powerful/flexible flag to set. */ + kac[i] = CapabilityDebugFlags::Encode(false, false, true); + break; + default: + break; + } + } + } + void PreProcessCapability(util::BitPack32 *kac, size_t count) { for (size_t i = 0; i < count; ++i) { const auto cap = kac[i]; diff --git a/stratosphere/loader/source/ldr_capabilities.hpp b/stratosphere/loader/source/ldr_capabilities.hpp index 0a91b23cc..21748a7fb 100644 --- a/stratosphere/loader/source/ldr_capabilities.hpp +++ b/stratosphere/loader/source/ldr_capabilities.hpp @@ -23,6 +23,8 @@ namespace ams::ldr { u16 MakeProgramInfoFlag(const util::BitPack32 *kac, size_t count); void UpdateProgramInfoFlag(u16 flags, util::BitPack32 *kac, size_t count); + void FixDebugCapabilityForHbl(util::BitPack32 *kac, size_t count); + void PreProcessCapability(util::BitPack32 *kac, size_t count); } diff --git a/stratosphere/loader/source/ldr_main.cpp b/stratosphere/loader/source/ldr_main.cpp index 5b6001f93..5e4d8ca06 100644 --- a/stratosphere/loader/source/ldr_main.cpp +++ b/stratosphere/loader/source/ldr_main.cpp @@ -46,7 +46,7 @@ namespace ams { namespace { struct ServerOptions { - static constexpr size_t PointerBufferSize = 0x400; + static constexpr size_t PointerBufferSize = 0x420; static constexpr size_t MaxDomains = 0; static constexpr size_t MaxDomainObjects = 0; static constexpr bool CanDeferInvokeRequest = false; diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp index ee43aeedc..b1d1a85ad 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -252,6 +252,10 @@ namespace ams::ldr { meta->npdm->main_thread_priority = HblMainThreadPriorityApplet; } } + + /* Fix the debug capabilities, to prevent needing a hbl recompilation. */ + FixDebugCapabilityForHbl(static_cast(meta->acid_kac), meta->acid->kac_size / sizeof(util::BitPack32)); + FixDebugCapabilityForHbl(static_cast(meta->aci_kac), meta->aci->kac_size / sizeof(util::BitPack32)); } else if (hos::GetVersion() >= hos::Version_10_0_0) { /* If storage id is none, there is no base code filesystem, and thus it is impossible for us to validate. */ /* However, if we're an application, we are guaranteed a base code filesystem. */ From 02e837d82e9b36fad9b4a7e5acf7a456556562c6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 05:31:57 -0700 Subject: [PATCH 158/238] kern: start KPageTable(Impl) refactor, use array-with-levels for KPageTableImpl --- .../arch/arm64/kern_k_page_table_entry.hpp | 13 +- .../arch/arm64/kern_k_page_table_impl.hpp | 34 +- .../arch/arm64/kern_k_page_table_impl.cpp | 388 ++++++++---------- 3 files changed, 205 insertions(+), 230 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp index 93925e3fa..8941928ed 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp @@ -170,9 +170,17 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE bool IsReadOnly() const { return this->GetBits(7, 1) != 0; } constexpr ALWAYS_INLINE bool IsUserAccessible() const { return this->GetBits(6, 1) != 0; } constexpr ALWAYS_INLINE bool IsNonSecure() const { return this->GetBits(5, 1) != 0; } + + constexpr ALWAYS_INLINE u64 GetTestTableMask() const { return (m_attributes & ExtensionFlag_TestTableMask); } + constexpr ALWAYS_INLINE bool IsBlock() const { return (m_attributes & ExtensionFlag_TestTableMask) == ExtensionFlag_Valid; } + constexpr ALWAYS_INLINE bool IsPage() const { return (m_attributes & ExtensionFlag_TestTableMask) == ExtensionFlag_TestTableMask; } constexpr ALWAYS_INLINE bool IsTable() const { return (m_attributes & ExtensionFlag_TestTableMask) == 2; } constexpr ALWAYS_INLINE bool IsEmpty() const { return (m_attributes & ExtensionFlag_TestTableMask) == 0; } + + constexpr ALWAYS_INLINE KPhysicalAddress GetTable() const { return this->SelectBits(12, 36); } + + constexpr ALWAYS_INLINE bool IsMappedTable() const { return this->GetBits(0, 2) == 3; } constexpr ALWAYS_INLINE bool IsMapped() const { return this->GetBits(0, 1) != 0; } constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; } @@ -196,10 +204,13 @@ namespace ams::kern::arch::arm64 { return (m_attributes & BaseMaskForMerge) == attr; } - constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const { + constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafe() const { return m_attributes; } + constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafeForSwap() const { + return m_attributes; + } protected: constexpr ALWAYS_INLINE u64 GetRawAttributes() const { return m_attributes; diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index e5df6defb..8616ac0dd 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -37,10 +37,17 @@ namespace ams::kern::arch::arm64 { constexpr bool IsTailMergeDisabled() const { return (this->sw_reserved_bits & PageTableEntry::SoftwareReservedBit_DisableMergeHeadTail) != 0; } }; + enum EntryLevel : u32 { + EntryLevel_L3 = 0, + EntryLevel_L2 = 1, + EntryLevel_L1 = 2, + EntryLevel_Count = 3, + }; + struct TraversalContext { - const L1PageTableEntry *l1_entry; - const L2PageTableEntry *l2_entry; - const L3PageTableEntry *l3_entry; + const PageTableEntry *level_entries[EntryLevel_Count]; + EntryLevel level; + bool is_contiguous; }; private: static constexpr size_t PageBits = util::CountTrailingZeros(PageSize); @@ -53,16 +60,26 @@ namespace ams::kern::arch::arm64 { return (value >> Offset) & ((1ul << Count) - 1); } + static constexpr ALWAYS_INLINE u64 GetBits(u64 value, size_t offset, size_t count) { + return (value >> offset) & ((1ul << count) - 1); + } + template - constexpr ALWAYS_INLINE u64 SelectBits(u64 value) { + static constexpr ALWAYS_INLINE u64 SelectBits(u64 value) { return value & (((1ul << Count) - 1) << Offset); } + static constexpr ALWAYS_INLINE u64 SelectBits(u64 value, size_t offset, size_t count) { + return value & (((1ul << count) - 1) << offset); + } + static constexpr ALWAYS_INLINE uintptr_t GetL0Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL1Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL2Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL3Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } + static constexpr ALWAYS_INLINE uintptr_t GetLevelIndex(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), PageBits + LevelBits * level, LevelBits); } + static constexpr ALWAYS_INLINE uintptr_t GetL1Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 1)>(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2)>(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3)>(GetInteger(addr)); } @@ -70,13 +87,16 @@ namespace ams::kern::arch::arm64 { static constexpr ALWAYS_INLINE uintptr_t GetContiguousL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2) + 4>(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetContiguousL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3) + 4>(GetInteger(addr)); } + static constexpr ALWAYS_INLINE uintptr_t GetBlock(const PageTableEntry *pte, EntryLevel level) { return SelectBits(pte->GetRawAttributesUnsafe(), PageBits + LevelBits * level, LevelBits * (NumLevels + 1 - level)); } + static constexpr ALWAYS_INLINE uintptr_t GetOffset(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), 0, PageBits + LevelBits * level); } + static ALWAYS_INLINE KVirtualAddress GetPageTableVirtualAddress(KPhysicalAddress addr) { return KMemoryLayout::GetLinearVirtualAddress(addr); } - ALWAYS_INLINE bool ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const; - ALWAYS_INLINE bool ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const; - ALWAYS_INLINE bool ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const; + //ALWAYS_INLINE bool ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const; + //ALWAYS_INLINE bool ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const; + //ALWAYS_INLINE bool ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const; private: L1PageTableEntry *m_table; bool m_is_kernel; diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 280498f78..5bc775f66 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -33,103 +33,98 @@ namespace ams::kern::arch::arm64 { return m_table; } - bool KPageTableImpl::ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const { - /* Set the L3 entry. */ - out_context->l3_entry = l3_entry; - - if (l3_entry->IsBlock()) { - /* Set the output entry. */ - out_entry->phys_addr = l3_entry->GetBlock() + (virt_addr & (L3BlockSize - 1)); - if (l3_entry->IsContiguous()) { - out_entry->block_size = L3ContiguousBlockSize; - } else { - out_entry->block_size = L3BlockSize; - } - out_entry->sw_reserved_bits = l3_entry->GetSoftwareReservedBits(); - out_entry->attr = 0; - - return true; - } else { - out_entry->phys_addr = Null; - out_entry->block_size = L3BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - return false; - } - } - - bool KPageTableImpl::ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const { - /* Set the L2 entry. */ - out_context->l2_entry = l2_entry; - - if (l2_entry->IsBlock()) { - /* Set the output entry. */ - out_entry->phys_addr = l2_entry->GetBlock() + (virt_addr & (L2BlockSize - 1)); - if (l2_entry->IsContiguous()) { - out_entry->block_size = L2ContiguousBlockSize; - } else { - out_entry->block_size = L2BlockSize; - } - out_entry->sw_reserved_bits = l2_entry->GetSoftwareReservedBits(); - out_entry->attr = 0; - - /* Set the output context. */ - out_context->l3_entry = nullptr; - return true; - } else if (l2_entry->IsTable()) { - return this->ExtractL3Entry(out_entry, out_context, this->GetL3EntryFromTable(GetPageTableVirtualAddress(l2_entry->GetTable()), virt_addr), virt_addr); - } else { - out_entry->phys_addr = Null; - out_entry->block_size = L2BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - - out_context->l3_entry = nullptr; - return false; - } - } - - bool KPageTableImpl::ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const { - /* Set the L1 entry. */ - out_context->l1_entry = l1_entry; - - if (l1_entry->IsBlock()) { - /* Set the output entry. */ - out_entry->phys_addr = l1_entry->GetBlock() + (virt_addr & (L1BlockSize - 1)); - if (l1_entry->IsContiguous()) { - out_entry->block_size = L1ContiguousBlockSize; - } else { - out_entry->block_size = L1BlockSize; - } - out_entry->sw_reserved_bits = l1_entry->GetSoftwareReservedBits(); - - /* Set the output context. */ - out_context->l2_entry = nullptr; - out_context->l3_entry = nullptr; - return true; - } else if (l1_entry->IsTable()) { - return this->ExtractL2Entry(out_entry, out_context, this->GetL2EntryFromTable(GetPageTableVirtualAddress(l1_entry->GetTable()), virt_addr), virt_addr); - } else { - out_entry->phys_addr = Null; - out_entry->block_size = L1BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - - out_context->l2_entry = nullptr; - out_context->l3_entry = nullptr; - return false; - } - } + // bool KPageTableImpl::ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const { + // /* Set the L3 entry. */ + // out_context->l3_entry = l3_entry; + // + // if (l3_entry->IsBlock()) { + // /* Set the output entry. */ + // out_entry->phys_addr = l3_entry->GetBlock() + (virt_addr & (L3BlockSize - 1)); + // if (l3_entry->IsContiguous()) { + // out_entry->block_size = L3ContiguousBlockSize; + // } else { + // out_entry->block_size = L3BlockSize; + // } + // out_entry->sw_reserved_bits = l3_entry->GetSoftwareReservedBits(); + // out_entry->attr = 0; + // + // return true; + // } else { + // out_entry->phys_addr = Null; + // out_entry->block_size = L3BlockSize; + // out_entry->sw_reserved_bits = 0; + // out_entry->attr = 0; + // return false; + // } + // } + // + // bool KPageTableImpl::ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const { + // /* Set the L2 entry. */ + // out_context->l2_entry = l2_entry; + // + // if (l2_entry->IsBlock()) { + // /* Set the output entry. */ + // out_entry->phys_addr = l2_entry->GetBlock() + (virt_addr & (L2BlockSize - 1)); + // if (l2_entry->IsContiguous()) { + // out_entry->block_size = L2ContiguousBlockSize; + // } else { + // out_entry->block_size = L2BlockSize; + // } + // out_entry->sw_reserved_bits = l2_entry->GetSoftwareReservedBits(); + // out_entry->attr = 0; + // + // /* Set the output context. */ + // out_context->l3_entry = nullptr; + // return true; + // } else if (l2_entry->IsTable()) { + // return this->ExtractL3Entry(out_entry, out_context, this->GetL3EntryFromTable(GetPageTableVirtualAddress(l2_entry->GetTable()), virt_addr), virt_addr); + // } else { + // out_entry->phys_addr = Null; + // out_entry->block_size = L2BlockSize; + // out_entry->sw_reserved_bits = 0; + // out_entry->attr = 0; + // + // out_context->l3_entry = nullptr; + // return false; + // } + // } + // + // bool KPageTableImpl::ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const { + // /* Set the L1 entry. */ + // out_context->level_entries[EntryLevel_L1] = l1_entry; + // + // if (l1_entry->IsBlock()) { + // /* Set the output entry. */ + // out_entry->phys_addr = l1_entry->GetBlock() + (virt_addr & (L1BlockSize - 1)); + // if (l1_entry->IsContiguous()) { + // out_entry->block_size = L1ContiguousBlockSize; + // } else { + // out_entry->block_size = L1BlockSize; + // } + // out_entry->sw_reserved_bits = l1_entry->GetSoftwareReservedBits(); + // + // /* Set the output context. */ + // out_context->l2_entry = nullptr; + // out_context->l3_entry = nullptr; + // return true; + // } else if (l1_entry->IsTable()) { + // return this->ExtractL2Entry(out_entry, out_context, this->GetL2EntryFromTable(GetPageTableVirtualAddress(l1_entry->GetTable()), virt_addr), virt_addr); + // } else { + // out_entry->phys_addr = Null; + // out_entry->block_size = L1BlockSize; + // out_entry->sw_reserved_bits = 0; + // out_entry->attr = 0; + // + // out_context->l2_entry = nullptr; + // out_context->l3_entry = nullptr; + // return false; + // } + // } bool KPageTableImpl::BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const { /* Setup invalid defaults. */ - out_entry->phys_addr = Null; - out_entry->block_size = L1BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - out_context->l1_entry = m_table + m_num_entries; - out_context->l2_entry = nullptr; - out_context->l3_entry = nullptr; + *out_entry = {}; + *out_context = {}; /* Validate that we can read the actual entry. */ const size_t l0_index = GetL0Index(address); @@ -146,125 +141,79 @@ namespace ams::kern::arch::arm64 { } } - /* Extract the entry. */ - const bool valid = this->ExtractL1Entry(out_entry, out_context, this->GetL1Entry(address), address); + /* Get the L1 entry, and check if it's a table. */ + out_context->level_entries[EntryLevel_L1] = this->GetL1Entry(address); + if (out_context->level_entries[EntryLevel_L1]->IsMappedTable()) { + /* Get the L2 entry, and check if it's a table. */ + out_context->level_entries[EntryLevel_L2] = this->GetL2EntryFromTable(GetPageTableVirtualAddress(out_context->level_entries[EntryLevel_L1]->GetTable()), address); + if (out_context->level_entries[EntryLevel_L2]->IsMappedTable()) { + /* Get the L3 entry. */ + out_context->level_entries[EntryLevel_L3] = this->GetL3EntryFromTable(GetPageTableVirtualAddress(out_context->level_entries[EntryLevel_L2]->GetTable()), address); - /* Update the context for next traversal. */ - switch (out_entry->block_size) { - case L1ContiguousBlockSize: - out_context->l1_entry += (L1ContiguousBlockSize / L1BlockSize) - GetContiguousL1Offset(address) / L1BlockSize; - break; - case L1BlockSize: - out_context->l1_entry += 1; - break; - case L2ContiguousBlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += (L2ContiguousBlockSize / L2BlockSize) - GetContiguousL2Offset(address) / L2BlockSize; - break; - case L2BlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += 1; - break; - case L3ContiguousBlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += 1; - out_context->l3_entry += (L3ContiguousBlockSize / L3BlockSize) - GetContiguousL3Offset(address) / L3BlockSize; - break; - case L3BlockSize: - out_context->l1_entry += 1; - out_context->l2_entry += 1; - out_context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + /* It's either a page or not. */ + out_context->level = EntryLevel_L3; + } else { + /* Not a L2 table, so possibly an L2 block. */ + out_context->level = EntryLevel_L2; + } + } else { + /* Not a L1 table, so possibly an L1 block. */ + out_context->level = EntryLevel_L1; } - return valid; + /* Determine other fields. */ + const auto *pte = out_context->level_entries[out_context->level]; + + out_context->is_contiguous = pte->IsContiguous(); + + out_entry->sw_reserved_bits = pte->GetSoftwareReservedBits(); + out_entry->attr = 0; + out_entry->phys_addr = this->GetBlock(pte, out_context->level) + this->GetOffset(address, out_context->level); + out_entry->block_size = static_cast(1) << (PageBits + LevelBits * out_context->level + 4 * out_context->is_contiguous); + + return out_context->level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock(); } bool KPageTableImpl::ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const { - bool valid = false; + /* Advance entry. */ - /* Check if we're not at the end of an L3 table. */ - if (!util::IsAligned(reinterpret_cast(context->l3_entry), PageSize)) { - valid = this->ExtractL3Entry(out_entry, context, context->l3_entry, Null); + auto *cur_pte = context->level_entries[context->level]; + auto *next_pte = reinterpret_cast(context->is_contiguous ? util::AlignDown(reinterpret_cast(cur_pte), 0x10 * sizeof(PageTableEntry)) + 0x10 * sizeof(PageTableEntry) : reinterpret_cast(cur_pte) + sizeof(PageTableEntry)); - switch (out_entry->block_size) { - case L3ContiguousBlockSize: - context->l3_entry += (L3ContiguousBlockSize / L3BlockSize); - break; - case L3BlockSize: - context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } - } else if (!util::IsAligned(reinterpret_cast(context->l2_entry), PageSize)) { - /* We're not at the end of an L2 table. */ - valid = this->ExtractL2Entry(out_entry, context, context->l2_entry, Null); + /* Set the pte. */ + context->level_entries[context->level] = next_pte; - switch (out_entry->block_size) { - case L2ContiguousBlockSize: - context->l2_entry += (L2ContiguousBlockSize / L2BlockSize); - break; - case L2BlockSize: - context->l2_entry += 1; - break; - case L3ContiguousBlockSize: - context->l2_entry += 1; - context->l3_entry += (L3ContiguousBlockSize / L3BlockSize); - break; - case L3BlockSize: - context->l2_entry += 1; - context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } - } else { - /* We need to update the l1 entry. */ - const size_t l1_index = context->l1_entry - m_table; - if (l1_index < m_num_entries) { - valid = this->ExtractL1Entry(out_entry, context, context->l1_entry, Null); - } else { - /* Invalid, end traversal. */ - out_entry->phys_addr = Null; - out_entry->block_size = L1BlockSize; - out_entry->sw_reserved_bits = 0; - out_entry->attr = 0; - context->l1_entry = m_table + m_num_entries; - context->l2_entry = nullptr; - context->l3_entry = nullptr; + /* Advance appropriately. */ + while (context->level < EntryLevel_L1 && util::IsAligned(reinterpret_cast(context->level_entries[context->level]), PageSize)) { + /* Advance the above table by one entry. */ + context->level_entries[context->level + 1]++; + context->level = static_cast(util::ToUnderlying(context->level) + 1); + } + + /* Check if we've hit the end of the L1 table. */ + if (context->level == EntryLevel_L1) { + if (context->level_entries[EntryLevel_L1] - static_cast(m_table) >= m_num_entries) { + *context = {}; + *out_entry = {}; return false; } - - switch (out_entry->block_size) { - case L1ContiguousBlockSize: - context->l1_entry += (L1ContiguousBlockSize / L1BlockSize); - break; - case L1BlockSize: - context->l1_entry += 1; - break; - case L2ContiguousBlockSize: - context->l1_entry += 1; - context->l2_entry += (L2ContiguousBlockSize / L2BlockSize); - break; - case L2BlockSize: - context->l1_entry += 1; - context->l2_entry += 1; - break; - case L3ContiguousBlockSize: - context->l1_entry += 1; - context->l2_entry += 1; - context->l3_entry += (L3ContiguousBlockSize / L3BlockSize); - break; - case L3BlockSize: - context->l1_entry += 1; - context->l2_entry += 1; - context->l3_entry += 1; - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } } - return valid; + /* We may have advanced to a new table, and if we have we should descend. */ + while (context->level > EntryLevel_L3 && context->level_entries[context->level]->IsMappedTable()) { + context->level_entries[context->level - 1] = GetPointer(GetPageTableVirtualAddress(context->level_entries[context->level]->GetTable())); + context->level = static_cast(util::ToUnderlying(context->level) - 1); + } + + const auto *pte = context->level_entries[context->level]; + + context->is_contiguous = pte->IsContiguous(); + + out_entry->sw_reserved_bits = pte->GetSoftwareReservedBits(); + out_entry->attr = 0; + out_entry->phys_addr = this->GetBlock(pte, context->level); + out_entry->block_size = static_cast(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous); + return context->level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock(); } bool KPageTableImpl::GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress address) const { @@ -283,32 +232,27 @@ namespace ams::kern::arch::arm64 { } } - /* Try to get from l1 table. */ - const L1PageTableEntry *l1_entry = this->GetL1Entry(address); - if (l1_entry->IsBlock()) { - *out = l1_entry->GetBlock() + GetL1Offset(address); - return true; - } else if (!l1_entry->IsTable()) { - return false; + /* Get the L1 entry, and check if it's a table. */ + const PageTableEntry *pte = this->GetL1Entry(address); + EntryLevel level = EntryLevel_L1; + if (pte->IsMappedTable()) { + /* Get the L2 entry, and check if it's a table. */ + pte = this->GetL2EntryFromTable(GetPageTableVirtualAddress(pte->GetTable()), address); + level = EntryLevel_L2; + if (pte->IsMappedTable()) { + pte = this->GetL3EntryFromTable(GetPageTableVirtualAddress(pte->GetTable()), address); + level = EntryLevel_L3; + } } - /* Try to get from l2 table. */ - const L2PageTableEntry *l2_entry = this->GetL2Entry(l1_entry, address); - if (l2_entry->IsBlock()) { - *out = l2_entry->GetBlock() + GetL2Offset(address); - return true; - } else if (!l2_entry->IsTable()) { - return false; + const bool is_block = level == EntryLevel_L3 ? pte->IsPage() : pte->IsBlock(); + if (is_block) { + *out = this->GetBlock(pte, level) + this->GetOffset(address, level); + } else { + *out = Null; } - /* Try to get from l3 table. */ - const L3PageTableEntry *l3_entry = this->GetL3Entry(l2_entry, address); - if (l3_entry->IsBlock()) { - *out = l3_entry->GetBlock() + GetL3Offset(address); - return true; - } - - return false; + return is_block; } void KPageTableImpl::Dump(uintptr_t start, size_t size) const { From 9610f42dc0f7d16fc2c567bc230a0e9834cef651 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 12:58:15 -0700 Subject: [PATCH 159/238] kern: continue page table refactor, implement separate/unmap --- .../arch/arm64/kern_k_page_table.hpp | 7 +- .../arch/arm64/kern_k_page_table_entry.hpp | 69 +++- .../arch/arm64/kern_k_page_table_impl.hpp | 9 +- libraries/libmesosphere/libmesosphere.mk | 2 +- .../source/arch/arm64/kern_k_page_table.cpp | 359 +++++++----------- .../arch/arm64/kern_k_page_table_impl.cpp | 138 +++---- .../libmesosphere/source/kern_k_thread.cpp | 3 + 7 files changed, 265 insertions(+), 322 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 2ccd4b72a..8446b6f1c 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -233,8 +233,11 @@ namespace ams::kern::arch::arm64 { bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list); - ALWAYS_INLINE Result SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); - Result SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); + void MergePages(TraversalContext *context, PageLinkedList *page_list); + void MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list); + + Result SeparatePagesImpl(TraversalEntry *entry, TraversalContext *context, KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); + Result SeparatePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool reuse_ll); Result ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp index 8941928ed..a87c7b5c5 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp @@ -20,18 +20,22 @@ namespace ams::kern::arch::arm64 { + constexpr size_t BlocksPerContiguousBlock = 0x10; + constexpr size_t BlocksPerTable = PageSize / sizeof(u64); + constexpr size_t L1BlockSize = 1_GB; - constexpr size_t L1ContiguousBlockSize = 0x10 * L1BlockSize; + constexpr size_t L1ContiguousBlockSize = BlocksPerContiguousBlock * L1BlockSize; constexpr size_t L2BlockSize = 2_MB; - constexpr size_t L2ContiguousBlockSize = 0x10 * L2BlockSize; + constexpr size_t L2ContiguousBlockSize = BlocksPerContiguousBlock * L2BlockSize; constexpr size_t L3BlockSize = PageSize; - constexpr size_t L3ContiguousBlockSize = 0x10 * L3BlockSize; + constexpr size_t L3ContiguousBlockSize = BlocksPerContiguousBlock * L3BlockSize; class PageTableEntry { public: struct InvalidTag{}; struct TableTag{}; struct BlockTag{}; + struct SeparateContiguousTag{}; enum Permission : u64 { Permission_KernelRWX = ((0ul << 53) | (1ul << 54) | (0ul << 6)), @@ -122,6 +126,25 @@ namespace ams::kern::arch::arm64 { { /* ... */ } + + /* Construct a table. */ + constexpr explicit ALWAYS_INLINE PageTableEntry(TableTag, KPhysicalAddress phys_addr, bool is_kernel, bool pxn, size_t num_blocks) + : PageTableEntry(((is_kernel ? 0x3ul : 0) << 60) | (static_cast(pxn) << 59) | GetInteger(phys_addr) | (num_blocks << 2) | 0x3) + { + /* ... */ + } + + /* Construct a block. */ + constexpr explicit ALWAYS_INLINE PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig, bool page) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | (page ? ExtensionFlag_TestTableMask : ExtensionFlag_Valid)) + { + /* ... */ + } + constexpr explicit ALWAYS_INLINE PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, SeparateContiguousTag) + : PageTableEntry(attr, GetInteger(phys_addr)) + { + /* ... */ + } protected: constexpr ALWAYS_INLINE u64 GetBits(size_t offset, size_t count) const { return (m_attributes >> offset) & ((1ul << count) - 1); @@ -165,7 +188,7 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE Shareable GetShareable() const { return static_cast(this->SelectBits(8, 2)); } constexpr ALWAYS_INLINE PageAttribute GetPageAttribute() const { return static_cast(this->SelectBits(2, 3)); } constexpr ALWAYS_INLINE int GetAccessFlagInteger() const { return static_cast(this->GetBits(10, 1)); } - constexpr ALWAYS_INLINE int GetShareableInteger() const { return static_cast(this->GetBits(8, 2)); } + constexpr ALWAYS_INLINE int GetShareableInteger() const { return static_cast(this->GetBits(8, 2)); } constexpr ALWAYS_INLINE int GetPageAttributeInteger() const { return static_cast(this->GetBits(2, 3)); } constexpr ALWAYS_INLINE bool IsReadOnly() const { return this->GetBits(7, 1) != 0; } constexpr ALWAYS_INLINE bool IsUserAccessible() const { return this->GetBits(6, 1) != 0; } @@ -194,6 +217,12 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE decltype(auto) SetPageAttribute(PageAttribute a) { this->SetBitsDirect(2, 3, a); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetMapped(bool m) { static_assert(static_cast(MappingFlag_Mapped == (1 << 0))); this->SetBit(0, m); return *this; } + constexpr ALWAYS_INLINE size_t GetTableNumEntries() const { return this->GetBits(2, 10); } + constexpr ALWAYS_INLINE decltype(auto) SetTableNumEntries(size_t num) { this->SetBits(2, 10, num); } + + constexpr ALWAYS_INLINE decltype(auto) AddTableEntries(size_t num) { return this->SetTableNumEntries(this->GetTableNumEntries() + num); } + constexpr ALWAYS_INLINE decltype(auto) RemoveTableEntries(size_t num) { return this->SetTableNumEntries(this->GetTableNumEntries() - num); } + constexpr ALWAYS_INLINE u64 GetEntryTemplateForMerge() const { constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); return m_attributes & BaseMask; @@ -204,6 +233,38 @@ namespace ams::kern::arch::arm64 { return (m_attributes & BaseMaskForMerge) == attr; } + static constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateContiguousMask(size_t idx) { + constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + if (idx == 0) { + return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody; + } else if (idx < BlocksPerContiguousBlock - 1) { + return BaseMask; + } else { + return BaseMask | ExtensionFlag_DisableMergeTail; + } + } + + constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateContiguous(size_t idx) const { + return m_attributes & GetEntryTemplateForSeparateContiguousMask(idx); + } + + static constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparateMask(size_t idx) { + constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + if (idx == 0) { + return BaseMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody; + } else if (idx < BlocksPerContiguousBlock) { + return BaseMask | ExtensionFlag_DisableMergeHeadAndBody; + } else if (idx < BlocksPerTable - 1) { + return BaseMask; + } else { + return BaseMask | ExtensionFlag_DisableMergeTail; + } + } + + constexpr ALWAYS_INLINE u64 GetEntryTemplateForSeparate(size_t idx) const { + return m_attributes & GetEntryTemplateForSeparateMask(idx); + } + constexpr ALWAYS_INLINE u64 GetRawAttributesUnsafe() const { return m_attributes; } diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index 8616ac0dd..68b324f6e 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -45,7 +45,7 @@ namespace ams::kern::arch::arm64 { }; struct TraversalContext { - const PageTableEntry *level_entries[EntryLevel_Count]; + PageTableEntry *level_entries[EntryLevel_Count]; EntryLevel level; bool is_contiguous; }; @@ -125,6 +125,10 @@ namespace ams::kern::arch::arm64 { ALWAYS_INLINE L3PageTableEntry *GetL3Entry(const L2PageTableEntry *entry, KProcessAddress address) const { return GetL3EntryFromTable(KMemoryLayout::GetLinearVirtualAddress(entry->GetTable()), address); } + + static constexpr size_t GetBlockSize(EntryLevel level, bool contiguous = false) { + return 1 << (PageBits + LevelBits * level + 4 * contiguous); + } public: constexpr explicit KPageTableImpl(util::ConstantInitializeTag) : m_table(), m_is_kernel(), m_num_entries() { /* ... */ } @@ -141,6 +145,9 @@ namespace ams::kern::arch::arm64 { bool ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const; bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const; + + static bool MergePages(KVirtualAddress *out, TraversalContext *context); + void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const; }; } diff --git a/libraries/libmesosphere/libmesosphere.mk b/libraries/libmesosphere/libmesosphere.mk index 32db70664..79c2c13ed 100644 --- a/libraries/libmesosphere/libmesosphere.mk +++ b/libraries/libmesosphere/libmesosphere.mk @@ -20,7 +20,7 @@ endif DEFINES := $(ATMOSPHERE_DEFINES) -DATMOSPHERE_IS_MESOSPHERE SETTINGS := $(ATMOSPHERE_SETTINGS) $(ATMOSPHERE_OPTIMIZATION_FLAG) -mgeneral-regs-only -ffixed-x18 -Wextra -Werror -fno-non-call-exceptions CFLAGS := $(ATMOSPHERE_CFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) -CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit -flto +CXXFLAGS := $(CFLAGS) $(ATMOSPHERE_CXXFLAGS) -fno-use-cxa-atexit ASFLAGS := $(ATMOSPHERE_ASFLAGS) $(SETTINGS) $(DEFINES) $(INCLUDE) SOURCES += $(foreach v,$(call ALL_SOURCE_DIRS,../libvapours/source),$(if $(findstring ../libvapours/source/sdmmc,$v),,$v)) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index c1b0c76b4..381f6c880 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -280,18 +280,7 @@ namespace ams::kern::arch::arm64 { if (operation == OperationType_Unmap) { R_RETURN(this->Unmap(virt_addr, num_pages, page_list, false, reuse_ll)); } else if (operation == OperationType_Separate) { - const size_t size = num_pages * PageSize; - R_TRY(this->SeparatePages(virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - - if (num_pages > 1) { - const auto end_page = virt_addr + size; - const auto last_page = end_page - PageSize; - - R_TRY(this->SeparatePages(last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); - } - - R_SUCCEED(); + R_RETURN(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); } else { auto entry_template = this->GetEntryTemplate(properties); @@ -519,16 +508,7 @@ namespace ams::kern::arch::arm64 { /* If we're not forcing an unmap, separate pages immediately. */ if (!force) { - const size_t size = num_pages * PageSize; - R_TRY(this->SeparatePages(virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - - if (num_pages > 1) { - const auto end_page = virt_addr + size; - const auto last_page = end_page - PageSize; - - R_TRY(this->SeparatePages(last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); - } + R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); } /* Cache initial addresses for use on cleanup. */ @@ -558,10 +538,7 @@ namespace ams::kern::arch::arm64 { /* Handle the case where the block is bigger than it should be. */ if (next_entry.block_size > remaining_pages * PageSize) { MESOSPHERE_ABORT_UNLESS(force); - MESOSPHERE_R_ABORT_UNLESS(this->SeparatePages(virt_addr, remaining_pages * PageSize, page_list, reuse_ll)); - const bool new_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), virt_addr); - MESOSPHERE_ASSERT(new_valid); - MESOSPHERE_UNUSED(new_valid); + MESOSPHERE_R_ABORT_UNLESS(this->SeparatePagesImpl(std::addressof(next_entry), std::addressof(context), virt_addr, remaining_pages * PageSize, page_list, reuse_ll)); } /* Check that our state is coherent. */ @@ -569,87 +546,38 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(util::IsAligned(GetInteger(next_entry.phys_addr), next_entry.block_size)); /* Unmap the block. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); - switch (next_entry.block_size) { - case L1BlockSize: - { - /* Clear the entry. */ - *l1_entry = InvalidL1PageTableEntry; - } + bool freeing_table = false; + while (true) { + /* Clear the entries. */ + const size_t num_to_clear = (!freeing_table && context.is_contiguous) ? BlocksPerContiguousBlock : 1; + auto *pte = reinterpret_cast(context.is_contiguous ? util::AlignDown(reinterpret_cast(context.level_entries[context.level]), BlocksPerContiguousBlock * sizeof(PageTableEntry)) : reinterpret_cast(context.level_entries[context.level])); + for (size_t i = 0; i < num_to_clear; ++i) { + pte[i] = InvalidPageTableEntry; + } + + /* Remove the entries from the previous table. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->RemoveTableEntries(num_to_clear); + } + + /* If we cleared a table, we need to note that we updated and free the table. */ + if (freeing_table) { + this->NoteUpdated(); + this->FreePageTable(page_list, KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize))); + } + + /* Advance; we're no longer contiguous. */ + context.is_contiguous = false; + context.level_entries[context.level] = pte + num_to_clear - 1; + + /* We may have removed the last entries in a table, in which case we can free an unmap the tables. */ + if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { break; - case L2ContiguousBlockSize: - case L2BlockSize: - { - /* Get the number of L2 blocks. */ - const size_t num_l2_blocks = next_entry.block_size / L2BlockSize; + } - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - - /* Clear the entry. */ - for (size_t i = 0; i < num_l2_blocks; i++) { - *impl.GetL2EntryFromTable(l2_virt, virt_addr + L2BlockSize * i) = InvalidL2PageTableEntry; - } - PteDataMemoryBarrier(); - - /* Close references to the L2 table. */ - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - if (this->GetPageTableManager().Close(l2_virt, num_l2_blocks)) { - *l1_entry = InvalidL1PageTableEntry; - this->NoteUpdated(); - this->FreePageTable(page_list, l2_virt); - pages_to_close.CloseAndReset(); - } - } - } - break; - case L3ContiguousBlockSize: - case L3BlockSize: - { - /* Get the number of L3 blocks. */ - const size_t num_l3_blocks = next_entry.block_size / L3BlockSize; - - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - L2PageTableEntry *l2_entry = impl.GetL2EntryFromTable(l2_virt, virt_addr); - - /* Get the L3 entry. */ - KPhysicalAddress l3_phys = Null; - MESOSPHERE_ABORT_UNLESS(l2_entry->GetTable(l3_phys)); - const KVirtualAddress l3_virt = GetPageTableVirtualAddress(l3_phys); - - /* Clear the entry. */ - for (size_t i = 0; i < num_l3_blocks; i++) { - *impl.GetL3EntryFromTable(l3_virt, virt_addr + L3BlockSize * i) = InvalidL3PageTableEntry; - } - PteDataMemoryBarrier(); - - /* Close references to the L3 table. */ - if (this->GetPageTableManager().IsInPageTableHeap(l3_virt)) { - if (this->GetPageTableManager().Close(l3_virt, num_l3_blocks)) { - *l2_entry = InvalidL2PageTableEntry; - this->NoteUpdated(); - - /* Close reference to the L2 table. */ - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - if (this->GetPageTableManager().Close(l2_virt, 1)) { - *l1_entry = InvalidL1PageTableEntry; - this->NoteUpdated(); - this->FreePageTable(page_list, l2_virt); - } - } - - this->FreePageTable(page_list, l3_virt); - pages_to_close.CloseAndReset(); - } - } - } - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + /* Advance; we will not be working with blocks any more. */ + context.level = static_cast(util::ToUnderlying(context.level) + 1); + freeing_table = true; } /* Close the blocks. */ @@ -663,8 +591,19 @@ namespace ams::kern::arch::arm64 { } /* Advance. */ - virt_addr += next_entry.block_size; - remaining_pages -= next_entry.block_size / PageSize; + size_t freed_size = next_entry.block_size; + if (freeing_table) { + /* We advanced more than by the block, so we need to calculate the actual advanced size. */ + const KProcessAddress new_virt_addr = util::AlignUp(GetInteger(virt_addr), impl.GetBlockSize(context.level, context.is_contiguous)); + MESOSPHERE_ABORT_UNLESS(new_virt_addr >= virt_addr + next_entry.block_size); + + freed_size = std::min(new_virt_addr - virt_addr, remaining_pages * PageSize); + } + + /* We can just advance by the block size. */ + virt_addr += freed_size; + remaining_pages -= freed_size / PageSize; + next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); } @@ -1032,141 +971,116 @@ namespace ams::kern::arch::arm64 { return merged; } - Result KPageTable::SeparatePagesImpl(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { + void KPageTable::MergePages(TraversalContext *context, PageLinkedList *page_list) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); auto &impl = this->GetImpl(); - /* First, try to separate an L1 block into contiguous L2 blocks. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); - if (l1_entry->IsBlock()) { - /* If our block size is too big, don't bother. */ - R_SUCCEED_IF(block_size >= L1BlockSize); - - /* Get the addresses we're working with. */ - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L1BlockSize); - const KPhysicalAddress block_phys_addr = l1_entry->GetBlock(); - - /* Allocate a new page for the L2 table. */ - const KVirtualAddress l2_table = this->AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l2_table != Null, svc::ResultOutOfResource()); - const KPhysicalAddress l2_phys = GetPageTablePhysicalAddress(l2_table); - - /* Set the entries in the L2 table. */ - for (size_t i = 0; i < L1BlockSize / L2BlockSize; i++) { - const u64 entry_template = l1_entry->GetEntryTemplateForL2Block(i); - *(impl.GetL2EntryFromTable(l2_table, block_virt_addr + L2BlockSize * i)) = L2PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L2BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, true); + /* Iteratively merge, until we can't. */ + while (true) { + /* Try to merge. */ + KVirtualAddress freed_table = Null; + if (!impl.MergePages(std::addressof(freed_table), context)) { + break; } - /* Open references to the L2 table. */ - this->GetPageTableManager().Open(l2_table, L1BlockSize / L2BlockSize); + /* Note that we updated. */ + this->NoteUpdated(); - /* Replace the L1 entry with one to the new table. */ - PteDataMemoryBarrier(); - *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, l2_phys, this->IsKernel(), true); + /* Free the page. */ + ClearPageTable(freed_table); + this->FreePageTable(page_list, freed_table); + } + } + + void KPageTable::MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list) { + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + + auto &impl = this->GetImpl(); + + /* Begin traversal. */ + TraversalContext context; + TraversalEntry entry; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(context), virt_addr)); + + /* Merge start of the range. */ + this->MergePages(std::addressof(context), page_list); + + /* If we have more than one page, do the same for the end of the range. */ + if (num_pages > 1) { + /* Begin traversal for end of range. */ + const size_t size = num_pages * PageSize; + const auto end_page = virt_addr + size; + const auto last_page = end_page - PageSize; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(context), last_page)); + + /* Merge. */ + this->MergePages(std::addressof(context), page_list); + } + } + + Result KPageTable::SeparatePagesImpl(TraversalEntry *entry, TraversalContext *context, KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + + auto &impl = this->GetImpl(); + + /* If at any point we fail, we want to merge. */ + ON_RESULT_FAILURE { this->MergePages(context, page_list); }; + + /* Iterate, separating until our block size is small enough. */ + while (entry->block_size > block_size) { + /* If necessary, allocate a table. */ + KVirtualAddress table = Null; + if (!context->is_contiguous) { + table = this->AllocatePageTable(page_list, reuse_ll); + R_UNLESS(table != Null, svc::ResultOutOfResource()); + } + + /* Separate. */ + impl.SeparatePages(entry, context, virt_addr, nullptr); this->NoteUpdated(); } - /* If we don't have an l1 table, we're done. */ - MESOSPHERE_ABORT_UNLESS(l1_entry->IsTable() || l1_entry->IsEmpty()); - R_SUCCEED_IF(!l1_entry->IsTable()); - - /* We want to separate L2 contiguous blocks into L2 blocks, so check that our size permits that. */ - R_SUCCEED_IF(block_size >= L2ContiguousBlockSize); - - L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { - /* If we're contiguous, try to separate. */ - if (l2_entry->IsContiguous()) { - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L2ContiguousBlockSize); - const KPhysicalAddress block_phys_addr = util::AlignDown(GetInteger(l2_entry->GetBlock()), L2ContiguousBlockSize); - - /* Mark the entries as non-contiguous. */ - for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { - L2PageTableEntry *target = impl.GetL2Entry(l1_entry, block_virt_addr + L2BlockSize * i); - const u64 entry_template = target->GetEntryTemplateForL2Block(i); - *target = L2PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L2BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, false); - } - this->NoteUpdated(); - } - - /* We want to separate L2 blocks into L3 contiguous blocks, so check that our size permits that. */ - R_SUCCEED_IF(block_size >= L2BlockSize); - - /* Get the addresses we're working with. */ - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L2BlockSize); - const KPhysicalAddress block_phys_addr = l2_entry->GetBlock(); - - /* Allocate a new page for the L3 table. */ - const KVirtualAddress l3_table = this->AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l3_table != Null, svc::ResultOutOfResource()); - const KPhysicalAddress l3_phys = GetPageTablePhysicalAddress(l3_table); - - /* Set the entries in the L3 table. */ - for (size_t i = 0; i < L2BlockSize / L3BlockSize; i++) { - const u64 entry_template = l2_entry->GetEntryTemplateForL3Block(i); - *(impl.GetL3EntryFromTable(l3_table, block_virt_addr + L3BlockSize * i)) = L3PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L3BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, true); - } - - /* Open references to the L3 table. */ - this->GetPageTableManager().Open(l3_table, L2BlockSize / L3BlockSize); - - /* Replace the L2 entry with one to the new table. */ - PteDataMemoryBarrier(); - *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, l3_phys, this->IsKernel(), true); - this->NoteUpdated(); - } - - /* If we don't have an L3 table, we're done. */ - MESOSPHERE_ABORT_UNLESS(l2_entry->IsTable() || l2_entry->IsEmpty()); - R_SUCCEED_IF(!l2_entry->IsTable()); - - /* We want to separate L3 contiguous blocks into L2 blocks, so check that our size permits that. */ - R_SUCCEED_IF(block_size >= L3ContiguousBlockSize); - - /* If we're contiguous, try to separate. */ - L3PageTableEntry *l3_entry = impl.GetL3Entry(l2_entry, virt_addr); - if (l3_entry->IsBlock() && l3_entry->IsContiguous()) { - const KProcessAddress block_virt_addr = util::AlignDown(GetInteger(virt_addr), L3ContiguousBlockSize); - const KPhysicalAddress block_phys_addr = util::AlignDown(GetInteger(l3_entry->GetBlock()), L3ContiguousBlockSize); - - /* Mark the entries as non-contiguous. */ - for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { - L3PageTableEntry *target = impl.GetL3Entry(l2_entry, block_virt_addr + L3BlockSize * i); - const u64 entry_template = target->GetEntryTemplateForL3Block(i); - *target = L3PageTableEntry(PageTableEntry::BlockTag{}, block_phys_addr + L3BlockSize * i, PageTableEntry(entry_template), PageTableEntry::SoftwareReservedBit_None, false); - } - this->NoteUpdated(); - } - - /* We're done! */ R_SUCCEED(); } - Result KPageTable::SeparatePages(KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll) { + Result KPageTable::SeparatePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - /* If we fail while separating, re-merge. */ - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; + auto &impl = this->GetImpl(); - /* Try to separate pages. */ - R_RETURN(this->SeparatePagesImpl(virt_addr, block_size, page_list, reuse_ll)); + /* Begin traversal. */ + TraversalContext start_context; + TraversalEntry entry; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(start_context), virt_addr)); + + /* Separate pages at the start of the range. */ + const size_t size = num_pages * PageSize; + R_TRY(this->SeparatePagesImpl(std::addressof(entry), std::addressof(start_context), virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); + + /* If necessary, separate pages at the end of the range. */ + if (num_pages > 1) { + const auto end_page = virt_addr + size; + const auto last_page = end_page - PageSize; + + /* Begin traversal. */ + TraversalContext end_context; + MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(entry), std::addressof(end_context), last_page)); + + + ON_RESULT_FAILURE { this->MergePages(std::addressof(start_context), page_list); }; + + R_TRY(this->SeparatePagesImpl(std::addressof(entry), std::addressof(end_context), last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); + } + + R_SUCCEED(); } Result KPageTable::ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); /* Separate pages before we change permissions. */ - const size_t size = num_pages * PageSize; - R_TRY(this->SeparatePages(virt_addr, std::min(util::GetAlignment(GetInteger(virt_addr)), size), page_list, reuse_ll)); - if (num_pages > 1) { - const auto end_page = virt_addr + size; - const auto last_page = end_page - PageSize; - - ON_RESULT_FAILURE { this->MergePages(virt_addr, page_list); }; - - R_TRY(this->SeparatePages(last_page, std::min(util::GetAlignment(GetInteger(end_page)), size), page_list, reuse_ll)); - } + R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); /* ===================================================== */ @@ -1376,10 +1290,7 @@ namespace ams::kern::arch::arm64 { } /* We've succeeded, now perform what coalescing we can. */ - this->MergePages(virt_addr, page_list); - if (num_pages > 1) { - this->MergePages(virt_addr + (num_pages - 1) * PageSize, page_list); - } + this->MergePages(virt_addr, num_pages, page_list); R_SUCCEED(); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 5bc775f66..5f03bb83c 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -33,94 +33,6 @@ namespace ams::kern::arch::arm64 { return m_table; } - // bool KPageTableImpl::ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const { - // /* Set the L3 entry. */ - // out_context->l3_entry = l3_entry; - // - // if (l3_entry->IsBlock()) { - // /* Set the output entry. */ - // out_entry->phys_addr = l3_entry->GetBlock() + (virt_addr & (L3BlockSize - 1)); - // if (l3_entry->IsContiguous()) { - // out_entry->block_size = L3ContiguousBlockSize; - // } else { - // out_entry->block_size = L3BlockSize; - // } - // out_entry->sw_reserved_bits = l3_entry->GetSoftwareReservedBits(); - // out_entry->attr = 0; - // - // return true; - // } else { - // out_entry->phys_addr = Null; - // out_entry->block_size = L3BlockSize; - // out_entry->sw_reserved_bits = 0; - // out_entry->attr = 0; - // return false; - // } - // } - // - // bool KPageTableImpl::ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const { - // /* Set the L2 entry. */ - // out_context->l2_entry = l2_entry; - // - // if (l2_entry->IsBlock()) { - // /* Set the output entry. */ - // out_entry->phys_addr = l2_entry->GetBlock() + (virt_addr & (L2BlockSize - 1)); - // if (l2_entry->IsContiguous()) { - // out_entry->block_size = L2ContiguousBlockSize; - // } else { - // out_entry->block_size = L2BlockSize; - // } - // out_entry->sw_reserved_bits = l2_entry->GetSoftwareReservedBits(); - // out_entry->attr = 0; - // - // /* Set the output context. */ - // out_context->l3_entry = nullptr; - // return true; - // } else if (l2_entry->IsTable()) { - // return this->ExtractL3Entry(out_entry, out_context, this->GetL3EntryFromTable(GetPageTableVirtualAddress(l2_entry->GetTable()), virt_addr), virt_addr); - // } else { - // out_entry->phys_addr = Null; - // out_entry->block_size = L2BlockSize; - // out_entry->sw_reserved_bits = 0; - // out_entry->attr = 0; - // - // out_context->l3_entry = nullptr; - // return false; - // } - // } - // - // bool KPageTableImpl::ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const { - // /* Set the L1 entry. */ - // out_context->level_entries[EntryLevel_L1] = l1_entry; - // - // if (l1_entry->IsBlock()) { - // /* Set the output entry. */ - // out_entry->phys_addr = l1_entry->GetBlock() + (virt_addr & (L1BlockSize - 1)); - // if (l1_entry->IsContiguous()) { - // out_entry->block_size = L1ContiguousBlockSize; - // } else { - // out_entry->block_size = L1BlockSize; - // } - // out_entry->sw_reserved_bits = l1_entry->GetSoftwareReservedBits(); - // - // /* Set the output context. */ - // out_context->l2_entry = nullptr; - // out_context->l3_entry = nullptr; - // return true; - // } else if (l1_entry->IsTable()) { - // return this->ExtractL2Entry(out_entry, out_context, this->GetL2EntryFromTable(GetPageTableVirtualAddress(l1_entry->GetTable()), virt_addr), virt_addr); - // } else { - // out_entry->phys_addr = Null; - // out_entry->block_size = L1BlockSize; - // out_entry->sw_reserved_bits = 0; - // out_entry->attr = 0; - // - // out_context->l2_entry = nullptr; - // out_context->l3_entry = nullptr; - // return false; - // } - // } - bool KPageTableImpl::BeginTraversal(TraversalEntry *out_entry, TraversalContext *out_context, KProcessAddress address) const { /* Setup invalid defaults. */ *out_entry = {}; @@ -176,9 +88,8 @@ namespace ams::kern::arch::arm64 { bool KPageTableImpl::ContinueTraversal(TraversalEntry *out_entry, TraversalContext *context) const { /* Advance entry. */ - auto *cur_pte = context->level_entries[context->level]; - auto *next_pte = reinterpret_cast(context->is_contiguous ? util::AlignDown(reinterpret_cast(cur_pte), 0x10 * sizeof(PageTableEntry)) + 0x10 * sizeof(PageTableEntry) : reinterpret_cast(cur_pte) + sizeof(PageTableEntry)); + auto *next_pte = reinterpret_cast(context->is_contiguous ? util::AlignDown(reinterpret_cast(cur_pte), BlocksPerContiguousBlock * sizeof(PageTableEntry)) + BlocksPerContiguousBlock * sizeof(PageTableEntry) : reinterpret_cast(cur_pte) + sizeof(PageTableEntry)); /* Set the pte. */ context->level_entries[context->level] = next_pte; @@ -255,6 +166,53 @@ namespace ams::kern::arch::arm64 { return is_block; } + bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context) { + /* TODO */ + MESOSPHERE_UNUSED(out, context); + MESOSPHERE_PANIC("page tables"); + } + + void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const { + /* We want to downgrade the pages by one step. */ + if (context->is_contiguous) { + /* We want to downgrade a contiguous mapping to a non-contiguous mapping. */ + pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerContiguousBlock * sizeof(PageTableEntry))); + + auto * const first = pte; + const KPhysicalAddress block = this->GetBlock(first, context->level); + for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * context->level)), PageTableEntry(first->GetEntryTemplateForSeparateContiguous(i)), PageTableEntry::SeparateContiguousTag{}); + } + + context->is_contiguous = false; + + context->level_entries[context->level] = pte + (this->GetLevelIndex(address, context->level) & (BlocksPerContiguousBlock - 1)); + } else { + /* We want to downgrade a block into a table. */ + auto * const first = context->level_entries[context->level]; + const KPhysicalAddress block = this->GetBlock(first, context->level); + for (size_t i = 0; i < BlocksPerTable; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * (context->level - 1))), PageTableEntry(first->GetEntryTemplateForSeparate(i)), PageTableEntry::SoftwareReservedBit_None, true, context->level == EntryLevel_L3); + } + + context->is_contiguous = true; + context->level = static_cast(util::ToUnderlying(context->level) - 1); + + /* Wait for pending stores to complete. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); + + /* Update the block entry to be a table entry. */ + *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(KVirtualAddress(first)), m_is_kernel, true, BlocksPerTable); + + context->level_entries[context->level] = pte + this->GetLevelIndex(address, context->level); + } + + entry->sw_reserved_bits = 0; + entry->attr = 0; + entry->phys_addr = this->GetBlock(context->level_entries[context->level], context->level) + this->GetOffset(address, context->level); + entry->block_size = static_cast(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous); + } + void KPageTableImpl::Dump(uintptr_t start, size_t size) const { /* If zero size, there's nothing to dump. */ if (size == 0) { diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 4ec7aa1dd..74b39acd3 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -1438,7 +1438,10 @@ namespace ams::kern { this->SetState(ThreadState_Waiting); /* Set our wait queue. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdangling-pointer" m_wait_queue = queue; + #pragma GCC diagnostic pop } void KThread::NotifyAvailable(KSynchronizationObject *signaled_object, Result wait_result) { From cb970049db49989b6eaf395cbcf719c1e172b229 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 13:25:37 -0700 Subject: [PATCH 160/238] kern: implement KPageTableImpl merge --- .../arch/arm64/kern_k_page_table_entry.hpp | 2 +- .../arch/arm64/kern_k_page_table_impl.cpp | 75 ++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp index a87c7b5c5..d3ac79089 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp @@ -224,7 +224,7 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE decltype(auto) RemoveTableEntries(size_t num) { return this->SetTableNumEntries(this->GetTableNumEntries() - num); } constexpr ALWAYS_INLINE u64 GetEntryTemplateForMerge() const { - constexpr u64 BaseMask = (0xFFF0000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); + constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); return m_attributes & BaseMask; } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 5f03bb83c..249024a29 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -167,9 +167,78 @@ namespace ams::kern::arch::arm64 { } bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context) { - /* TODO */ - MESOSPHERE_UNUSED(out, context); - MESOSPHERE_PANIC("page tables"); + /* We want to upgrade the pages by one step. */ + if (context->is_contiguous) { + /* We can't merge an L1 table. */ + if (context->level == EntryLevel_L1) { + return false; + } + + /* We want to upgrade a contiguous mapping in a table to a block. */ + PageTableEntry *pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerTable * sizeof(PageTableEntry))); + const KPhysicalAddress phys_addr = GetBlock(pte, context->level); + + /* First, check that all entries are valid for us to merge. */ + const u64 entry_template = pte->GetEntryTemplateForMerge(); + for (size_t i = 0; i < BlocksPerTable; ++i) { + if (!pte[i].IsForMerge(entry_template | GetInteger(phys_addr + (i << (PageBits + LevelBits * context->level))) | PageTableEntry::ContigType_Contiguous | pte->GetTestTableMask())) { + return false; + } + if (i > 0 && pte[i].IsHeadOrHeadAndBodyMergeDisabled()) { + return false; + } + if (i < BlocksPerTable - 1 && pte[i].IsTailMergeDisabled()) { + return false; + } + } + + /* The entries are valid for us to merge, so merge them. */ + const auto *head_pte = pte; + const auto *tail_pte = pte + BlocksPerTable - 1; + const auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_pte->IsHeadMergeDisabled(), head_pte->IsHeadAndBodyMergeDisabled(), tail_pte->IsTailMergeDisabled()); + + *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false, false); + + /* Update our context. */ + context->is_contiguous = false; + context->level = static_cast(util::ToUnderlying(context->level) + 1); + + /* Set the output to the table we just freed. */ + *out = KVirtualAddress(pte); + } else { + /* We want to upgrade a non-contiguous mapping to a contiguous mapping. */ + PageTableEntry *pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerContiguousBlock * sizeof(PageTableEntry))); + const KPhysicalAddress phys_addr = GetBlock(pte, context->level); + + /* First, check that all entries are valid for us to merge. */ + const u64 entry_template = pte->GetEntryTemplateForMerge(); + for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { + if (!pte[i].IsForMerge(entry_template | GetInteger(phys_addr + (i << (PageBits + LevelBits * context->level))) | pte->GetTestTableMask())) { + return false; + } + if (i > 0 && pte[i].IsHeadOrHeadAndBodyMergeDisabled()) { + return false; + } + if (i < BlocksPerContiguousBlock - 1 && pte[i].IsTailMergeDisabled()) { + return false; + } + } + + /* The entries are valid for us to merge, so merge them. */ + const auto *head_pte = pte; + const auto *tail_pte = pte + BlocksPerContiguousBlock - 1; + const auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_pte->IsHeadMergeDisabled(), head_pte->IsHeadAndBodyMergeDisabled(), tail_pte->IsTailMergeDisabled()); + + for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + (i << (PageBits + LevelBits * context->level)), PageTableEntry(entry_template), sw_reserved_bits, true, context->level == EntryLevel_L3); + } + + /* Update our context. */ + context->level_entries[context->level] = pte; + context->is_contiguous = true; + } + + return true; } void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const { From 62abb3112212114b18894d1de8da8b994f6872e9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 13:39:08 -0700 Subject: [PATCH 161/238] kern: use new merge pages api --- .../arch/arm64/kern_k_page_table.hpp | 4 +- .../source/arch/arm64/kern_k_page_table.cpp | 214 ++---------------- 2 files changed, 15 insertions(+), 203 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 8446b6f1c..e4fca0dd5 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -231,9 +231,7 @@ namespace ams::kern::arch::arm64 { Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll); - bool MergePages(KProcessAddress virt_addr, PageLinkedList *page_list); - - void MergePages(TraversalContext *context, PageLinkedList *page_list); + bool MergePages(TraversalContext *context, PageLinkedList *page_list); void MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list); Result SeparatePagesImpl(TraversalEntry *entry, TraversalContext *context, KProcessAddress virt_addr, size_t block_size, PageLinkedList *page_list, bool reuse_ll); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 381f6c880..e62114d60 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -678,13 +678,7 @@ namespace ams::kern::arch::arm64 { } /* Perform what coalescing we can. */ - this->MergePages(orig_virt_addr, page_list); - if (num_pages > 1) { - this->MergePages(orig_virt_addr + (num_pages - 1) * PageSize, page_list); - } - - /* Wait for pending stores to complete. */ - cpu::DataSynchronizationBarrierInnerShareableStore(); + this->MergePages(orig_virt_addr, num_pages, page_list); /* Open references to the pages, if we should. */ if (IsHeapPhysicalAddress(orig_phys_addr)) { @@ -776,207 +770,20 @@ namespace ams::kern::arch::arm64 { MESOSPHERE_ASSERT(mapped_pages == num_pages); /* Perform what coalescing we can. */ - this->MergePages(orig_virt_addr, page_list); - if (num_pages > 1) { - this->MergePages(orig_virt_addr + (num_pages - 1) * PageSize, page_list); - } - - /* Wait for pending stores to complete. */ - cpu::DataSynchronizationBarrierInnerShareableStore(); + this->MergePages(orig_virt_addr, num_pages, page_list); /* We succeeded! We want to persist the reference to the pages. */ spg.CancelClose(); R_SUCCEED(); } - bool KPageTable::MergePages(KProcessAddress virt_addr, PageLinkedList *page_list) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - - auto &impl = this->GetImpl(); - bool merged = false; - - /* If there's no L1 table, don't bother. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); - if (!l1_entry->IsTable()) { - /* Ensure the table is not corrupted. */ - MESOSPHERE_ABORT_UNLESS(l1_entry->IsBlock() || l1_entry->IsEmpty()); - return merged; - } - - /* Examine and try to merge the L2 table. */ - L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsTable()) { - /* We have an L3 entry. */ - L3PageTableEntry *l3_entry = impl.GetL3Entry(l2_entry, virt_addr); - if (!l3_entry->IsBlock()) { - return merged; - } - - /* If it's not contiguous, try to make it so. */ - if (!l3_entry->IsContiguous()) { - virt_addr = util::AlignDown(GetInteger(virt_addr), L3ContiguousBlockSize); - const KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l3_entry->GetBlock()), L3ContiguousBlockSize); - const u64 entry_template = l3_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { - const L3PageTableEntry *check_entry = impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L3BlockSize * i) | PageTableEntry::Type_L3Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L3ContiguousBlockSize / L3BlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L3PageTableEntry *head_entry = impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * 0); - const L3PageTableEntry *tail_entry = impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * ((L3ContiguousBlockSize / L3BlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - for (size_t i = 0; i < L3ContiguousBlockSize / L3BlockSize; i++) { - *impl.GetL3Entry(l2_entry, virt_addr + L3BlockSize * i) = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + L3BlockSize * i, PageTableEntry(entry_template), sw_reserved_bits, true); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; - } - - /* We might be able to upgrade a contiguous set of L3 entries into an L2 block. */ - virt_addr = util::AlignDown(GetInteger(virt_addr), L2BlockSize); - KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l3_entry->GetBlock()), L2BlockSize); - const u64 entry_template = l3_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L2BlockSize / L3ContiguousBlockSize; i++) { - const L3PageTableEntry *check_entry = impl.GetL3Entry(l2_entry, virt_addr + L3ContiguousBlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L3ContiguousBlockSize * i) | PageTableEntry::ContigType_Contiguous | PageTableEntry::Type_L3Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L2BlockSize / L3ContiguousBlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L3PageTableEntry *head_entry = impl.GetL3Entry(l2_entry, virt_addr + L3ContiguousBlockSize * 0); - const L3PageTableEntry *tail_entry = impl.GetL3Entry(l2_entry, virt_addr + L3ContiguousBlockSize * ((L2BlockSize / L3ContiguousBlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - *l2_entry = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; - - /* Free the L3 table. */ - KVirtualAddress l3_table = util::AlignDown(reinterpret_cast(l3_entry), PageSize); - if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) { - this->GetPageTableManager().Close(l3_table, L2BlockSize / L3BlockSize); - ClearPageTable(l3_table); - this->FreePageTable(page_list, l3_table); - } - } - - /* If the l2 entry is not a block or we can't make it contiguous, we're done. */ - if (!l2_entry->IsBlock()) { - return merged; - } - - /* If it's not contiguous, try to make it so. */ - if (!l2_entry->IsContiguous()) { - virt_addr = util::AlignDown(GetInteger(virt_addr), L2ContiguousBlockSize); - KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l2_entry->GetBlock()), L2ContiguousBlockSize); - const u64 entry_template = l2_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { - const L2PageTableEntry *check_entry = impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L2BlockSize * i) | PageTableEntry::Type_L2Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L2ContiguousBlockSize / L2BlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L2PageTableEntry *head_entry = impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * 0); - const L2PageTableEntry *tail_entry = impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * ((L2ContiguousBlockSize / L2BlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - for (size_t i = 0; i < L2ContiguousBlockSize / L2BlockSize; i++) { - *impl.GetL2Entry(l1_entry, virt_addr + L2BlockSize * i) = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + L2BlockSize * i, PageTableEntry(entry_template), sw_reserved_bits, true); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; - } - - /* We might be able to upgrade a contiguous set of L2 entries into an L1 block. */ - virt_addr = util::AlignDown(GetInteger(virt_addr), L1BlockSize); - KPhysicalAddress phys_addr = util::AlignDown(GetInteger(l2_entry->GetBlock()), L1BlockSize); - const u64 entry_template = l2_entry->GetEntryTemplateForMerge(); - - /* Validate that we can merge. */ - for (size_t i = 0; i < L1BlockSize / L2ContiguousBlockSize; i++) { - const L2PageTableEntry *check_entry = impl.GetL2Entry(l1_entry, virt_addr + L2ContiguousBlockSize * i); - if (!check_entry->IsForMerge(entry_template | GetInteger(phys_addr + L2ContiguousBlockSize * i) | PageTableEntry::ContigType_Contiguous | PageTableEntry::Type_L2Block)) { - return merged; - } - if (i > 0 && (check_entry->IsHeadOrHeadAndBodyMergeDisabled())) { - return merged; - } - if ((i < (L1ContiguousBlockSize / L2ContiguousBlockSize) - 1) && check_entry->IsTailMergeDisabled()) { - return merged; - } - } - - /* Determine the new software reserved bits. */ - const L2PageTableEntry *head_entry = impl.GetL2Entry(l1_entry, virt_addr + L2ContiguousBlockSize * 0); - const L2PageTableEntry *tail_entry = impl.GetL2Entry(l1_entry, virt_addr + L2ContiguousBlockSize * ((L1BlockSize / L2ContiguousBlockSize) - 1)); - auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_entry->IsHeadMergeDisabled(), head_entry->IsHeadAndBodyMergeDisabled(), tail_entry->IsTailMergeDisabled()); - - /* Merge! */ - *l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - - /* Note that we updated. */ - this->NoteUpdated(); - merged = true; - - /* Free the L2 table. */ - KVirtualAddress l2_table = util::AlignDown(reinterpret_cast(l2_entry), PageSize); - if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) { - this->GetPageTableManager().Close(l2_table, L1BlockSize / L2BlockSize); - ClearPageTable(l2_table); - this->FreePageTable(page_list, l2_table); - } - - return merged; - } - - void KPageTable::MergePages(TraversalContext *context, PageLinkedList *page_list) { + bool KPageTable::MergePages(TraversalContext *context, PageLinkedList *page_list) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); auto &impl = this->GetImpl(); /* Iteratively merge, until we can't. */ + bool merged = false; while (true) { /* Try to merge. */ KVirtualAddress freed_table = Null; @@ -988,9 +795,16 @@ namespace ams::kern::arch::arm64 { this->NoteUpdated(); /* Free the page. */ - ClearPageTable(freed_table); - this->FreePageTable(page_list, freed_table); + if (freed_table != Null) { + ClearPageTable(freed_table); + this->FreePageTable(page_list, freed_table); + } + + /* We performed at least one merge. */ + merged = true; } + + return merged; } void KPageTable::MergePages(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list) { @@ -1231,7 +1045,7 @@ namespace ams::kern::arch::arm64 { if (util::IsAligned(GetInteger(cur_virt_addr) + next_entry.block_size, larger_align)) { const uintptr_t aligned_start = util::AlignDown(GetInteger(cur_virt_addr), larger_align); if (orig_virt_addr <= aligned_start && aligned_start + larger_align - 1 < GetInteger(orig_virt_addr) + (num_pages * PageSize) - 1) { - merge = this->MergePages(cur_virt_addr, page_list); + merge = this->MergePages(std::addressof(context), page_list); } else { merge = false; } From d2656e394809ed6913065c9574443ef05cb6ee69 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 14:00:15 -0700 Subject: [PATCH 162/238] kern: update KPageTable::Finalize for the refactor --- .../source/arch/arm64/kern_k_page_table.cpp | 127 +++++++++--------- 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index e62114d60..d34c98b69 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -174,79 +174,85 @@ namespace ams::kern::arch::arm64 { /* Traverse, freeing all pages. */ { - /* Get the address space size. */ - const size_t as_size = this->GetAddressSpaceSize(); - /* Begin the traversal. */ TraversalContext context; - TraversalEntry cur_entry = { .phys_addr = Null, .block_size = 0, .sw_reserved_bits = 0, .attr = 0 }; - bool cur_valid = false; - TraversalEntry next_entry; - bool next_valid; - size_t tot_size = 0; + TraversalEntry entry; - next_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), this->GetAddressSpaceStart()); + KPhysicalAddress cur_phys_addr = Null; + size_t cur_size = 0; + u8 has_attr = 0; - /* Iterate over entries. */ + bool cur_valid = impl.BeginTraversal(std::addressof(entry), std::addressof(context), this->GetAddressSpaceStart()); while (true) { - /* NOTE: Nintendo really does check next_entry.attr == (cur_entry.attr != 0)...but attr is always zero as of 18.0.0, and this is "probably" for the new console or debug-only anyway, */ - /* so we'll implement the weird logic verbatim even though it doesn't match the GetContiguousRange logic. */ - if ((!next_valid && !cur_valid) || (next_valid && cur_valid && next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size && next_entry.attr == (cur_entry.attr ? 1 : 0))) { - cur_entry.block_size += next_entry.block_size; - } else { - if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { - mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); + if (cur_valid) { + /* Free the actual pages, if there are any. */ + if (IsHeapPhysicalAddressForFinalize(entry.phys_addr)) { + if (cur_size > 0) { + /* NOTE: Nintendo really does check next_entry.attr == (cur_entry.attr != 0)...but attr is always zero as of 18.0.0, and this is "probably" for the new console or debug-only anyway, */ + /* so we'll implement the weird logic verbatim even though it doesn't match the GetContiguousRange logic. */ + if (entry.phys_addr == cur_phys_addr + cur_size && entry.attr == has_attr) { + /* Just extend the block, since we can. */ + cur_size += entry.block_size; + } else { + /* Close the block, and begin tracking anew. */ + mm.Close(cur_phys_addr, cur_size / PageSize); + + cur_phys_addr = entry.phys_addr; + cur_size = entry.block_size; + has_attr = entry.attr != 0; + } + } else { + cur_phys_addr = entry.phys_addr; + cur_size = entry.block_size; + has_attr = entry.attr != 0; + } } - /* Update tracking variables. */ - tot_size += cur_entry.block_size; - cur_entry = next_entry; - cur_valid = next_valid; - } + /* Clean up the page table entries. */ + bool freeing_table = false; + while (true) { + /* Clear the entries. */ + const size_t num_to_clear = (!freeing_table && context.is_contiguous) ? BlocksPerContiguousBlock : 1; + auto *pte = reinterpret_cast(context.is_contiguous ? util::AlignDown(reinterpret_cast(context.level_entries[context.level]), BlocksPerContiguousBlock * sizeof(PageTableEntry)) : reinterpret_cast(context.level_entries[context.level])); + for (size_t i = 0; i < num_to_clear; ++i) { + pte[i] = InvalidPageTableEntry; + } - if (cur_entry.block_size + tot_size >= as_size) { - break; - } + /* Remove the entries from the previous table. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->RemoveTableEntries(num_to_clear); + } - next_valid = impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context)); - } + /* If we cleared a table, we need to note that we updated and free the table. */ + if (freeing_table) { + KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize)); + ClearPageTable(table); + this->GetPageTableManager().Free(table); + } - /* Handle the last block. */ - if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) { - mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize); - } - } + /* Advance; we're no longer contiguous. */ + context.is_contiguous = false; + context.level_entries[context.level] = pte + num_to_clear - 1; - /* Cache address space extents for convenience. */ - const KProcessAddress as_start = this->GetAddressSpaceStart(); - const KProcessAddress as_last = as_start + this->GetAddressSpaceSize() - 1; + /* We may have removed the last entries in a table, in which case we can free and unmap the tables. */ + if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { + break; + } - /* Free all L3 tables. */ - for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L2BlockSize) { - L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address); - if (l1_entry->IsTable()) { - L2PageTableEntry *l2_entry = impl.GetL2Entry(l1_entry, cur_address); - if (l2_entry->IsTable()) { - const KVirtualAddress l3_table = GetPageTableVirtualAddress(l2_entry->GetTable()); - if (this->GetPageTableManager().IsInPageTableHeap(l3_table)) { - while (!this->GetPageTableManager().Close(l3_table, 1)) { /* ... */ } - ClearPageTable(l3_table); - this->GetPageTableManager().Free(l3_table); + /* Advance; we will not be working with blocks any more. */ + context.level = static_cast(util::ToUnderlying(context.level) + 1); + freeing_table = true; } - } - } - } - /* Free all L2 tables. */ - for (KProcessAddress cur_address = as_start; cur_address <= as_last; cur_address += L1BlockSize) { - L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_address); - if (l1_entry->IsTable()) { - const KVirtualAddress l2_table = GetPageTableVirtualAddress(l1_entry->GetTable()); - if (this->GetPageTableManager().IsInPageTableHeap(l2_table)) { - while (!this->GetPageTableManager().Close(l2_table, 1)) { /* ... */ } - ClearPageTable(l2_table); - this->GetPageTableManager().Free(l2_table); } + + /* Continue the traversal. */ + cur_valid = impl.ContinueTraversal(std::addressof(entry), std::addressof(context)); + } + + /* Free any remaining pages. */ + if (cur_size > 0) { + mm.Close(cur_phys_addr, cur_size / PageSize); } } @@ -260,6 +266,7 @@ namespace ams::kern::arch::arm64 { KPageTableBase::Finalize(); } + R_SUCCEED(); } @@ -570,7 +577,7 @@ namespace ams::kern::arch::arm64 { context.is_contiguous = false; context.level_entries[context.level] = pte + num_to_clear - 1; - /* We may have removed the last entries in a table, in which case we can free an unmap the tables. */ + /* We may have removed the last entries in a table, in which case we can free and unmap the tables. */ if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { break; } @@ -1056,7 +1063,7 @@ namespace ams::kern::arch::arm64 { /* If we merged, correct the traversal to a sane state. */ if (merge) { - /* NOTE: Nintendo does not verify the result of this BeginTraversal call. */ + /* NOTE: Begin a new traversal, now that we've merged. */ MESOSPHERE_ABORT_UNLESS(impl.BeginTraversal(std::addressof(next_entry), std::addressof(context), cur_virt_addr)); /* The actual size needs to not take into account the portion of the block before our virtual address. */ From e1e84d4450a1a47addce9b44a0a9ac8896a71e6c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 14:20:31 -0700 Subject: [PATCH 163/238] kern: update ChangePermissions to use new iteration logic --- .../arch/arm64/kern_k_page_table.hpp | 1 - .../source/arch/arm64/kern_k_page_table.cpp | 71 +++++-------------- 2 files changed, 19 insertions(+), 53 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index e4fca0dd5..0398d1a16 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -245,7 +245,6 @@ namespace ams::kern::arch::arm64 { static ALWAYS_INLINE void ClearPageTable(KVirtualAddress table) { cpu::ClearPageToZero(GetVoidPointer(table)); - cpu::DataSynchronizationBarrierInnerShareable(); } ALWAYS_INLINE void OnTableUpdated() const { diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index d34c98b69..63f4b46da 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -293,6 +293,10 @@ namespace ams::kern::arch::arm64 { switch (operation) { case OperationType_Map: + /* If mapping io or uncached pages, ensure that there is no pending reschedule. */ + if (properties.io || properties.uncached) { + KScopedSchedulerLock sl; + } R_RETURN(this->MapContiguous(virt_addr, phys_addr, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, page_list, reuse_ll)); case OperationType_ChangePermissions: R_RETURN(this->ChangePermissions(virt_addr, num_pages, entry_template, properties.disable_merge_attributes, false, false, page_list, reuse_ll)); @@ -317,6 +321,10 @@ namespace ams::kern::arch::arm64 { switch (operation) { case OperationType_MapGroup: case OperationType_MapFirstGroup: + /* If mapping io or uncached pages, ensure that there is no pending reschedule. */ + if (properties.io || properties.uncached) { + KScopedSchedulerLock sl; + } R_RETURN(this->MapGroup(virt_addr, page_group, num_pages, entry_template, properties.disable_merge_attributes == DisableMergeAttribute_DisableHead, operation != OperationType_MapFirstGroup, page_list, reuse_ll)); MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); } @@ -900,6 +908,9 @@ namespace ams::kern::arch::arm64 { Result KPageTable::ChangePermissions(KProcessAddress virt_addr, size_t num_pages, PageTableEntry entry_template, DisableMergeAttribute disable_merge_attr, bool refresh_mapping, bool flush_mapping, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + /* Ensure there are no pending data writes. */ + cpu::DataSynchronizationBarrier(); + /* Separate pages before we change permissions. */ R_TRY(this->SeparatePages(virt_addr, num_pages, page_list, reuse_ll)); @@ -990,59 +1001,15 @@ namespace ams::kern::arch::arm64 { } /* Apply the entry template. */ - L1PageTableEntry *l1_entry = impl.GetL1Entry(cur_virt_addr); - switch (next_entry.block_size) { - case L1BlockSize: - { - /* Write the updated entry. */ - *l1_entry = L1PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr, entry_template, sw_reserved_bits, false); - } - break; - case L2ContiguousBlockSize: - case L2BlockSize: - { - /* Get the number of L2 blocks. */ - const size_t num_l2_blocks = next_entry.block_size / L2BlockSize; + { + const size_t num_entries = context.is_contiguous ? BlocksPerContiguousBlock : 1; - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - - /* Write the updated entry. */ - const bool contig = next_entry.block_size == L2ContiguousBlockSize; - for (size_t i = 0; i < num_l2_blocks; i++) { - *impl.GetL2EntryFromTable(l2_virt, cur_virt_addr + L2BlockSize * i) = L2PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr + L2BlockSize * i, entry_template, sw_reserved_bits, contig); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - } - break; - case L3ContiguousBlockSize: - case L3BlockSize: - { - /* Get the number of L3 blocks. */ - const size_t num_l3_blocks = next_entry.block_size / L3BlockSize; - - /* Get the L2 entry. */ - KPhysicalAddress l2_phys = Null; - MESOSPHERE_ABORT_UNLESS(l1_entry->GetTable(l2_phys)); - const KVirtualAddress l2_virt = GetPageTableVirtualAddress(l2_phys); - L2PageTableEntry *l2_entry = impl.GetL2EntryFromTable(l2_virt, cur_virt_addr); - - /* Get the L3 entry. */ - KPhysicalAddress l3_phys = Null; - MESOSPHERE_ABORT_UNLESS(l2_entry->GetTable(l3_phys)); - const KVirtualAddress l3_virt = GetPageTableVirtualAddress(l3_phys); - - /* Write the updated entry. */ - const bool contig = next_entry.block_size == L3ContiguousBlockSize; - for (size_t i = 0; i < num_l3_blocks; i++) { - *impl.GetL3EntryFromTable(l3_virt, cur_virt_addr + L3BlockSize * i) = L3PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr + L3BlockSize * i, entry_template, sw_reserved_bits, contig); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - } - } - break; - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); + auto * const pte = context.level_entries[context.level]; + const size_t block_size = impl.GetBlockSize(context.level); + for (size_t i = 0; i < num_entries; ++i) { + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, next_entry.phys_addr + i * block_size, entry_template, sw_reserved_bits, context.is_contiguous, context.level == KPageTableImpl::EntryLevel_L3); + sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); + } } /* If our option asks us to, try to merge mappings. */ From 4c81432e94646e31fa222109a7fa2fa024ee2153 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 15:29:29 -0700 Subject: [PATCH 164/238] kern: update KPageTable::Map for new refactor --- .../arch/arm64/kern_k_page_table.hpp | 25 +- .../arch/arm64/kern_k_page_table_impl.hpp | 10 +- .../source/arch/arm64/kern_k_page_table.cpp | 309 +++++++----------- 3 files changed, 128 insertions(+), 216 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index 0398d1a16..f889d199a 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -201,32 +201,9 @@ namespace ams::kern::arch::arm64 { NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); Result Finalize(); private: - Result MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); - Result MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); - Result MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); - Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll); - Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) { - switch (page_size) { - case L1BlockSize: - R_RETURN(this->MapL1Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll)); - case L2ContiguousBlockSize: - entry_template.SetContiguous(true); - [[fallthrough]]; -#ifdef ATMOSPHERE_BOARD_NINTENDO_NX - case L2TegraSmmuBlockSize: -#endif - case L2BlockSize: - R_RETURN(this->MapL2Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll)); - case L3ContiguousBlockSize: - entry_template.SetContiguous(true); - [[fallthrough]]; - case L3BlockSize: - R_RETURN(this->MapL3Blocks(virt_addr, phys_addr, num_pages, entry_template, disable_head_merge, page_list, reuse_ll)); - MESOSPHERE_UNREACHABLE_DEFAULT_CASE(); - } - } + Result Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll); Result MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll); Result MapGroup(KProcessAddress virt_addr, const KPageGroup &pg, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, bool not_first, PageLinkedList *page_list, bool reuse_ll); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index 68b324f6e..57159c527 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -78,8 +78,6 @@ namespace ams::kern::arch::arm64 { static constexpr ALWAYS_INLINE uintptr_t GetL2Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL3Index(KProcessAddress addr) { return GetBits(GetInteger(addr)); } - static constexpr ALWAYS_INLINE uintptr_t GetLevelIndex(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), PageBits + LevelBits * level, LevelBits); } - static constexpr ALWAYS_INLINE uintptr_t GetL1Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 1)>(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL2Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 2)>(GetInteger(addr)); } static constexpr ALWAYS_INLINE uintptr_t GetL3Offset(KProcessAddress addr) { return GetBits<0, PageBits + LevelBits * (NumLevels - 3)>(GetInteger(addr)); } @@ -93,10 +91,8 @@ namespace ams::kern::arch::arm64 { static ALWAYS_INLINE KVirtualAddress GetPageTableVirtualAddress(KPhysicalAddress addr) { return KMemoryLayout::GetLinearVirtualAddress(addr); } - - //ALWAYS_INLINE bool ExtractL1Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L1PageTableEntry *l1_entry, KProcessAddress virt_addr) const; - //ALWAYS_INLINE bool ExtractL2Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L2PageTableEntry *l2_entry, KProcessAddress virt_addr) const; - //ALWAYS_INLINE bool ExtractL3Entry(TraversalEntry *out_entry, TraversalContext *out_context, const L3PageTableEntry *l3_entry, KProcessAddress virt_addr) const; + public: + static constexpr ALWAYS_INLINE uintptr_t GetLevelIndex(KProcessAddress addr, EntryLevel level) { return GetBits(GetInteger(addr), PageBits + LevelBits * level, LevelBits); } private: L1PageTableEntry *m_table; bool m_is_kernel; @@ -134,6 +130,8 @@ namespace ams::kern::arch::arm64 { explicit KPageTableImpl() { /* ... */ } + size_t GetNumL1Entries() const { return m_num_entries; } + NOINLINE void InitializeForKernel(void *tb, KVirtualAddress start, KVirtualAddress end); NOINLINE void InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end); L1PageTableEntry *Finalize(); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 63f4b46da..cbd586289 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -330,195 +330,12 @@ namespace ams::kern::arch::arm64 { } } - Result KPageTable::MapL1Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), L1BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(num_pages * PageSize, L1BlockSize)); - - /* Allocation is never needed for L1 block mapping. */ - MESOSPHERE_UNUSED(page_list, reuse_ll); - - auto &impl = this->GetImpl(); - - u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); - - /* Iterate, mapping each block. */ - for (size_t i = 0; i < num_pages; i += L1BlockSize / PageSize) { - /* Map the block. */ - *impl.GetL1Entry(virt_addr) = L1PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - virt_addr += L1BlockSize; - phys_addr += L1BlockSize; - } - - R_SUCCEED(); - } - - Result KPageTable::MapL2Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), L2BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), L2BlockSize)); - MESOSPHERE_ASSERT(util::IsAligned(num_pages * PageSize, L2BlockSize)); - - auto &impl = this->GetImpl(); - KVirtualAddress l2_virt = Null; - int l2_open_count = 0; - - u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); - - /* Iterate, mapping each block. */ - for (size_t i = 0; i < num_pages; i += L2BlockSize / PageSize) { - KPhysicalAddress l2_phys = Null; - - /* If we have no L2 table, we should get or allocate one. */ - if (l2_virt == Null) { - if (L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); !l1_entry->GetTable(l2_phys)) { - /* Allocate table. */ - l2_virt = AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l2_virt != Null, svc::ResultOutOfResource()); - - /* Set the entry. */ - l2_phys = GetPageTablePhysicalAddress(l2_virt); - PteDataMemoryBarrier(); - *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, l2_phys, this->IsKernel(), true); - } else { - l2_virt = GetPageTableVirtualAddress(l2_phys); - } - } - MESOSPHERE_ASSERT(l2_virt != Null); - - /* Map the block. */ - *impl.GetL2EntryFromTable(l2_virt, virt_addr) = L2PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - l2_open_count++; - virt_addr += L2BlockSize; - phys_addr += L2BlockSize; - - /* Account for hitting end of table. */ - if (util::IsAligned(GetInteger(virt_addr), L1BlockSize)) { - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - l2_virt = Null; - l2_open_count = 0; - } - } - - /* Perform any remaining opens. */ - if (l2_open_count > 0 && this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - - R_SUCCEED(); - } - - Result KPageTable::MapL3Blocks(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { - MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); - MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); - - auto &impl = this->GetImpl(); - KVirtualAddress l2_virt = Null; - KVirtualAddress l3_virt = Null; - int l2_open_count = 0; - int l3_open_count = 0; - - u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); - - /* Iterate, mapping each page. */ - for (size_t i = 0; i < num_pages; i++) { - KPhysicalAddress l3_phys = Null; - bool l2_allocated = false; - - /* If we have no L3 table, we should get or allocate one. */ - if (l3_virt == Null) { - KPhysicalAddress l2_phys = Null; - - /* If we have no L2 table, we should get or allocate one. */ - if (l2_virt == Null) { - if (L1PageTableEntry *l1_entry = impl.GetL1Entry(virt_addr); !l1_entry->GetTable(l2_phys)) { - /* Allocate table. */ - l2_virt = AllocatePageTable(page_list, reuse_ll); - R_UNLESS(l2_virt != Null, svc::ResultOutOfResource()); - - /* Set the entry. */ - l2_phys = GetPageTablePhysicalAddress(l2_virt); - PteDataMemoryBarrier(); - *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, l2_phys, this->IsKernel(), true); - l2_allocated = true; - } else { - l2_virt = GetPageTableVirtualAddress(l2_phys); - } - } - MESOSPHERE_ASSERT(l2_virt != Null); - - if (L2PageTableEntry *l2_entry = impl.GetL2EntryFromTable(l2_virt, virt_addr); !l2_entry->GetTable(l3_phys)) { - /* Allocate table. */ - l3_virt = AllocatePageTable(page_list, reuse_ll); - if (l3_virt == Null) { - /* Cleanup the L2 entry. */ - if (l2_allocated) { - *impl.GetL1Entry(virt_addr) = InvalidL1PageTableEntry; - this->NoteUpdated(); - FreePageTable(page_list, l2_virt); - } else if (this->GetPageTableManager().IsInPageTableHeap(l2_virt) && l2_open_count > 0) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - - R_THROW(svc::ResultOutOfResource()); - } - - /* Set the entry. */ - l3_phys = GetPageTablePhysicalAddress(l3_virt); - PteDataMemoryBarrier(); - *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, l3_phys, this->IsKernel(), true); - l2_open_count++; - } else { - l3_virt = GetPageTableVirtualAddress(l3_phys); - } - } - MESOSPHERE_ASSERT(l3_virt != Null); - - /* Map the page. */ - *impl.GetL3EntryFromTable(l3_virt, virt_addr) = L3PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false); - sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); - l3_open_count++; - virt_addr += PageSize; - phys_addr += PageSize; - - /* Account for hitting end of table. */ - if (util::IsAligned(GetInteger(virt_addr), L2BlockSize)) { - if (this->GetPageTableManager().IsInPageTableHeap(l3_virt)) { - this->GetPageTableManager().Open(l3_virt, l3_open_count); - } - l3_virt = Null; - l3_open_count = 0; - - if (util::IsAligned(GetInteger(virt_addr), L1BlockSize)) { - if (this->GetPageTableManager().IsInPageTableHeap(l2_virt) && l2_open_count > 0) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - l2_virt = Null; - l2_open_count = 0; - } - } - } - - /* Perform any remaining opens. */ - if (l2_open_count > 0 && this->GetPageTableManager().IsInPageTableHeap(l2_virt)) { - this->GetPageTableManager().Open(l2_virt, l2_open_count); - } - if (l3_open_count > 0 && this->GetPageTableManager().IsInPageTableHeap(l3_virt)) { - this->GetPageTableManager().Open(l3_virt, l3_open_count); - } - - R_SUCCEED(); - } - Result KPageTable::Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + /* Ensure there are no pending data writes. */ + cpu::DataSynchronizationBarrier(); + auto &impl = this->GetImpl(); /* If we're not forcing an unmap, separate pages immediately. */ @@ -632,6 +449,126 @@ namespace ams::kern::arch::arm64 { R_SUCCEED(); } + Result KPageTable::Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) { + MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); + /* MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); */ + /* MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); */ + + auto &impl = this->GetImpl(); + u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); + + /* Begin traversal. */ + TraversalContext context; + TraversalEntry entry; + bool valid = impl.BeginTraversal(std::addressof(entry), std::addressof(context), virt_addr); + + /* Iterate, mapping each page. */ + while (num_pages > 0) { + /* If we're mapping at the address, there must be nothing there. */ + MESOSPHERE_ABORT_UNLESS(!valid); + + /* If we fail, clean up any empty tables we may have allocated. */ + ON_RESULT_FAILURE { + /* Remove entries for and free any tables. */ + while (context.level < KPageTableImpl::EntryLevel_L1) { + /* If the higher-level table has entries, we don't need to do a free. */ + if (context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { + break; + } + + /* If there's no table, we also don't need to do a free. */ + const KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level]), PageSize)); + if (table == Null) { + break; + } + + /* Clear the entry for the table we're removing. */ + *context.level_entries[context.level + 1] = InvalidPageTableEntry; + + /* Remove the entry for the table one level higher. */ + if (context.level + 1 < KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 2]->RemoveTableEntries(1); + } + + /* Advance our level. */ + context.level = static_cast(util::ToUnderlying(context.level) + 1); + + /* Note that we performed an update and free the table. */ + this->NoteUpdated(); + this->FreePageTable(page_list, table); + } + }; + + /* If necessary, allocate page tables for the entry. */ + size_t mapping_size = entry.block_size; + while (mapping_size > page_size) { + /* Allocate the table. */ + const auto table = AllocatePageTable(page_list, reuse_ll); + R_UNLESS(table != Null, svc::ResultOutOfResource()); + + /* Wait for pending stores to complete. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); + + /* Update the block entry to be a table entry. */ + *context.level_entries[context.level] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(table), this->IsKernel(), true, 0); + + /* Add the entry to the table containing this one. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->AddTableEntries(1); + } + + /* Decrease our level. */ + context.level = static_cast(util::ToUnderlying(context.level) - 1); + + /* Add our new entry to the context. */ + context.level_entries[context.level] = GetPointer(table) + impl.GetLevelIndex(virt_addr, context.level); + + /* Update our mapping size. */ + mapping_size = impl.GetBlockSize(context.level); + } + + /* Determine how many pages we can set up on this iteration. */ + const size_t block_size = impl.GetBlockSize(context.level); + const size_t max_ptes = (context.level == KPageTableImpl::EntryLevel_L1 ? impl.GetNumL1Entries() : BlocksPerTable) - ((reinterpret_cast(context.level_entries[context.level]) / sizeof(PageTableEntry)) & (BlocksPerTable - 1)); + const size_t max_pages = (block_size * max_ptes) / PageSize; + + const size_t cur_pages = std::min(max_pages, num_pages); + + /* Determine the new base attribute. */ + const bool contig = page_size >= BlocksPerContiguousBlock * mapping_size; + + const size_t num_ptes = cur_pages / (block_size / PageSize); + auto *pte = context.level_entries[context.level]; + for (size_t i = 0; i < num_ptes; ++i) { + *pte = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + i * block_size, entry_template, sw_reserved_bits, contig, context.level == KPageTableImpl::EntryLevel_L3); + sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); + } + + /* Add the entries to the table containing this one. */ + if (context.level != KPageTableImpl::EntryLevel_L1) { + context.level_entries[context.level + 1]->AddTableEntries(num_ptes); + } + + /* Update our context. */ + context.is_contiguous = contig; + context.level_entries[context.level] = pte + num_ptes - (contig ? BlocksPerContiguousBlock : 1); + + /* Advance our addresses. */ + phys_addr += cur_pages * PageSize; + virt_addr += cur_pages * PageSize; + num_pages -= cur_pages; + + /* Continue traversal. */ + valid = impl.ContinueTraversal(std::addressof(entry), std::addressof(context)); + } + + /* We mapped, so wait for our writes to take. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); + + R_SUCCEED(); + + } + Result KPageTable::MapContiguous(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); From 570989384b9edd2489175db59fc2d6bc0c89ca3e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 16:10:18 -0700 Subject: [PATCH 165/238] kern: first round of page table refactor bug fixes --- .../libmesosphere/source/arch/arm64/kern_k_page_table.cpp | 4 ++-- .../source/arch/arm64/kern_k_page_table_impl.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index cbd586289..d488a1152 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -540,7 +540,7 @@ namespace ams::kern::arch::arm64 { const size_t num_ptes = cur_pages / (block_size / PageSize); auto *pte = context.level_entries[context.level]; for (size_t i = 0; i < num_ptes; ++i) { - *pte = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + i * block_size, entry_template, sw_reserved_bits, contig, context.level == KPageTableImpl::EntryLevel_L3); + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + i * block_size, entry_template, sw_reserved_bits, contig, context.level == KPageTableImpl::EntryLevel_L3); sw_reserved_bits &= ~(PageTableEntry::SoftwareReservedBit_DisableMergeHead); } @@ -803,7 +803,7 @@ namespace ams::kern::arch::arm64 { } /* Separate. */ - impl.SeparatePages(entry, context, virt_addr, nullptr); + impl.SeparatePages(entry, context, virt_addr, GetPointer(table)); this->NoteUpdated(); } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 249024a29..3a9c1275b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -261,7 +261,7 @@ namespace ams::kern::arch::arm64 { auto * const first = context->level_entries[context->level]; const KPhysicalAddress block = this->GetBlock(first, context->level); for (size_t i = 0; i < BlocksPerTable; ++i) { - pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * (context->level - 1))), PageTableEntry(first->GetEntryTemplateForSeparate(i)), PageTableEntry::SoftwareReservedBit_None, true, context->level == EntryLevel_L3); + pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * (context->level - 1))), PageTableEntry(first->GetEntryTemplateForSeparate(i)), PageTableEntry::SoftwareReservedBit_None, true, context->level - 1 == EntryLevel_L3); } context->is_contiguous = true; @@ -271,7 +271,8 @@ namespace ams::kern::arch::arm64 { cpu::DataSynchronizationBarrierInnerShareableStore(); /* Update the block entry to be a table entry. */ - *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(KVirtualAddress(first)), m_is_kernel, true, BlocksPerTable); + *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(KVirtualAddress(pte)), m_is_kernel, true, BlocksPerTable); + context->level_entries[context->level] = pte + this->GetLevelIndex(address, context->level); } From c911420d6aacff634428db1519a1531a5c2305ea Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 18:04:54 -0700 Subject: [PATCH 166/238] kern: fix more page table refactor bugs --- .../arch/arm64/kern_k_page_table_impl.hpp | 8 ++++++ .../source/arch/arm64/kern_k_page_table.cpp | 27 ++++++++++++++----- .../arch/arm64/kern_k_page_table_impl.cpp | 4 +-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index 57159c527..e8965c4d8 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -146,6 +146,14 @@ namespace ams::kern::arch::arm64 { static bool MergePages(KVirtualAddress *out, TraversalContext *context); void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const; + + KProcessAddress GetAddressForContext(const TraversalContext *context) const { + KProcessAddress addr = m_is_kernel ? static_cast(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0; + for (u32 level = context->level; level <= EntryLevel_L1; ++level) { + addr += ((reinterpret_cast(context->level_entries[level]) / sizeof(PageTableEntry)) & (BlocksPerTable - 1)) << (PageBits + LevelBits * level); + } + return addr; + } }; } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index d488a1152..39efc0b5f 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -226,6 +226,9 @@ namespace ams::kern::arch::arm64 { /* If we cleared a table, we need to note that we updated and free the table. */ if (freeing_table) { KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize)); + if (table == Null) { + break; + } ClearPageTable(table); this->GetPageTableManager().Free(table); } @@ -243,11 +246,14 @@ namespace ams::kern::arch::arm64 { context.level = static_cast(util::ToUnderlying(context.level) + 1); freeing_table = true; } - } /* Continue the traversal. */ cur_valid = impl.ContinueTraversal(std::addressof(entry), std::addressof(context)); + + if (entry.block_size == 0) { + break; + } } /* Free any remaining pages. */ @@ -266,7 +272,6 @@ namespace ams::kern::arch::arm64 { KPageTableBase::Finalize(); } - R_SUCCEED(); } @@ -379,6 +384,7 @@ namespace ams::kern::arch::arm64 { /* Unmap the block. */ bool freeing_table = false; + bool need_recalculate_virt_addr = false; while (true) { /* Clear the entries. */ const size_t num_to_clear = (!freeing_table && context.is_contiguous) ? BlocksPerContiguousBlock : 1; @@ -394,8 +400,14 @@ namespace ams::kern::arch::arm64 { /* If we cleared a table, we need to note that we updated and free the table. */ if (freeing_table) { + /* If there's no table, we also don't need to do a free. */ + const KVirtualAddress table = KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize)); + if (table == Null) { + break; + } this->NoteUpdated(); - this->FreePageTable(page_list, KVirtualAddress(util::AlignDown(reinterpret_cast(context.level_entries[context.level - 1]), PageSize))); + this->FreePageTable(page_list, table); + need_recalculate_virt_addr = true; } /* Advance; we're no longer contiguous. */ @@ -424,9 +436,10 @@ namespace ams::kern::arch::arm64 { /* Advance. */ size_t freed_size = next_entry.block_size; - if (freeing_table) { + if (need_recalculate_virt_addr) { /* We advanced more than by the block, so we need to calculate the actual advanced size. */ - const KProcessAddress new_virt_addr = util::AlignUp(GetInteger(virt_addr), impl.GetBlockSize(context.level, context.is_contiguous)); + const size_t block_size = impl.GetBlockSize(context.level, context.is_contiguous); + const KProcessAddress new_virt_addr = util::AlignDown(GetInteger(impl.GetAddressForContext(std::addressof(context))) + block_size, block_size); MESOSPHERE_ABORT_UNLESS(new_virt_addr >= virt_addr + next_entry.block_size); freed_size = std::min(new_virt_addr - virt_addr, remaining_pages * PageSize); @@ -451,8 +464,8 @@ namespace ams::kern::arch::arm64 { Result KPageTable::Map(KProcessAddress virt_addr, KPhysicalAddress phys_addr, size_t num_pages, PageTableEntry entry_template, bool disable_head_merge, size_t page_size, PageLinkedList *page_list, bool reuse_ll) { MESOSPHERE_ASSERT(this->IsLockedByCurrentThread()); - /* MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); */ - /* MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); */ + MESOSPHERE_ASSERT(util::IsAligned(GetInteger(virt_addr), PageSize)); + MESOSPHERE_ASSERT(util::IsAligned(GetInteger(phys_addr), PageSize)); auto &impl = this->GetImpl(); u8 sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(disable_head_merge, false, false); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 3a9c1275b..bddf5323f 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -176,7 +176,7 @@ namespace ams::kern::arch::arm64 { /* We want to upgrade a contiguous mapping in a table to a block. */ PageTableEntry *pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerTable * sizeof(PageTableEntry))); - const KPhysicalAddress phys_addr = GetBlock(pte, context->level); + const KPhysicalAddress phys_addr = util::AlignDown(GetBlock(pte, context->level), GetBlockSize(static_cast(context->level + 1), false)); /* First, check that all entries are valid for us to merge. */ const u64 entry_template = pte->GetEntryTemplateForMerge(); @@ -208,7 +208,7 @@ namespace ams::kern::arch::arm64 { } else { /* We want to upgrade a non-contiguous mapping to a contiguous mapping. */ PageTableEntry *pte = reinterpret_cast(util::AlignDown(reinterpret_cast(context->level_entries[context->level]), BlocksPerContiguousBlock * sizeof(PageTableEntry))); - const KPhysicalAddress phys_addr = GetBlock(pte, context->level); + const KPhysicalAddress phys_addr = util::AlignDown(GetBlock(pte, context->level), GetBlockSize(context->level, true)); /* First, check that all entries are valid for us to merge. */ const u64 entry_template = pte->GetEntryTemplateForMerge(); From e63cae5c776fdb42dccdac1e599bcc53058b34c9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 19:14:07 -0700 Subject: [PATCH 167/238] kern: Perform page table validity pass during KPageTableImpl::InitializeForKernel --- .../arm64/init/kern_k_init_page_table.hpp | 104 +++++++++--------- .../arch/arm64/kern_k_page_table_entry.hpp | 22 ++-- .../source/arch/arm64/kern_k_page_table.cpp | 16 +-- .../arch/arm64/kern_k_page_table_impl.cpp | 54 +++++++++ 4 files changed, 127 insertions(+), 69 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 8b9a6953c..805b967db 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -110,47 +110,47 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ - if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { + if (l1_entry->IsMappedBlock() || l1_entry->IsEmpty()) { MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= L1BlockSize); virt_addr += L1BlockSize; - if (l1_entry->IsBlock() && block_size == L1BlockSize) { + if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) { count++; } continue; } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock() || l2_entry->IsEmpty()) { - const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; + if (l2_entry->IsMappedBlock() || l2_entry->IsEmpty()) { + const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); virt_addr += advance_size; - if (l2_entry->IsBlock() && block_size == advance_size) { + if (l2_entry->IsMappedBlock() && block_size == advance_size) { count++; } continue; } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block or empty. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsEmpty()); - const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; + const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); virt_addr += advance_size; - if (l3_entry->IsBlock() && block_size == advance_size) { + if (l3_entry->IsMappedBlock() && block_size == advance_size) { count++; } } @@ -164,10 +164,10 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ - if (l1_entry->IsBlock() || l1_entry->IsEmpty()) { + if (l1_entry->IsMappedBlock() || l1_entry->IsEmpty()) { MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= L1BlockSize); - if (l1_entry->IsBlock() && block_size == L1BlockSize) { + if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) { if ((count++) == index) { return virt_addr; } @@ -177,16 +177,16 @@ namespace ams::kern::arch::arm64::init { } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock() || l2_entry->IsEmpty()) { - const size_t advance_size = (l2_entry->IsBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; + if (l2_entry->IsMappedBlock() || l2_entry->IsEmpty()) { + const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); - if (l2_entry->IsBlock() && block_size == advance_size) { + if (l2_entry->IsMappedBlock() && block_size == advance_size) { if ((count++) == index) { return virt_addr; } @@ -196,18 +196,18 @@ namespace ams::kern::arch::arm64::init { } /* Non empty and non-block must be table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block or empty. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock() || l3_entry->IsEmpty()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsEmpty()); - const size_t advance_size = (l3_entry->IsBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; + const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); - if (l3_entry->IsBlock() && block_size == advance_size) { + if (l3_entry->IsMappedBlock() && block_size == advance_size) { if ((count++) == index) { return virt_addr; } @@ -220,29 +220,29 @@ namespace ams::kern::arch::arm64::init { PageTableEntry *GetMappingEntry(KVirtualAddress virt_addr, size_t block_size) { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { MESOSPHERE_INIT_ABORT_UNLESS(block_size == L1BlockSize); return l1_entry; } - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { const size_t real_size = (l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size); return l2_entry; } - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); const size_t real_size = (l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(real_size == block_size); @@ -340,7 +340,7 @@ namespace ams::kern::arch::arm64::init { } /* If we don't already have an L2 table, we need to make a new one. */ - if (!l1_entry->IsTable()) { + if (!l1_entry->IsMappedTable()) { KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset); cpu::DataSynchronizationBarrierInnerShareable(); *l1_entry = L1PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); @@ -371,7 +371,7 @@ namespace ams::kern::arch::arm64::init { } /* If we don't already have an L3 table, we need to make a new one. */ - if (!l2_entry->IsTable()) { + if (!l2_entry->IsMappedTable()) { KPhysicalAddress new_table = AllocateNewPageTable(allocator, phys_to_virt_offset); cpu::DataSynchronizationBarrierInnerShareable(); *l2_entry = L2PageTableEntry(PageTableEntry::TableTag{}, new_table, attr.IsPrivilegedExecuteNever()); @@ -416,12 +416,12 @@ namespace ams::kern::arch::arm64::init { for (size_t l1_index = 0; l1_index < m_num_entries[0]; l1_index++) { /* Get L1 entry. */ L1PageTableEntry * const l1_entry = l1_table + l1_index; - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { /* Unmap the L1 entry, if we should. */ if (ShouldUnmap(l1_entry)) { *static_cast(l1_entry) = InvalidPageTableEntry; } - } else if (l1_entry->IsTable()) { + } else if (l1_entry->IsMappedTable()) { /* Get the L2 table. */ L2PageTableEntry * const l2_table = reinterpret_cast(GetInteger(l1_entry->GetTable()) + phys_to_virt_offset); @@ -430,7 +430,7 @@ namespace ams::kern::arch::arm64::init { for (size_t l2_index = 0; l2_index < MaxPageTableEntries; ++l2_index) { /* Get L2 entry. */ L2PageTableEntry * const l2_entry = l2_table + l2_index; - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { const size_t num_to_clear = (l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize) / L2BlockSize; if (ShouldUnmap(l2_entry)) { @@ -442,7 +442,7 @@ namespace ams::kern::arch::arm64::init { } l2_index = l2_index + num_to_clear - 1; - } else if (l2_entry->IsTable()) { + } else if (l2_entry->IsMappedTable()) { /* Get the L3 table. */ L3PageTableEntry * const l3_table = reinterpret_cast(GetInteger(l2_entry->GetTable()) + phys_to_virt_offset); @@ -450,7 +450,7 @@ namespace ams::kern::arch::arm64::init { size_t remaining_l3_entries = 0; for (size_t l3_index = 0; l3_index < MaxPageTableEntries; ++l3_index) { /* Get L3 entry. */ - if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsBlock()) { + if (L3PageTableEntry * const l3_entry = l3_table + l3_index; l3_entry->IsMappedBlock()) { const size_t num_to_clear = (l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize) / L3BlockSize; if (ShouldUnmap(l3_entry)) { @@ -498,25 +498,25 @@ namespace ams::kern::arch::arm64::init { /* Get the L1 entry. */ const L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { return l1_entry->GetBlock() + (GetInteger(virt_addr) & (L1BlockSize - 1)); } - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); /* Get the L2 entry. */ const L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { return l2_entry->GetBlock() + (GetInteger(virt_addr) & (L2BlockSize - 1)); } - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* Get the L3 entry. */ const L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); return l3_entry->GetBlock() + (GetInteger(virt_addr) & (L3BlockSize - 1)); } @@ -561,26 +561,26 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped, update. */ - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { UpdateExtents(l1_entry->GetBlock(), L1BlockSize); continue; } /* Not a block, so we must have a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { UpdateExtents(l2_entry->GetBlock(), l2_entry->IsContiguous() ? L2ContiguousBlockSize : L2BlockSize); continue; } /* Not a block, so we must have a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* We must have a mapped l3 entry to inspect. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); UpdateExtents(l3_entry->GetBlock(), l3_entry->IsContiguous() ? L3ContiguousBlockSize : L3BlockSize); } @@ -602,11 +602,11 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped, the address isn't free. */ - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { return false; } - if (!l1_entry->IsTable()) { + if (!l1_entry->IsMappedTable()) { /* Not a table, so just move to check the next region. */ virt_addr = util::AlignDown(GetInteger(virt_addr) + L1BlockSize, L1BlockSize); continue; @@ -615,11 +615,11 @@ namespace ams::kern::arch::arm64::init { /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { return false; } - if (!l2_entry->IsTable()) { + if (!l2_entry->IsMappedTable()) { /* Not a table, so just move to check the next region. */ virt_addr = util::AlignDown(GetInteger(virt_addr) + L2BlockSize, L2BlockSize); continue; @@ -628,7 +628,7 @@ namespace ams::kern::arch::arm64::init { /* Table, so check if we're mapped in L3. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - if (l3_entry->IsBlock()) { + if (l3_entry->IsMappedBlock()) { return false; } @@ -648,7 +648,7 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* Check if an L1 block is present. */ - if (l1_entry->IsBlock()) { + if (l1_entry->IsMappedBlock()) { /* Ensure that we are allowed to have an L1 block here. */ const KPhysicalAddress block = l1_entry->GetBlock(); MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); @@ -669,10 +669,10 @@ namespace ams::kern::arch::arm64::init { } /* Not a block, so we must be a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l1_entry->IsMappedTable()); L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsBlock()) { + if (l2_entry->IsMappedBlock()) { const KPhysicalAddress block = l2_entry->GetBlock(); if (l2_entry->IsContiguous()) { @@ -720,11 +720,11 @@ namespace ams::kern::arch::arm64::init { } /* Not a block, so we must be a table. */ - MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsTable()); + MESOSPHERE_INIT_ABORT_UNLESS(l2_entry->IsMappedTable()); /* We must have a mapped l3 entry to reprotect. */ L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsBlock()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock()); const KPhysicalAddress block = l3_entry->GetBlock(); if (l3_entry->IsContiguous()) { diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp index d3ac79089..6fce69f81 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp @@ -128,8 +128,8 @@ namespace ams::kern::arch::arm64 { } /* Construct a table. */ - constexpr explicit ALWAYS_INLINE PageTableEntry(TableTag, KPhysicalAddress phys_addr, bool is_kernel, bool pxn, size_t num_blocks) - : PageTableEntry(((is_kernel ? 0x3ul : 0) << 60) | (static_cast(pxn) << 59) | GetInteger(phys_addr) | (num_blocks << 2) | 0x3) + constexpr explicit ALWAYS_INLINE PageTableEntry(TableTag, KPhysicalAddress phys_addr, bool is_kernel, bool pxn, size_t ref_count) + : PageTableEntry(((is_kernel ? 0x3ul : 0) << 60) | (static_cast(pxn) << 59) | GetInteger(phys_addr) | (ref_count << 2) | 0x3) { /* ... */ } @@ -203,6 +203,7 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE KPhysicalAddress GetTable() const { return this->SelectBits(12, 36); } + constexpr ALWAYS_INLINE bool IsMappedBlock() const { return this->GetBits(0, 2) == 1; } constexpr ALWAYS_INLINE bool IsMappedTable() const { return this->GetBits(0, 2) == 3; } constexpr ALWAYS_INLINE bool IsMapped() const { return this->GetBits(0, 1) != 0; } @@ -217,11 +218,13 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE decltype(auto) SetPageAttribute(PageAttribute a) { this->SetBitsDirect(2, 3, a); return *this; } constexpr ALWAYS_INLINE decltype(auto) SetMapped(bool m) { static_assert(static_cast(MappingFlag_Mapped == (1 << 0))); this->SetBit(0, m); return *this; } - constexpr ALWAYS_INLINE size_t GetTableNumEntries() const { return this->GetBits(2, 10); } - constexpr ALWAYS_INLINE decltype(auto) SetTableNumEntries(size_t num) { this->SetBits(2, 10, num); } + constexpr ALWAYS_INLINE size_t GetTableReferenceCount() const { return this->GetBits(2, 10); } + constexpr ALWAYS_INLINE decltype(auto) SetTableReferenceCount(size_t num) { this->SetBits(2, 10, num); return *this; } - constexpr ALWAYS_INLINE decltype(auto) AddTableEntries(size_t num) { return this->SetTableNumEntries(this->GetTableNumEntries() + num); } - constexpr ALWAYS_INLINE decltype(auto) RemoveTableEntries(size_t num) { return this->SetTableNumEntries(this->GetTableNumEntries() - num); } + constexpr ALWAYS_INLINE decltype(auto) OpenTableReferences(size_t num) { MESOSPHERE_ASSERT(this->GetTableReferenceCount() + num <= BlocksPerTable + 1); return this->SetTableReferenceCount(this->GetTableReferenceCount() + num); } + constexpr ALWAYS_INLINE decltype(auto) CloseTableReferences(size_t num) { MESOSPHERE_ASSERT(this->GetTableReferenceCount() >= num); return this->SetTableReferenceCount(this->GetTableReferenceCount() - num); } + + constexpr ALWAYS_INLINE decltype(auto) SetValid() { MESOSPHERE_ASSERT((m_attributes & ExtensionFlag_Valid) == 0); m_attributes |= ExtensionFlag_Valid; return *this; } constexpr ALWAYS_INLINE u64 GetEntryTemplateForMerge() const { constexpr u64 BaseMask = (0xFFFF000000000FFFul & ~static_cast((0x1ul << 52) | ExtensionFlag_TestTableMask | ExtensionFlag_DisableMergeHead | ExtensionFlag_DisableMergeHeadAndBody | ExtensionFlag_DisableMergeTail)); @@ -301,7 +304,7 @@ namespace ams::kern::arch::arm64 { } constexpr explicit ALWAYS_INLINE L1PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig) - : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | 0x1) { /* ... */ } @@ -363,7 +366,7 @@ namespace ams::kern::arch::arm64 { } constexpr explicit ALWAYS_INLINE L2PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig) - : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | PageTableEntry::ExtensionFlag_Valid) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | 0x1) { /* ... */ } @@ -428,12 +431,13 @@ namespace ams::kern::arch::arm64 { constexpr explicit ALWAYS_INLINE L3PageTableEntry(InvalidTag) : PageTableEntry(InvalidTag{}) { /* ... */ } constexpr explicit ALWAYS_INLINE L3PageTableEntry(BlockTag, KPhysicalAddress phys_addr, const PageTableEntry &attr, u8 sw_reserved_bits, bool contig) - : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | static_cast(ExtensionFlag_TestTableMask)) + : PageTableEntry(attr, (static_cast(sw_reserved_bits) << 55) | (static_cast(contig) << 52) | GetInteger(phys_addr) | 0x3) { /* ... */ } constexpr ALWAYS_INLINE bool IsBlock() const { return (GetRawAttributes() & ExtensionFlag_TestTableMask) == ExtensionFlag_TestTableMask; } + constexpr ALWAYS_INLINE bool IsMappedBlock() const { return this->GetBits(0, 2) == 3; } constexpr ALWAYS_INLINE KPhysicalAddress GetBlock() const { return this->SelectBits(12, 36); diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index 39efc0b5f..d13f81979 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -220,7 +220,7 @@ namespace ams::kern::arch::arm64 { /* Remove the entries from the previous table. */ if (context.level != KPageTableImpl::EntryLevel_L1) { - context.level_entries[context.level + 1]->RemoveTableEntries(num_to_clear); + context.level_entries[context.level + 1]->CloseTableReferences(num_to_clear); } /* If we cleared a table, we need to note that we updated and free the table. */ @@ -238,7 +238,7 @@ namespace ams::kern::arch::arm64 { context.level_entries[context.level] = pte + num_to_clear - 1; /* We may have removed the last entries in a table, in which case we can free and unmap the tables. */ - if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { + if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableReferenceCount() != 0) { break; } @@ -395,7 +395,7 @@ namespace ams::kern::arch::arm64 { /* Remove the entries from the previous table. */ if (context.level != KPageTableImpl::EntryLevel_L1) { - context.level_entries[context.level + 1]->RemoveTableEntries(num_to_clear); + context.level_entries[context.level + 1]->CloseTableReferences(num_to_clear); } /* If we cleared a table, we need to note that we updated and free the table. */ @@ -415,7 +415,7 @@ namespace ams::kern::arch::arm64 { context.level_entries[context.level] = pte + num_to_clear - 1; /* We may have removed the last entries in a table, in which case we can free and unmap the tables. */ - if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { + if (context.level >= KPageTableImpl::EntryLevel_L1 || context.level_entries[context.level + 1]->GetTableReferenceCount() != 0) { break; } @@ -485,7 +485,7 @@ namespace ams::kern::arch::arm64 { /* Remove entries for and free any tables. */ while (context.level < KPageTableImpl::EntryLevel_L1) { /* If the higher-level table has entries, we don't need to do a free. */ - if (context.level_entries[context.level + 1]->GetTableNumEntries() != 0) { + if (context.level_entries[context.level + 1]->GetTableReferenceCount() != 0) { break; } @@ -500,7 +500,7 @@ namespace ams::kern::arch::arm64 { /* Remove the entry for the table one level higher. */ if (context.level + 1 < KPageTableImpl::EntryLevel_L1) { - context.level_entries[context.level + 2]->RemoveTableEntries(1); + context.level_entries[context.level + 2]->CloseTableReferences(1); } /* Advance our level. */ @@ -527,7 +527,7 @@ namespace ams::kern::arch::arm64 { /* Add the entry to the table containing this one. */ if (context.level != KPageTableImpl::EntryLevel_L1) { - context.level_entries[context.level + 1]->AddTableEntries(1); + context.level_entries[context.level + 1]->OpenTableReferences(1); } /* Decrease our level. */ @@ -559,7 +559,7 @@ namespace ams::kern::arch::arm64 { /* Add the entries to the table containing this one. */ if (context.level != KPageTableImpl::EntryLevel_L1) { - context.level_entries[context.level + 1]->AddTableEntries(num_ptes); + context.level_entries[context.level + 1]->OpenTableReferences(num_ptes); } /* Update our context. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index bddf5323f..32dfb00e5 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -27,6 +27,60 @@ namespace ams::kern::arch::arm64 { m_table = static_cast(tb); m_is_kernel = false; m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize; + + /* Page table entries created by KInitialPageTable need to be iterated and modified to ensure KPageTable invariants. */ + PageTableEntry *level_entries[EntryLevel_Count] = { nullptr, nullptr, m_table }; + u32 level = EntryLevel_L1; + while (level != EntryLevel_L1 || (level_entries[EntryLevel_L1] - static_cast(m_table)) < m_num_entries) { + /* Get the pte; it must never have the validity-extension flag set. */ + auto *pte = level_entries[level]; + MESOSPHERE_ASSERT((pte->GetSoftwareReservedBits() & PageTableEntry::SoftwareReservedBit_Valid) == 0); + + /* While we're a table, recurse, fixing up the reference counts. */ + while (level > EntryLevel_L3 && pte->IsMappedTable()) { + /* Count how many references are in the table. */ + auto *table = GetPointer(GetPageTableVirtualAddress(pte->GetTable())); + + size_t ref_count = 0; + for (size_t i = 0; i < BlocksPerTable; ++i) { + if (table[i].IsMapped()) { + ++ref_count; + } + } + + /* Set the reference count for our new page, adding one additional uncloseable reference; kernel pages must never be unreferenced. */ + pte->SetTableReferenceCount(ref_count + 1).SetValid(); + + /* Iterate downwards. */ + level -= 1; + level_entries[level] = table; + pte = level_entries[level]; + + /* Check that the entry isn't unexpected. */ + MESOSPHERE_ASSERT((pte->GetSoftwareReservedBits() & PageTableEntry::SoftwareReservedBit_Valid) == 0); + } + + /* We're dealing with some block. If it's mapped, set it valid. */ + if (pte->IsMapped()) { + pte->SetValid(); + } + + /* Advance. */ + while (true) { + /* Advance to the next entry at the current level. */ + ++level_entries[level]; + if (!util::IsAligned(reinterpret_cast(++level_entries[level]), PageSize)) { + break; + } + + /* If we're at the end of a level, advance upwards. */ + level_entries[level++] = nullptr; + + if (level > EntryLevel_L1) { + return; + } + } + } } L1PageTableEntry *KPageTableImpl::Finalize() { From 3522ac18c17dcfdb9532eb9ae01f32c241b8fb44 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 10 Oct 2024 19:14:22 -0700 Subject: [PATCH 168/238] kern: support reboot to fatal error on mariko --- .../source/board/nintendo/nx/kern_k_system_control.cpp | 7 +------ .../source/board/nintendo/nx/kern_secure_monitor.hpp | 7 ++++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index 8050f78e0..b82518e6e 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -623,13 +623,8 @@ namespace ams::kern::board::nintendo::nx { for (size_t i = 0; i < RebootPayloadSize / sizeof(u32); ++i) { GetPointer(iram_address)[i] = GetPointer(reboot_payload)[i]; } - - /* Reboot. */ - smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToPayload); - } else { - /* If we don't have a payload, reboot to rcm. */ - smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToRcm); } + smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToFatalError); } if (g_call_smc_on_panic) { diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp index 1e64d11f9..6ee325aa3 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_secure_monitor.hpp @@ -98,9 +98,10 @@ namespace ams::kern::board::nintendo::nx::smc { }; enum UserRebootType { - UserRebootType_None = 0, - UserRebootType_ToRcm = 1, - UserRebootType_ToPayload = 2, + UserRebootType_None = 0, + UserRebootType_ToRcm = 1, + UserRebootType_ToPayload = 2, + UserRebootType_ToFatalError = 3, }; void GenerateRandomBytes(void *dst, size_t size); From 9112461620330ba73a74926edd4c08b3cc0310f0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 14 Oct 2024 10:19:37 -0700 Subject: [PATCH 169/238] loader: add usb 3.0 enable patches for 19.0.0 --- stratosphere/loader/source/ldr_embedded_usb_patches.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index 4ae97c2ec..e51b60a10 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -64,6 +64,11 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_18_0_0[] = { { 0x6E48, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_19_0_0[] = { + { 0x6D90, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x6E10, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 }, @@ -76,4 +81,5 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("225865A442B4B66E8BD14B3E9450B901BDF29A40"), util::size(Usb30ForceEnablePatches_16_0_0), Usb30ForceEnablePatches_16_0_0 }, /* 16.0.0 */ { ParseModuleId("70D4C2ABCD049F16B301186924367F813DA70248"), util::size(Usb30ForceEnablePatches_17_0_0), Usb30ForceEnablePatches_17_0_0 }, /* 17.0.0 */ { ParseModuleId("4F21AE15E814FA46515C0401BB23D4F7ADCBF3F4"), util::size(Usb30ForceEnablePatches_18_0_0), Usb30ForceEnablePatches_18_0_0 }, /* 18.0.0 */ + { ParseModuleId("54BB9BB32C958E02752DC5E4AE8D016BFE1F5418"), util::size(Usb30ForceEnablePatches_19_0_0), Usb30ForceEnablePatches_19_0_0 }, /* 19.0.0 */ }; From 7c31b21d4b13e118b6579c974f324c1eef753a6e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 15 Oct 2024 21:50:20 -0700 Subject: [PATCH 170/238] git subrepo push emummc subrepo: subdir: "emummc" merged: "d248ea6f7" upstream: origin: "https://github.com/m4xw/emummc" branch: "develop" commit: "d248ea6f7" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- emummc/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index f4eb810eb..abdce15be 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = f23f943d4092ca9490dbcebbdd117abc3740abcf - parent = 1e3349e99a023517269b3fc1bc32fd84e5b3caa9 + commit = d248ea6f700c3e6987549e30a1e2eeb609ce9f8c + parent = 9112461620330ba73a74926edd4c08b3cc0310f0 method = merge cmdver = 0.4.1 From be19749841e581de4cc5d38f39f4de5fa4046c52 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 15 Oct 2024 21:51:17 -0700 Subject: [PATCH 171/238] svc: bump supported kernel version --- libraries/libvapours/include/vapours/svc/svc_version.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index e7ece762b..8c9033ab0 100644 --- a/libraries/libvapours/include/vapours/svc/svc_version.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_version.hpp @@ -57,7 +57,7 @@ namespace ams::svc { /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ - constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(18); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(19); constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); From 0c3608d1f4663955e2eed2f3f98e66a91a669224 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 15 Oct 2024 21:52:50 -0700 Subject: [PATCH 172/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "989fb7be0" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "989fb7be0" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index fe36741b8..67a54d63c 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = bb767869105d0eb5c38425f54bf20614639a078d - parent = ab5cc7568430e2c1b3fa1be6be104b7c5f71eb32 + commit = 989fb7be0c68bf229fe6789428b6c448b6de142a + parent = be19749841e581de4cc5d38f39f4de5fa4046c52 method = merge cmdver = 0.4.1 From c6014b533fb3b53998bc2cbd2608769fd44a5bc1 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 15 Oct 2024 21:55:50 -0700 Subject: [PATCH 173/238] docs: add changelog for 1.8.0 --- docs/changelog.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index ae38d0d70..9da892b07 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,19 @@ # Changelog +## 1.8.0 ++ Basic support was added for 19.0.0. + + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. + + There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update. There is still one action item from 18.0.0 to be addressed, as well. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + `loader` was updated to reflect the latest official behavior. + + `pm` was updated to reflect the latest official behavior. + + `ro` was updated to reflect the latest official behavior. ++ `creport`'s file acces patterns were optimized, greatly improving performance when generating a crash report. ++ Atmosphère now uses `relr` relocations where possible. + + This reduces the filesize of a number of atmosphère's modules. ++ A number of minor issues were fixed and improvements were made, including: + + Support was fixed for running Atmosphère on newer units with specific Hynix/Micron DRAM chips. ++ General system stability improvements to enhance the user's experience. ## 1.7.1 + Support was added for 18.1.0. + Atmosphère was updated to use GCC 14/newlib (latest devkitA64/devkitARM releases). From 57e15f3622829fd1fc7fb07f91f3a8a4dfa999d5 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Oct 2024 19:24:52 -0700 Subject: [PATCH 174/238] strat: ldr::PlatformId -> ncm::ContentMetaPlatform --- .../fssystem_crypto_configuration.hpp | 8 +++--- .../stratosphere/ldr/ldr_platform_id.hpp | 27 ------------------- .../include/stratosphere/ldr/ldr_types.hpp | 2 +- .../source/erpt/srv/erpt_srv_reporter.cpp | 2 ++ .../fssystem_crypto_configuration.cpp | 12 ++++----- .../loader/source/ldr_content_management.cpp | 12 ++++----- .../loader/source/ldr_content_management.hpp | 10 +++---- .../loader/source/ldr_loader_service.cpp | 12 ++++----- stratosphere/loader/source/ldr_meta.cpp | 10 +++---- stratosphere/loader/source/ldr_meta.hpp | 4 +-- .../loader/source/ldr_process_creation.cpp | 4 +-- .../loader/source/ldr_process_creation.hpp | 4 +-- 12 files changed, 41 insertions(+), 66 deletions(-) delete mode 100644 libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp diff --git a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp index 90f2ccdb0..17dfb656b 100644 --- a/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssystem/fssystem_crypto_configuration.hpp @@ -16,7 +16,7 @@ #pragma once #include #include -#include +#include namespace ams::fssystem { @@ -26,10 +26,10 @@ namespace ams::fssystem { void InvalidateHardwareAesKey(); - bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation); + bool IsValidSignatureKeyGeneration(ncm::ContentMetaPlatform platform, size_t key_generation); - const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused); - size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused); + const u8 *GetAcidSignatureKeyModulus(ncm::ContentMetaPlatform platform, bool prod, size_t key_generation, bool unk_unused); + size_t GetAcidSignatureKeyModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused); const u8 *GetAcidSignatureKeyPublicExponent(); diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp deleted file mode 100644 index 884cd0945..000000000 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_platform_id.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#include - -namespace ams::ldr { - - /* TODO: Is this really a FS type? What namespace does this actually live inside? */ - enum PlatformId { - PlatformId_Nx = 0, - }; - -} diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index 7d1a94aa1..524657042 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include namespace ams::ldr { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index 274f9d5ab..eb291db67 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -537,6 +537,8 @@ namespace ams::erpt::srv { /* NOTE: Nintendo ignores the result of this call. */ SubmitFsInfo(); } + #else + AMS_UNUSED(flags); #endif diff --git a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp index dbd2f86cd..23e4d0b3b 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_crypto_configuration.cpp @@ -297,20 +297,20 @@ namespace ams::fssystem { } } - bool IsValidSignatureKeyGeneration(ldr::PlatformId platform, size_t key_generation) { + bool IsValidSignatureKeyGeneration(ncm::ContentMetaPlatform platform, size_t key_generation) { switch (platform) { - case ldr::PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: return key_generation <= NxAcidSignatureKeyGenerationMax; AMS_UNREACHABLE_DEFAULT_CASE(); } } - const u8 *GetAcidSignatureKeyModulus(ldr::PlatformId platform, bool prod, size_t key_generation, bool unk_unused) { + const u8 *GetAcidSignatureKeyModulus(ncm::ContentMetaPlatform platform, bool prod, size_t key_generation, bool unk_unused) { AMS_ASSERT(IsValidSignatureKeyGeneration(platform, key_generation)); AMS_UNUSED(unk_unused); switch (platform) { - case ldr::PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: { const size_t used_keygen = (key_generation % (NxAcidSignatureKeyGenerationMax + 1)); return prod ? NxAcidSignatureKeyModulusProd[used_keygen] : NxAcidSignatureKeyModulusDev[used_keygen]; @@ -319,11 +319,11 @@ namespace ams::fssystem { } } - size_t GetAcidSignatureKeyModulusSize(ldr::PlatformId platform, bool unk_unused) { + size_t GetAcidSignatureKeyModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused) { AMS_UNUSED(unk_unused); switch (platform) { - case ldr::PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: return NxAcidSignatureKeyModulusSize; AMS_UNREACHABLE_DEFAULT_CASE(); } diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index 2a704bcd5..dbab1983f 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -25,11 +25,11 @@ namespace ams::ldr { } /* ScopedCodeMount functionality. */ - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { m_result = this->Initialize(loc, platform); } - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, PlatformId platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, ncm::ContentMetaPlatform platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { m_result = this->Initialize(loc, platform); } @@ -46,7 +46,7 @@ namespace ams::ldr { } } - Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, PlatformId platform) { + Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) { /* Capture override status, if necessary. */ this->EnsureOverrideStatus(loc); AMS_ABORT_UNLESS(m_has_status); @@ -83,7 +83,7 @@ namespace ams::ldr { } /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform) { + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) { /* Check for storage id none. */ if (static_cast(loc.storage_id) == ncm::StorageId::None) { std::memset(out_path, 0, out_size); @@ -166,9 +166,9 @@ namespace ams::ldr { R_SUCCEED(); } - fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform) { + fs::ContentAttributes GetPlatformContentAttributes(ncm::ContentMetaPlatform platform) { switch (platform) { - case PlatformId_Nx: + case ncm::ContentMetaPlatform::Nx: return fs::ContentAttributes_None; AMS_UNREACHABLE_DEFAULT_CASE(); } diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index bc5848826..f44ef738e 100644 --- a/stratosphere/loader/source/ldr_content_management.hpp +++ b/stratosphere/loader/source/ldr_content_management.hpp @@ -34,8 +34,8 @@ namespace ams::ldr { bool m_mounted_sd_or_code; bool m_mounted_code; public: - ScopedCodeMount(const ncm::ProgramLocation &loc, PlatformId platform); - ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, PlatformId platform); + ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform); + ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, ncm::ContentMetaPlatform platform); ~ScopedCodeMount(); Result GetResult() const { @@ -59,7 +59,7 @@ namespace ams::ldr { return m_base_code_verification_data; } private: - Result Initialize(const ncm::ProgramLocation &loc, PlatformId platform); + Result Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform); void EnsureOverrideStatus(const ncm::ProgramLocation &loc); }; @@ -76,10 +76,10 @@ namespace ams::ldr { #define ENCODE_CMPT_PATH(relative) "cmpt:" relative /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, PlatformId platform); + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform); Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc); Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc); - fs::ContentAttributes GetPlatformContentAttributes(PlatformId platform); + fs::ContentAttributes GetPlatformContentAttributes(ncm::ContentMetaPlatform platform); } diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index 8a888caac..b363d6b13 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -27,11 +27,11 @@ namespace ams::ldr { constinit ArgumentStore g_argument_store; - bool IsValidPlatform(PlatformId platform) { - return platform == PlatformId_Nx; + bool IsValidPlatform(ncm::ContentMetaPlatform platform) { + return platform == ncm::ContentMetaPlatform::Nx; } - Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, PlatformId platform) { + Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) { /* Check that the platform is valid. */ R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); @@ -49,7 +49,7 @@ namespace ams::ldr { R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, platform)); } - Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, PlatformId platform) { + Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) { /* Check that the platform is valid. */ R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); @@ -88,11 +88,11 @@ namespace ams::ldr { Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) { - R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, PlatformId_Nx)); + R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, ncm::ContentMetaPlatform::Nx)); } Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { - R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, PlatformId_Nx)); + R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, ncm::ContentMetaPlatform::Nx)); } Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { diff --git a/stratosphere/loader/source/ldr_meta.cpp b/stratosphere/loader/source/ldr_meta.cpp index b1d1a85ad..04e71d38b 100644 --- a/stratosphere/loader/source/ldr_meta.cpp +++ b/stratosphere/loader/source/ldr_meta.cpp @@ -103,15 +103,15 @@ namespace ams::ldr { R_SUCCEED(); } - const u8 *GetAcidSignatureModulus(PlatformId platform, u8 key_generation, bool unk_unused) { + const u8 *GetAcidSignatureModulus(ncm::ContentMetaPlatform platform, u8 key_generation, bool unk_unused) { return fssystem::GetAcidSignatureKeyModulus(platform, !IsDevelopmentForAcidSignatureCheck(), key_generation, unk_unused); } - size_t GetAcidSignatureModulusSize(PlatformId platform, bool unk_unused) { + size_t GetAcidSignatureModulusSize(ncm::ContentMetaPlatform platform, bool unk_unused) { return fssystem::GetAcidSignatureKeyModulusSize(platform, unk_unused); } - Result ValidateAcidSignature(Meta *meta, PlatformId platform, bool unk_unused) { + Result ValidateAcidSignature(Meta *meta, ncm::ContentMetaPlatform platform, bool unk_unused) { /* Loader did not check signatures prior to 10.0.0. */ if (hos::GetVersion() < hos::Version_10_0_0) { meta->check_verification_data = false; @@ -190,7 +190,7 @@ namespace ams::ldr { } /* API. */ - Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused) { + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform, bool unk_unused) { /* Set the cached program id back to zero. */ g_cached_program_id = {}; @@ -282,7 +282,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform) { + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform) { if (g_cached_program_id != loc.program_id || g_cached_override_status != status) { R_RETURN(LoadMeta(out_meta, loc, status, platform, false)); } diff --git a/stratosphere/loader/source/ldr_meta.hpp b/stratosphere/loader/source/ldr_meta.hpp index 2ac88b63b..4d3ce3fb8 100644 --- a/stratosphere/loader/source/ldr_meta.hpp +++ b/stratosphere/loader/source/ldr_meta.hpp @@ -36,8 +36,8 @@ namespace ams::ldr { }; /* Meta API. */ - Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform, bool unk_unused); - Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, PlatformId platform); + Result LoadMeta(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform, bool unk_unused); + Result LoadMetaFromCache(Meta *out_meta, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status, ncm::ContentMetaPlatform platform); void InvalidateMetaCache(); } diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index c1daeeb9f..ad94e85d6 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -664,7 +664,7 @@ namespace ams::ldr { } /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform) { + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) { /* Mount code. */ AMS_UNUSED(path); ScopedCodeMount mount(loc, override_status, platform); @@ -720,7 +720,7 @@ namespace ams::ldr { R_SUCCEED(); } - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform) { + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform) { Meta meta; /* Load Meta. */ diff --git a/stratosphere/loader/source/ldr_process_creation.hpp b/stratosphere/loader/source/ldr_process_creation.hpp index 79a622169..5e224a72a 100644 --- a/stratosphere/loader/source/ldr_process_creation.hpp +++ b/stratosphere/loader/source/ldr_process_creation.hpp @@ -19,8 +19,8 @@ namespace ams::ldr { /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, PlatformId platform); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, PlatformId platform); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform); Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); Result UnpinProgram(PinId id); From e51e11a71cdc4552467b02d7153a430ac43e6584 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Oct 2024 19:30:30 -0700 Subject: [PATCH 175/238] libstrat: re-nolto files when compiling for windows-audit --- libraries/libstratosphere/libstratosphere.mk | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/libstratosphere/libstratosphere.mk b/libraries/libstratosphere/libstratosphere.mk index b10f27f13..faec4fdb3 100644 --- a/libraries/libstratosphere/libstratosphere.mk +++ b/libraries/libstratosphere/libstratosphere.mk @@ -154,12 +154,14 @@ spl_secure_monitor_api.os.generic.o: CXXFLAGS += -I$(ATMOSPHERE_LIBRARIES_DIR)/l fs_id_string_impl.os.generic.o: CXXFLAGS += -I$(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/include ifeq ($(ATMOSPHERE_OS_NAME),windows) -# I do not remember why these had fno-lto, but it appears to -# work without no-lto (2023/03/09), so I am disabling these. I may regret this later. -#os_%.o: CXXFLAGS += -fno-lto -#fssystem_%.o: CXXFLAGS += -fno-lto -#fssrv_%.o: CXXFLAGS += -fno-lto -#fs_%.o: CXXFLAGS += -fno-lto +# Audit builds fail when these have lto disabled. +# Noting 10/29/24: +# In member function '__ct ': +# internal compiler error: in binds_to_current_def_p, at symtab.cc:2589 +os_%.o: CXXFLAGS += -fno-lto +fssystem_%.o: CXXFLAGS += -fno-lto +fssrv_%.o: CXXFLAGS += -fno-lto +fs_%.o: CXXFLAGS += -fno-lto endif #--------------------------------------------------------------------------------- From 3a5f70dceba0b75db4ea0793d8f74949e2fd233d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Oct 2024 20:00:08 -0700 Subject: [PATCH 176/238] fs: fix uninit warnings on windows localfilesystem --- .../source/fssystem/fssystem_local_file_system.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp b/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp index 2a11b1550..0f5760e64 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_local_file_system.cpp @@ -1346,7 +1346,7 @@ namespace ams::fssystem { R_UNLESS(::GetLastError() == ERROR_ACCESS_DENIED, last_error_result); /* Check if we tried to open a directory. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_path.get())); /* If the type is anything other than directory, perform generic result conversion. */ @@ -1459,7 +1459,7 @@ namespace ams::fssystem { R_TRY(this->ResolveFullPath(std::addressof(native_new_path), new_path, MaxFilePathLength, 0, false)); /* Check that the old path is a file. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_old_path.get())); R_UNLESS(type == fs::DirectoryEntryType_File, fs::ResultPathNotFound()); @@ -1509,7 +1509,7 @@ namespace ams::fssystem { R_TRY(this->ResolveFullPath(std::addressof(native_new_path), new_path, MaxDirectoryPathLength, 0, false)); /* Check that the old path is a file. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_old_path.get())); R_UNLESS(type == fs::DirectoryEntryType_Directory, fs::ResultPathNotFound()); @@ -1577,7 +1577,7 @@ namespace ams::fssystem { R_UNLESS(::GetLastError() == ERROR_ACCESS_DENIED, last_error_result); /* Check if we tried to open a directory. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_path.get())); /* If the type isn't file, return path not found. */ @@ -1623,7 +1623,7 @@ namespace ams::fssystem { ON_RESULT_FAILURE { ::CloseHandle(dir_handle); }; /* Check that we tried to open a directory. */ - fs::DirectoryEntryType type; + fs::DirectoryEntryType type{}; R_TRY(GetEntryTypeImpl(std::addressof(type), native_path.get())); /* If the type isn't directory, return path not found. */ From 9f8d17b9e6079eb421e194b81bed8a3de357c10d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Oct 2024 18:08:29 -0700 Subject: [PATCH 177/238] crypto: implement CmacGenerator --- .../libvapours/include/vapours/crypto.hpp | 1 + .../crypto/crypto_aes_128_cmac_generator.hpp | 61 +++++++++ .../vapours/crypto/crypto_cmac_generator.hpp | 51 +++++++ .../vapours/crypto/impl/crypto_cmac_impl.hpp | 128 ++++++++++++++++++ 4 files changed, 241 insertions(+) create mode 100644 libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp create mode 100644 libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp create mode 100644 libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp diff --git a/libraries/libvapours/include/vapours/crypto.hpp b/libraries/libvapours/include/vapours/crypto.hpp index 63cfcb2e4..205bbb7e6 100644 --- a/libraries/libvapours/include/vapours/crypto.hpp +++ b/libraries/libvapours/include/vapours/crypto.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp b/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp new file mode 100644 index 000000000..c252263e1 --- /dev/null +++ b/libraries/libvapours/include/vapours/crypto/crypto_aes_128_cmac_generator.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include +#include +#include + +namespace ams::crypto { + + class Aes128CmacGenerator { + NON_COPYABLE(Aes128CmacGenerator); + NON_MOVEABLE(Aes128CmacGenerator); + public: + static constexpr size_t MacSize = AesEncryptor128::BlockSize; + private: + AesEncryptor128 m_aes; + CmacGenerator m_cmac_generator; + public: + Aes128CmacGenerator() { /* ... */ } + + void Initialize(const void *key, size_t key_size) { + AMS_ASSERT(key_size == AesEncryptor128::KeySize); + + m_aes.Initialize(key, key_size); + m_cmac_generator.Initialize(std::addressof(m_aes)); + } + + void Update(const void *data, size_t size) { + m_cmac_generator.Update(data, size); + } + + void GetMac(void *dst, size_t size) { + m_cmac_generator.GetMac(dst, size); + } + }; + + ALWAYS_INLINE void GenerateAes128Cmac(void *dst, size_t dst_size, const void *data, size_t data_size, const void *key, size_t key_size) { + Aes128CmacGenerator cmac_generator; + + cmac_generator.Initialize(key, key_size); + cmac_generator.Update(data, data_size); + cmac_generator.GetMac(dst, dst_size); + } + +} diff --git a/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp b/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp new file mode 100644 index 000000000..052dab42e --- /dev/null +++ b/libraries/libvapours/include/vapours/crypto/crypto_cmac_generator.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include +#include + +namespace ams::crypto { + + template + class CmacGenerator { + NON_COPYABLE(CmacGenerator); + NON_MOVEABLE(CmacGenerator); + private: + using Impl = impl::CmacImpl; + public: + static constexpr size_t MacSize = BlockCipher::BlockSize; + private: + Impl m_impl; + public: + CmacGenerator() { /* ... */ } + + void Initialize(const BlockCipher *cipher) { + return m_impl.Initialize(cipher); + } + + void Update(const void *data, size_t size) { + return m_impl.Update(data, size); + } + + void GetMac(void *dst, size_t dst_size) { + return m_impl.GetMac(dst, dst_size); + } + }; + +} diff --git a/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp b/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp new file mode 100644 index 000000000..fb237540d --- /dev/null +++ b/libraries/libvapours/include/vapours/crypto/impl/crypto_cmac_impl.hpp @@ -0,0 +1,128 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include +#include +#include +#include +#include + +namespace ams::crypto::impl { + + template + class CmacImpl { + NON_COPYABLE(CmacImpl); + NON_MOVEABLE(CmacImpl); + public: + static constexpr size_t BlockSize = BlockCipher::BlockSize; + static constexpr size_t MacSize = BlockSize; + static_assert(BlockSize == 0x10); /* TODO: Should this be supported? */ + private: + enum State { + State_None = 0, + State_Initialized = 1, + State_Done = 2, + }; + private: + CbcMacImpl m_cbc_mac_impl; + u8 m_sub_key[BlockSize]; + State m_state; + public: + CmacImpl() : m_state(State_None) { /* ... */ } + ~CmacImpl() { + /* Clear everything. */ + ClearMemory(this, sizeof(*this)); + } + + void Initialize(const BlockCipher *cipher); + void Update(const void *data, size_t data_size); + void GetMac(void *dst, size_t dst_size); + private: + static void MultiplyOneOverGF128(u8 *data) { + /* Determine the carry bit. */ + const u8 carry = data[0] & 0x80; + + /* Shift all bytes by one bit. */ + for (size_t i = 0; i < BlockSize - 1; ++i) { + data[i] = (data[i] << 1) | (data[i + 1] >> 7); + } + data[BlockSize - 1] <<= 1; + + /* Adjust based on carry. */ + if (carry) { + data[BlockSize - 1] ^= 0x87; + } + } + }; + + template + inline void CmacImpl::Initialize(const BlockCipher *cipher) { + /* Clear the key storage. */ + std::memset(m_sub_key, 0, sizeof(m_sub_key)); + + /* Set the key storage. */ + cipher->EncryptBlock(m_sub_key, BlockSize, m_sub_key, BlockSize); + MultiplyOneOverGF128(m_sub_key); + + /* Initialize the cbc-mac impl. */ + m_cbc_mac_impl.Initialize(cipher); + + /* Mark initialized. */ + m_state = State_Initialized; + } + + template + inline void CmacImpl::Update(const void *data, size_t data_size) { + AMS_ASSERT(m_state == State_Initialized); + + m_cbc_mac_impl.template Update(data, data_size); + } + + template + inline void CmacImpl::GetMac(void *dst, size_t dst_size) { + AMS_ASSERT(m_state == State_Initialized || m_state == State_Done); + AMS_ASSERT(dst_size >= MacSize); + AMS_UNUSED(dst_size); + + /* If we're not already finalized, get the final mac. */ + if (m_state == State_Initialized) { + /* Process padding as needed. */ + if (m_cbc_mac_impl.GetBufferedDataSize() != BlockSize) { + /* Determine the remaining size. */ + const size_t remaining = BlockSize - m_cbc_mac_impl.GetBufferedDataSize(); + + /* Update with padding. */ + static constexpr u8 s_padding[BlockSize] = { 0x80, /* ... */ }; + m_cbc_mac_impl.template Update(s_padding, remaining); + + /* Update our subkey. */ + MultiplyOneOverGF128(m_sub_key); + } + + /* Mask the subkey. */ + m_cbc_mac_impl.MaskBufferedData(m_sub_key, BlockSize); + + /* Set our state as done. */ + m_state = State_Done; + } + + /* Get the mac. */ + m_cbc_mac_impl.GetMac(dst, dst_size); + } + +} From 4e99a5e08d255dc52b55f2ab0b491e6eb85cee20 Mon Sep 17 00:00:00 2001 From: tomvita <68505331+tomvita@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:38:59 +0800 Subject: [PATCH 178/238] Add extensions to dmnt cheat virtual machine (#2479) * dmnt_extension * update type 8 extension * clearify that bit 27 does not correspond to a button * update cheat.md with new code type 0xC4 * implement code type 0xC4 * Add type 1 extension * remove C0Tcr6Ma aaaaaaaa VVVVVVVV (VVVVVVVV) * Type 9 extension for floating point math * updated according to review --- docs/features/cheats.md | 91 +++++++++++++++++-- .../dmnt/source/cheat/impl/dmnt_cheat_vm.cpp | 73 ++++++++++++++- .../dmnt/source/cheat/impl/dmnt_cheat_vm.hpp | 17 +++- 3 files changed, 171 insertions(+), 10 deletions(-) diff --git a/docs/features/cheats.md b/docs/features/cheats.md index f67236bba..bf7320f23 100644 --- a/docs/features/cheats.md +++ b/docs/features/cheats.md @@ -49,7 +49,7 @@ Code type 0x0 allows writing a static value to a memory address. `0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` + T: Width of memory write (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to use as an offset from memory region base. + A: Immediate offset to use from memory region base. + V: Value to write. @@ -62,11 +62,13 @@ Code type 0x1 performs a comparison of the contents of memory to a static value. If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped. #### Encoding -`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` +`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)` -+ T: Width of memory write (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + C: Condition to use, see below. ++ X: Operand Type, see below. ++ r: Offset Register (operand types 1). + A: Immediate offset to use from memory region base. + V: Value to compare to. @@ -78,6 +80,9 @@ If the condition is not met, all instructions until the appropriate End or Else + 5: == + 6: != +#### Operand Type ++ 0: Memory Base + Relative Offset ++ 1: Memory Base + Offset Register + Relative Offset --- ### Code Type 0x2: End Conditional Block @@ -126,7 +131,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a `5TMR00AA AAAAAAAA` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to load value into. + A: Immediate offset to use from memory region base. @@ -137,6 +142,22 @@ Code type 0x5 allows loading a value from memory into a register, either using a + R: Register to load value into. (This register is also used as the base memory address). + A: Immediate offset to use from register R. +#### Load from Register Address Encoding +`5T0R2SAA AAAAAAAA` + ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ R: Register to load value into. ++ S: Register to use as the base memory address. ++ A: Immediate offset to use from register R. + +#### Load From Fixed Address Encoding with offset register +`5TMR3SAA AAAAAAAA` + ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). ++ R: Register to load value into. ++ S: Register to use as offset register. ++ A: Immediate offset to use from memory region base. --- ### Code Type 0x6: Store Static Value to Register Memory Address @@ -250,7 +271,10 @@ Code type 0x9 allows performing arithmetic on registers. + 7: Logical Not (discards right-hand operand) + 8: Logical Xor + 9: None/Move (discards right-hand operand) - ++ 10: Float Addition, T==4 single T==8 double ++ 11: Float Subtraction, T==4 single T==8 double ++ 12: Float Multiplication, T==4 single T==8 double ++ 13: Float Division, T==4 single T==8 double --- ### Code Type 0xA: Store Register to Memory Address @@ -380,6 +404,61 @@ Code type 0xC3 reads or writes a static register with a given register. --- +### Code Type 0xC4: Begin Extended Keypress Conditional Block +Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed. + +#### Encoding +`C4r00000 kkkkkkkk kkkkkkkk` + ++ r: Auto-repeat, see below. ++ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`. + +Note that for multiple button combinations, the bitmasks should be OR'd together. + +#### Auto-repeat + ++ 0: The conditional block executes only once when the keypad mask matches. The mask must stop matching to reset for the next trigger. ++ 1: The conditional block executes as long as the keypad mask matches. + +#### Keypad Values +Note: This is the direct output of `hidKeysDown()`. + ++ 000000001: A ++ 000000002: B ++ 000000004: X ++ 000000008: Y ++ 000000010: Left Stick Pressed ++ 000000020: Right Stick Pressed ++ 000000040: L ++ 000000080: R ++ 000000100: ZL ++ 000000200: ZR ++ 000000400: Plus ++ 000000800: Minus ++ 000001000: Left ++ 000002000: Up ++ 000004000: Right ++ 000008000: Down ++ 000010000: Left Stick Left ++ 000020000: Left Stick Up ++ 000040000: Left Stick Right ++ 000080000: Left Stick Down ++ 000100000: Right Stick Left ++ 000200000: Right Stick Up ++ 000400000: Right Stick Right ++ 000800000: Right Stick Down ++ 001000000: SL Left Joy-Con ++ 002000000: SR Left Joy-Con ++ 004000000: SL Right Joy-Con ++ 008000000: SR Right Joy-Con ++ 010000000: Top button on Poké Ball Plus (Palma) controller ++ 020000000: Verification ++ 040000000: B button on Left NES/HVC controller in Handheld mode ++ 080000000: Left C button in N64 controller ++ 100000000: Up C button in N64 controller ++ 200000000: Right C button in N64 controller ++ 400000000: Down C button in N64 controller + ### Code Type 0xF0: Double Extended-Width Instruction Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble. diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index e553efd0b..c1ecfb675 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -108,6 +108,8 @@ namespace ams::dmnt::cheat::impl { this->LogToDebugFile("Bit Width: %x\n", opcode->begin_cond.bit_width); this->LogToDebugFile("Mem Type: %x\n", opcode->begin_cond.mem_type); this->LogToDebugFile("Cond Type: %x\n", opcode->begin_cond.cond_type); + this->LogToDebugFile("Inc Ofs reg: %d\n", opcode->begin_cond.include_ofs_reg); + this->LogToDebugFile("Ofs Reg Idx: %x\n", opcode->begin_cond.ofs_reg_index); this->LogToDebugFile("Rel Addr: %lx\n", opcode->begin_cond.rel_address); this->LogToDebugFile("Value: %lx\n", opcode->begin_cond.value.bit64); break; @@ -158,6 +160,11 @@ namespace ams::dmnt::cheat::impl { this->LogToDebugFile("Opcode: Begin Keypress Conditional\n"); this->LogToDebugFile("Key Mask: %x\n", opcode->begin_keypress_cond.key_mask); break; + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: + this->LogToDebugFile("Opcode: Begin Extended Keypress Conditional\n"); + this->LogToDebugFile("Key Mask: %x\n", opcode->begin_ext_keypress_cond.key_mask); + this->LogToDebugFile("Auto Repeat: %d\n", opcode->begin_ext_keypress_cond.auto_repeat); + break; case CheatVmOpcodeType_PerformArithmeticRegister: this->LogToDebugFile("Opcode: Perform Register Arithmetic\n"); this->LogToDebugFile("Bit Width: %x\n", opcode->perform_math_reg.bit_width); @@ -358,6 +365,7 @@ namespace ams::dmnt::cheat::impl { switch (opcode.opcode) { case CheatVmOpcodeType_BeginConditionalBlock: case CheatVmOpcodeType_BeginKeypressConditionalBlock: + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: case CheatVmOpcodeType_BeginRegisterConditionalBlock: opcode.begin_conditional_block = true; break; @@ -387,6 +395,8 @@ namespace ams::dmnt::cheat::impl { opcode.begin_cond.bit_width = (first_dword >> 24) & 0xF; opcode.begin_cond.mem_type = (MemoryAccessType)((first_dword >> 20) & 0xF); opcode.begin_cond.cond_type = (ConditionalComparisonType)((first_dword >> 16) & 0xF); + opcode.begin_cond.include_ofs_reg = ((first_dword >> 12) & 0xF) != 0; + opcode.begin_cond.ofs_reg_index = ((first_dword >> 8) & 0xF); opcode.begin_cond.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword); opcode.begin_cond.value = GetNextVmInt(opcode.begin_cond.bit_width); } @@ -427,7 +437,8 @@ namespace ams::dmnt::cheat::impl { opcode.ldr_memory.bit_width = (first_dword >> 24) & 0xF; opcode.ldr_memory.mem_type = (MemoryAccessType)((first_dword >> 20) & 0xF); opcode.ldr_memory.reg_index = ((first_dword >> 16) & 0xF); - opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0; + opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF); + opcode.ldr_memory.offset_register = ((first_dword >> 8) & 0xF); opcode.ldr_memory.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword); } break; @@ -460,6 +471,14 @@ namespace ams::dmnt::cheat::impl { opcode.begin_keypress_cond.key_mask = first_dword & 0x0FFFFFFF; } break; + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: + { + /* C4r00000 kkkkkkkk kkkkkkkk */ + /* Read additional words. */ + opcode.begin_ext_keypress_cond.key_mask = (u64)GetNextDword() << 32ul | (u64)GetNextDword(); + opcode.begin_ext_keypress_cond.auto_repeat = ((first_dword >> 20) & 0xF) != 0; + } + break; case CheatVmOpcodeType_PerformArithmeticRegister: { /* 9TCRSIs0 (VVVVVVVV (VVVVVVVV)) */ @@ -734,6 +753,8 @@ namespace ams::dmnt::cheat::impl { return metadata->alias_extents.base + rel_address; case MemoryAccessType_Aslr: return metadata->aslr_extents.base + rel_address; + case MemoryAccessType_NonRelative: + return rel_address; } } @@ -769,6 +790,7 @@ namespace ams::dmnt::cheat::impl { return true; } + static u64 s_keyold = 0; void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) { CheatVmOpcode cur_opcode; u64 kHeld = 0; @@ -824,7 +846,7 @@ namespace ams::dmnt::cheat::impl { case CheatVmOpcodeType_BeginConditionalBlock: { /* Read value from memory. */ - u64 src_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, cur_opcode.begin_cond.rel_address); + u64 src_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, (cur_opcode.begin_cond.include_ofs_reg) ? m_registers[cur_opcode.begin_cond.ofs_reg_index] + cur_opcode.begin_cond.rel_address : cur_opcode.begin_cond.rel_address); u64 src_value = 0; switch (cur_opcode.store_static.bit_width) { case 1: @@ -896,8 +918,12 @@ namespace ams::dmnt::cheat::impl { { /* Choose source address. */ u64 src_address; - if (cur_opcode.ldr_memory.load_from_reg) { + if (cur_opcode.ldr_memory.load_from_reg == 1) { src_address = m_registers[cur_opcode.ldr_memory.reg_index] + cur_opcode.ldr_memory.rel_address; + } else if (cur_opcode.ldr_memory.load_from_reg == 2) { + src_address = m_registers[cur_opcode.ldr_memory.offset_register] + cur_opcode.ldr_memory.rel_address; + } else if (cur_opcode.ldr_memory.load_from_reg == 3) { + src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, m_registers[cur_opcode.ldr_memory.offset_register] + cur_opcode.ldr_memory.rel_address); } else { src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, cur_opcode.ldr_memory.rel_address); } @@ -982,6 +1008,18 @@ namespace ams::dmnt::cheat::impl { this->SkipConditionalBlock(true); } break; + case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: + /* Check for keypress. */ + if (!cur_opcode.begin_ext_keypress_cond.auto_repeat) { + if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != (cur_opcode.begin_ext_keypress_cond.key_mask) || (cur_opcode.begin_ext_keypress_cond.key_mask & s_keyold) == (cur_opcode.begin_ext_keypress_cond.key_mask)) { + /* Keys not pressed. Skip conditional block. */ + this->SkipConditionalBlock(true); + } + } else if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != cur_opcode.begin_ext_keypress_cond.key_mask) { + /* Keys not pressed. Skip conditional block. */ + this->SkipConditionalBlock(true); + } + break; case CheatVmOpcodeType_PerformArithmeticRegister: { const u64 operand_1_value = m_registers[cur_opcode.perform_math_reg.src_reg_1_index]; @@ -1022,6 +1060,34 @@ namespace ams::dmnt::cheat::impl { case RegisterArithmeticType_None: res_val = operand_1_value; break; + case RegisterArithmeticType_FloatAddition: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) + std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) + std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatSubtraction: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) - std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) - std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatMultiplication: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) * std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) * std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatDivision: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) / std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) / std::bit_cast(operand_2_value)); + } + break; } @@ -1304,6 +1370,7 @@ namespace ams::dmnt::cheat::impl { break; } } + s_keyold = kHeld; } } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp index 0eb47b2a2..2dd958d5c 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp @@ -43,6 +43,7 @@ namespace ams::dmnt::cheat::impl { CheatVmOpcodeType_SaveRestoreRegister = 0xC1, CheatVmOpcodeType_SaveRestoreRegisterMask = 0xC2, CheatVmOpcodeType_ReadWriteStaticRegister = 0xC3, + CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock = 0xC4, /* This is a meta entry, and not a real opcode. */ /* This is to facilitate multi-nybble instruction decoding. */ @@ -59,6 +60,7 @@ namespace ams::dmnt::cheat::impl { MemoryAccessType_Heap = 1, MemoryAccessType_Alias = 2, MemoryAccessType_Aslr = 3, + MemoryAccessType_NonRelative = 4, }; enum ConditionalComparisonType : u32 { @@ -84,6 +86,10 @@ namespace ams::dmnt::cheat::impl { RegisterArithmeticType_LogicalXor = 8, RegisterArithmeticType_None = 9, + RegisterArithmeticType_FloatAddition = 10, + RegisterArithmeticType_FloatSubtraction = 11, + RegisterArithmeticType_FloatMultiplication = 12, + RegisterArithmeticType_FloatDivision = 13, }; enum StoreRegisterOffsetType : u32 { @@ -138,6 +144,8 @@ namespace ams::dmnt::cheat::impl { u32 bit_width; MemoryAccessType mem_type; ConditionalComparisonType cond_type; + bool include_ofs_reg; + u32 ofs_reg_index; u64 rel_address; VmInt value; }; @@ -161,7 +169,8 @@ namespace ams::dmnt::cheat::impl { u32 bit_width; MemoryAccessType mem_type; u32 reg_index; - bool load_from_reg; + u8 load_from_reg; + u8 offset_register; u64 rel_address; }; @@ -185,6 +194,11 @@ namespace ams::dmnt::cheat::impl { u32 key_mask; }; + struct BeginExtendedKeypressConditionalOpcode { + u64 key_mask; + bool auto_repeat; + }; + struct PerformArithmeticRegisterOpcode { u32 bit_width; RegisterArithmeticType math_type; @@ -259,6 +273,7 @@ namespace ams::dmnt::cheat::impl { StoreStaticToAddressOpcode str_static; PerformArithmeticStaticOpcode perform_math_static; BeginKeypressConditionalOpcode begin_keypress_cond; + BeginExtendedKeypressConditionalOpcode begin_ext_keypress_cond; PerformArithmeticRegisterOpcode perform_math_reg; StoreRegisterToAddressOpcode str_register; BeginRegisterConditionalOpcode begin_reg_cond; From 85fd13f72462095159c5edd0a034e250a1209ba9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 7 Apr 2025 16:46:58 -0700 Subject: [PATCH 179/238] kern: update KernelLdr for 19.0.0 (new checks, dummy function call). Also, fix a few very embarassing mistakes in kernel ldr: * We have been mapping the page table region RWX for a few years now, accidentally. * My attempt at making initial page tables not use bit 58 was broken in multiple ways. --- .../arch/arm64/init/kern_k_init_page_table.hpp | 12 ++++++------ .../arch/arm64/kern_k_page_table_entry.hpp | 3 ++- .../arch/arm64/kern_k_page_table_impl.cpp | 13 ++++++------- .../kernel_ldr/source/kern_init_loader.cpp | 17 +++++++++++++---- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 805b967db..b653da7bd 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -110,7 +110,7 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ - if (l1_entry->IsMappedBlock() || l1_entry->IsEmpty()) { + if (l1_entry->IsMappedBlock() || l1_entry->IsMappedEmpty()) { MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= L1BlockSize); virt_addr += L1BlockSize; @@ -126,7 +126,7 @@ namespace ams::kern::arch::arm64::init { /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock() || l2_entry->IsEmpty()) { + if (l2_entry->IsMappedBlock() || l2_entry->IsMappedEmpty()) { const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); @@ -144,7 +144,7 @@ namespace ams::kern::arch::arm64::init { L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block or empty. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsEmpty()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsMappedEmpty()); const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); @@ -164,7 +164,7 @@ namespace ams::kern::arch::arm64::init { L1PageTableEntry *l1_entry = this->GetL1Entry(virt_addr); /* If an L1 block is mapped or we're empty, advance by L1BlockSize. */ - if (l1_entry->IsMappedBlock() || l1_entry->IsEmpty()) { + if (l1_entry->IsMappedBlock() || l1_entry->IsMappedEmpty()) { MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), L1BlockSize)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= L1BlockSize); if (l1_entry->IsMappedBlock() && block_size == L1BlockSize) { @@ -182,7 +182,7 @@ namespace ams::kern::arch::arm64::init { /* Table, so check if we're mapped in L2. */ L2PageTableEntry *l2_entry = GetL2Entry(l1_entry, virt_addr); - if (l2_entry->IsMappedBlock() || l2_entry->IsEmpty()) { + if (l2_entry->IsMappedBlock() || l2_entry->IsMappedEmpty()) { const size_t advance_size = (l2_entry->IsMappedBlock() && l2_entry->IsContiguous()) ? L2ContiguousBlockSize : L2BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); MESOSPHERE_INIT_ABORT_UNLESS(static_cast(end_virt_addr - virt_addr) >= advance_size); @@ -202,7 +202,7 @@ namespace ams::kern::arch::arm64::init { L3PageTableEntry *l3_entry = GetL3Entry(l2_entry, virt_addr); /* L3 must be block or empty. */ - MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsEmpty()); + MESOSPHERE_INIT_ABORT_UNLESS(l3_entry->IsMappedBlock() || l3_entry->IsMappedEmpty()); const size_t advance_size = (l3_entry->IsMappedBlock() && l3_entry->IsContiguous()) ? L3ContiguousBlockSize : L3BlockSize; MESOSPHERE_INIT_ABORT_UNLESS(util::IsAligned(GetInteger(virt_addr), advance_size)); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp index 6fce69f81..ed32262f9 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_entry.hpp @@ -122,7 +122,7 @@ namespace ams::kern::arch::arm64 { /* Construct a new attribute. */ constexpr explicit ALWAYS_INLINE PageTableEntry(Permission perm, PageAttribute p_a, Shareable share, MappingFlag m) - : m_attributes(static_cast(perm) | static_cast(AccessFlag_Accessed) | static_cast(p_a) | static_cast(share) | static_cast(ExtensionFlag_Valid) | static_cast(m)) + : m_attributes(static_cast(perm) | static_cast(AccessFlag_Accessed) | static_cast(p_a) | static_cast(share) | static_cast(m)) { /* ... */ } @@ -205,6 +205,7 @@ namespace ams::kern::arch::arm64 { constexpr ALWAYS_INLINE bool IsMappedBlock() const { return this->GetBits(0, 2) == 1; } constexpr ALWAYS_INLINE bool IsMappedTable() const { return this->GetBits(0, 2) == 3; } + constexpr ALWAYS_INLINE bool IsMappedEmpty() const { return this->GetBits(0, 2) == 0; } constexpr ALWAYS_INLINE bool IsMapped() const { return this->GetBits(0, 1) != 0; } constexpr ALWAYS_INLINE decltype(auto) SetUserExecuteNever(bool en) { this->SetBit(54, en); return *this; } diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 32dfb00e5..150aa1d1c 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -21,12 +21,6 @@ namespace ams::kern::arch::arm64 { m_table = static_cast(tb); m_is_kernel = true; m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize; - } - - void KPageTableImpl::InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end) { - m_table = static_cast(tb); - m_is_kernel = false; - m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize; /* Page table entries created by KInitialPageTable need to be iterated and modified to ensure KPageTable invariants. */ PageTableEntry *level_entries[EntryLevel_Count] = { nullptr, nullptr, m_table }; @@ -68,7 +62,6 @@ namespace ams::kern::arch::arm64 { /* Advance. */ while (true) { /* Advance to the next entry at the current level. */ - ++level_entries[level]; if (!util::IsAligned(reinterpret_cast(++level_entries[level]), PageSize)) { break; } @@ -83,6 +76,12 @@ namespace ams::kern::arch::arm64 { } } + void KPageTableImpl::InitializeForProcess(void *tb, KVirtualAddress start, KVirtualAddress end) { + m_table = static_cast(tb); + m_is_kernel = false; + m_num_entries = util::AlignUp(end - start, L1BlockSize) / L1BlockSize; + } + L1PageTableEntry *KPageTableImpl::Finalize() { return m_table; } diff --git a/mesosphere/kernel_ldr/source/kern_init_loader.cpp b/mesosphere/kernel_ldr/source/kern_init_loader.cpp index 33fe56393..43979905c 100644 --- a/mesosphere/kernel_ldr/source/kern_init_loader.cpp +++ b/mesosphere/kernel_ldr/source/kern_init_loader.cpp @@ -49,7 +49,7 @@ namespace ams::kern::init::loader { constinit void *g_final_state[2]; - void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout) { + void RelocateKernelPhysically(uintptr_t &base_address, KernelLayout *&layout, const uintptr_t &ini_base_address) { /* Adjust layout to be correct. */ { const ptrdiff_t layout_offset = reinterpret_cast(layout) - base_address; @@ -74,6 +74,12 @@ namespace ams::kern::init::loader { const uintptr_t diff = GetInteger(correct_base) - base_address; const size_t size = layout->rw_end_offset; + /* Check that the new kernel doesn't overlap with us. */ + MESOSPHERE_INIT_ABORT_UNLESS((GetInteger(correct_base) >= reinterpret_cast(__bin_end__)) || (GetInteger(correct_base) + size <= reinterpret_cast(__bin_start__))); + + /* Check that the new kernel doesn't overlap with the initial process binary. */ + MESOSPHERE_INIT_ABORT_UNLESS((ini_base_address + InitialProcessBinarySizeMax <= GetInteger(correct_base)) || (GetInteger(correct_base) + size <= ini_base_address)); + /* Conversion from KPhysicalAddress to void * is safe here, because MMU is not set up yet. */ std::memmove(reinterpret_cast(GetInteger(correct_base)), reinterpret_cast(base_address), size); base_address += diff; @@ -90,11 +96,11 @@ namespace ams::kern::init::loader { constexpr PageTableEntry KernelLdrRWXIdentityAttribute(PageTableEntry::Permission_KernelRWX, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); const uintptr_t kernel_ldr_base = util::AlignDown(reinterpret_cast(__bin_start__), PageSize); const uintptr_t kernel_ldr_size = util::AlignUp(reinterpret_cast(__bin_end__), PageSize) - kernel_ldr_base; - init_pt.Map(kernel_ldr_base, kernel_ldr_size, kernel_ldr_base, KernelRWXIdentityAttribute, allocator, 0); + init_pt.Map(kernel_ldr_base, kernel_ldr_size, kernel_ldr_base, KernelLdrRWXIdentityAttribute, allocator, 0); /* Map in the page table region as RW- for ourselves. */ constexpr PageTableEntry PageTableRegionRWAttribute(PageTableEntry::Permission_KernelRW, PageTableEntry::PageAttribute_NormalMemory, PageTableEntry::Shareable_InnerShareable, PageTableEntry::MappingFlag_Mapped); - init_pt.Map(page_table_region, page_table_region_size, page_table_region, KernelRWXIdentityAttribute, allocator, 0); + init_pt.Map(page_table_region, page_table_region_size, page_table_region, PageTableRegionRWAttribute, allocator, 0); /* Place the L1 table addresses in the relevant system registers. */ cpu::SetTtbr0El1(init_pt.GetTtbr0L1TableAddress()); @@ -165,7 +171,7 @@ namespace ams::kern::init::loader { uintptr_t Main(uintptr_t base_address, KernelLayout *layout, uintptr_t ini_base_address) { /* Relocate the kernel to the correct physical base address. */ /* Base address and layout are passed by reference and modified. */ - RelocateKernelPhysically(base_address, layout); + RelocateKernelPhysically(base_address, layout, ini_base_address); /* Validate kernel layout. */ const uintptr_t rx_offset = layout->rx_offset; @@ -229,6 +235,9 @@ namespace ams::kern::init::loader { /* Setup initial identity mapping. TTBR1 table passed by reference. */ SetupInitialIdentityMapping(init_pt, base_address, bss_end_offset, resource_end_address, InitialPageTableRegionSizeMax, g_initial_page_allocator, reinterpret_cast(base_address + sysreg_offset)); + /* NOTE: On 19.0.0+, Nintendo calls an unknown function here on init_pt and g_initial_page_allocator. */ + /* This is stubbed in prod KernelLdr. */ + /* Generate a random slide for the kernel's base address. */ const KVirtualAddress virtual_base_address = GetRandomKernelBaseAddress(init_pt, base_address, bss_end_offset); From 6125f40bdb2560adc6fc6372600e751ca6ad9fb9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 8 Apr 2025 13:43:29 -0700 Subject: [PATCH 180/238] ams: various fixes to support booting debug configuration --- .../source/board/nintendo/nx/kern_k_device_page_table.cpp | 2 +- .../stratosphere/ams/impl/ams_system_thread_definitions.hpp | 2 +- .../include/stratosphere/ddsf/ddsf_i_session.hpp | 2 +- libraries/libstratosphere/source/diag/diag_log_impl.hpp | 2 +- libraries/libstratosphere/source/powctl/powctl_battery_api.cpp | 2 +- libraries/libstratosphere/source/powctl/powctl_charger_api.cpp | 2 +- libraries/libvapours/include/vapours/allocator.hpp | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp index f70bcbb97..292c25750 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp @@ -1214,7 +1214,7 @@ namespace ams::kern::board::nintendo::nx { for (size_t i = 0; i < map_count; ++i) { /* Get the physical address. */ const KPhysicalAddress phys_addr = l2[l2_index + i].GetPhysicalAddress(); - MESOSPHERE_ASSERT(IsHeapPhysicalAddress(phys_addr)); + MESOSPHERE_ASSERT(phys_addr == Null || IsHeapPhysicalAddress(phys_addr)); /* Fully invalidate the entry. */ l2[l2_index + i].Invalidate(); diff --git a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp index cd20d43a7..d51eb90e8 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp @@ -95,7 +95,7 @@ namespace ams::impl { AMS_DEFINE_SYSTEM_THREAD(16, creport, Main); /* ro. */ - AMS_DEFINE_SYSTEM_THREAD(16, ro, Main); + AMS_DEFINE_SYSTEM_THREAD(21, ro, Main); /* gpio. */ AMS_DEFINE_SYSTEM_THREAD(-12, gpio, InterruptHandler); diff --git a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp index 146b17dd5..a103aae83 100644 --- a/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp +++ b/libraries/libstratosphere/include/stratosphere/ddsf/ddsf_i_session.hpp @@ -50,7 +50,7 @@ namespace ams::ddsf { } void DetachDevice() { - AMS_ASSERT(this->IsOpen()); + /* AMS_ASSERT(this->IsOpen()); */ m_device = nullptr; m_access_mode = AccessMode_None; AMS_ASSERT(!this->IsOpen()); diff --git a/libraries/libstratosphere/source/diag/diag_log_impl.hpp b/libraries/libstratosphere/source/diag/diag_log_impl.hpp index 05b625307..4a504375f 100644 --- a/libraries/libstratosphere/source/diag/diag_log_impl.hpp +++ b/libraries/libstratosphere/source/diag/diag_log_impl.hpp @@ -20,7 +20,7 @@ namespace ams::diag { namespace impl { - constexpr inline size_t DebugPrintBufferLength = 0x80; + constexpr inline size_t DebugPrintBufferLength = 0x100; } diff --git a/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp b/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp index 09ec1a8a5..539ceb04f 100644 --- a/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp +++ b/libraries/libstratosphere/source/powctl/powctl_battery_api.cpp @@ -22,7 +22,7 @@ namespace ams::powctl { namespace { impl::SessionImpl &GetOpenSessionImpl(Session &session) { - AMS_ASSERT(session.has_session); + /* AMS_ASSERT(session.has_session); */ auto &impl = GetReference(session.impl_storage); AMS_ASSERT(impl.IsOpen()); return impl; diff --git a/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp b/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp index 51f3b6409..b408bf845 100644 --- a/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp +++ b/libraries/libstratosphere/source/powctl/powctl_charger_api.cpp @@ -22,7 +22,7 @@ namespace ams::powctl { namespace { impl::SessionImpl &GetOpenSessionImpl(Session &session) { - AMS_ASSERT(session.has_session); + /* AMS_ASSERT(session.has_session); */ auto &impl = GetReference(session.impl_storage); AMS_ASSERT(impl.IsOpen()); return impl; diff --git a/libraries/libvapours/include/vapours/allocator.hpp b/libraries/libvapours/include/vapours/allocator.hpp index b5d294bfe..3828d4a05 100644 --- a/libraries/libvapours/include/vapours/allocator.hpp +++ b/libraries/libvapours/include/vapours/allocator.hpp @@ -19,7 +19,7 @@ namespace ams { - constexpr inline size_t DefaultAlignment = alignof(max_align_t); + constexpr inline size_t DefaultAlignment = /*alignof(max_align_t)*/ 0x8; using AllocateFunction = void *(*)(size_t); using AllocateFunctionWithUserData = void *(*)(size_t, void *); From ef5334c3ca0a6e320b34398fd4ac2159245a9934 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Apr 2025 22:14:01 -0700 Subject: [PATCH 181/238] fusee/exo/ams: update with new keydata/version enums --- .../program/source/boot/secmon_boot_key_data.s | 9 +++++++-- .../program/source/boot/secmon_package2.cpp | 2 +- fusee/program/source/fusee_key_derivation.cpp | 11 ++++++++--- fusee/program/source/fusee_package2.cpp | 2 +- fusee/program/source/fusee_setup_horizon.cpp | 2 ++ fusee/program/source/fusee_stratosphere.cpp | 16 ++++++++++++++++ .../exosphere/pkg1/pkg1_key_generation.hpp | 1 + .../libexosphere/include/exosphere/pkg2.hpp | 2 +- libraries/libexosphere/source/fuse/fuse_api.cpp | 1 + .../include/stratosphere/hos/hos_types.hpp | 2 ++ .../fs/impl/fs_id_string_impl.os.generic.cpp | 5 +++-- .../include/vapours/ams/ams_api_version.h | 4 ++-- .../include/vapours/ams/ams_target_firmware.h | 6 +++++- 13 files changed, 50 insertions(+), 13 deletions(-) diff --git a/exosphere/program/source/boot/secmon_boot_key_data.s b/exosphere/program/source/boot/secmon_boot_key_data.s index 826441314..5ff3809d0 100644 --- a/exosphere/program/source/boot/secmon_boot_key_data.s +++ b/exosphere/program/source/boot/secmon_boot_key_data.s @@ -85,10 +85,10 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: /* We can get away with only including latest because exosphere supports newer-than-expected master key in engine. */ /* TODO: Update on next change of keys. */ /* Mariko Development Master Kek Source. */ -.byte 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70 +.byte 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03 /* Mariko Production Master Kek Source. */ -.byte 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 +.byte 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A /* Development Master Key Vectors. */ .byte 0x46, 0x22, 0xB4, 0x51, 0x9A, 0x7E, 0xA7, 0x7F, 0x62, 0xA1, 0x1F, 0x8F, 0xC5, 0x3A, 0xDB, 0xFE /* Zeroes encrypted with Master Key 00. */ @@ -110,6 +110,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 /* Master key 0F encrypted with Master key 10. */ .byte 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 /* Master key 10 encrypted with Master key 11. */ .byte 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 /* Master key 11 encrypted with Master key 12. */ +.byte 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE /* Master key 12 encrypted with Master key 13. */ /* Production Master Key Vectors. */ .byte 0x0C, 0xF0, 0x59, 0xAC, 0x85, 0xF6, 0x26, 0x65, 0xE1, 0xE9, 0x19, 0x55, 0xE6, 0xF2, 0x67, 0x3D /* Zeroes encrypted with Master Key 00. */ @@ -131,6 +132,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD /* Master key 0F encrypted with Master key 10. */ .byte 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 /* Master key 10 encrypted with Master key 11. */ .byte 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 /* Master key 11 encrypted with Master key 12. */ +.byte 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 /* Master key 12 encrypted with Master key 13. */ /* Device Master Key Source Sources. */ .byte 0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D /* 4.0.0 Device Master Key Source Source. */ @@ -149,6 +151,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 /* 17.0.0 Device Master Key Source Source. */ .byte 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 /* 18.0.0 Device Master Key Source Source. */ .byte 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 /* 19.0.0 Device Master Key Source Source. */ +.byte 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 /* 20.0.0 Device Master Key Source Source. */ /* Development Device Master Kek Sources. */ .byte 0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34 /* 4.0.0 Device Master Kek Source. */ @@ -167,6 +170,7 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 /* 17.0.0 Device Master Kek Source. */ .byte 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF /* 18.0.0 Device Master Kek Source. */ .byte 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 /* 19.0.0 Device Master Kek Source. */ +.byte 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D /* 20.0.0 Device Master Kek Source. */ /* Production Device Master Kek Sources. */ .byte 0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D /* 4.0.0 Device Master Kek Source. */ @@ -185,3 +189,4 @@ _ZN3ams6secmon4boot15VolatileKeyDataE: .byte 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E /* 17.0.0 Device Master Kek Source. */ .byte 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B /* 18.0.0 Device Master Kek Source. */ .byte 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F /* 19.0.0 Device Master Kek Source. */ +.byte 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 /* 20.0.0 Device Master Kek Source. */ \ No newline at end of file diff --git a/exosphere/program/source/boot/secmon_package2.cpp b/exosphere/program/source/boot/secmon_package2.cpp index 2d6b8948e..88c8f1189 100644 --- a/exosphere/program/source/boot/secmon_package2.cpp +++ b/exosphere/program/source/boot/secmon_package2.cpp @@ -94,7 +94,7 @@ namespace ams::secmon::boot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 19); + static_assert(pkg1::KeyGeneration_Count == 20); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_key_derivation.cpp b/fusee/program/source/fusee_key_derivation.cpp index 3d8eb31bf..bca7c4e9b 100644 --- a/fusee/program/source/fusee_key_derivation.cpp +++ b/fusee/program/source/fusee_key_derivation.cpp @@ -23,17 +23,17 @@ namespace ams::nxboot { alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 + 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A }; alignas(se::AesBlockSize) constexpr inline const u8 MarikoMasterKekSourceDev[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0x65, 0x7B, 0x11, 0x46, 0x0E, 0xC2, 0x22, 0x5D, 0xB9, 0xF1, 0xF5, 0x00, 0xF9, 0x3E, 0x1F, 0x70 + 0x8C, 0x2E, 0xC1, 0x1C, 0xA0, 0x28, 0x35, 0xFC, 0x9A, 0x9F, 0x1D, 0x9B, 0x4E, 0xDF, 0x1E, 0x03 }; alignas(se::AesBlockSize) constexpr inline const u8 EristaMasterKekSource[se::AesBlockSize] = { /* TODO: Update on next change of keys. */ - 0xD7, 0x63, 0x74, 0x46, 0x4E, 0xBA, 0x78, 0x0A, 0x7C, 0x9D, 0xB3, 0xE8, 0x7A, 0x3D, 0x71, 0xE3 + 0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8 }; alignas(se::AesBlockSize) constexpr inline const u8 KeyblobKeySource[se::AesBlockSize] = { @@ -73,6 +73,7 @@ namespace ams::nxboot { { 0xDA, 0xB9, 0xD6, 0x77, 0x52, 0x2D, 0x1F, 0x78, 0x73, 0xC9, 0x98, 0x5B, 0x06, 0xFE, 0xA0, 0x52 }, /* 17.0.0 Device Master Key Source Source. */ { 0x14, 0xF5, 0xA5, 0xD0, 0x73, 0x6D, 0x44, 0x80, 0x5F, 0x31, 0x5A, 0x8F, 0x1E, 0xD4, 0x0D, 0x63 }, /* 18.0.0 Device Master Key Source Source. */ { 0x07, 0x38, 0x9A, 0xEC, 0x9C, 0xBD, 0x50, 0x4A, 0x4C, 0x1F, 0x04, 0xDA, 0x40, 0x68, 0x29, 0xE3 }, /* 19.0.0 Device Master Key Source Source. */ + { 0xA3, 0x6B, 0x0A, 0xB5, 0x6F, 0x57, 0x4C, 0x5E, 0x00, 0xFD, 0x56, 0x21, 0xF5, 0x06, 0x6B, 0xD1 }, /* 20.0.0 Device Master Key Source Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSources[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -92,6 +93,7 @@ namespace ams::nxboot { { 0x21, 0xD6, 0x35, 0xF1, 0x0F, 0x7A, 0xF0, 0x5D, 0xDF, 0x79, 0x1C, 0x7A, 0xE4, 0x32, 0x82, 0x9E }, /* 17.0.0 Device Master Kek Source. */ { 0xE7, 0x85, 0x8C, 0xA2, 0xF4, 0x49, 0xCB, 0x07, 0xD1, 0x8E, 0x48, 0x1B, 0xE8, 0x1E, 0x28, 0x3B }, /* 18.0.0 Device Master Kek Source. */ { 0x9B, 0xA5, 0xFD, 0x74, 0x7F, 0xCD, 0x23, 0xD1, 0xD9, 0xBD, 0x6C, 0x51, 0x72, 0x5F, 0x3D, 0x1F }, /* 19.0.0 Device Master Kek Source. */ + { 0xDA, 0xFB, 0x61, 0x39, 0x48, 0x2D, 0xC2, 0x7E, 0x0D, 0x8E, 0x8F, 0x98, 0x57, 0x20, 0xB8, 0x15 }, /* 20.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 DeviceMasterKekSourcesDev[pkg1::OldDeviceMasterKeyCount][se::AesBlockSize] = { @@ -111,6 +113,7 @@ namespace ams::nxboot { { 0x4E, 0xCE, 0x7B, 0x2A, 0xEA, 0x2E, 0x3D, 0x16, 0xD5, 0x2A, 0xDE, 0xF6, 0xF8, 0x6A, 0x7D, 0x43 }, /* 17.0.0 Device Master Kek Source. */ { 0x3B, 0x00, 0x89, 0xD7, 0xA9, 0x9E, 0xB7, 0x70, 0x86, 0x00, 0xC3, 0x49, 0x52, 0x8C, 0xA4, 0xAF }, /* 18.0.0 Device Master Kek Source. */ { 0xAE, 0x78, 0x36, 0xB6, 0x91, 0xEB, 0xAF, 0x9C, 0x18, 0xF1, 0xC0, 0xD5, 0x8A, 0x0C, 0x7C, 0xA1 }, /* 19.0.0 Device Master Kek Source. */ + { 0x09, 0x12, 0x4F, 0x26, 0x90, 0xB9, 0xA6, 0xF5, 0xA5, 0x18, 0x74, 0xB6, 0x8D, 0x80, 0x59, 0x3D }, /* 20.0.0 Device Master Kek Source. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySources[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -133,6 +136,7 @@ namespace ams::nxboot { { 0x25, 0x12, 0x8B, 0xCB, 0xB5, 0x46, 0xA1, 0xF8, 0xE0, 0x52, 0x15, 0xB7, 0x0B, 0x57, 0x00, 0xBD }, /* Master key 0F encrypted with Master key 10. */ { 0x58, 0x15, 0xD2, 0xF6, 0x8A, 0xE8, 0x19, 0xAB, 0xFB, 0x2D, 0x52, 0x9D, 0xE7, 0x55, 0xF3, 0x93 }, /* Master key 10 encrypted with Master key 11. */ { 0x4A, 0x01, 0x3B, 0xC7, 0x44, 0x6E, 0x45, 0xBD, 0xE6, 0x5E, 0x2B, 0xEC, 0x07, 0x37, 0x52, 0x86 }, /* Master key 11 encrypted with Master key 12. */ + { 0x97, 0xE4, 0x11, 0xAB, 0x22, 0x72, 0x1A, 0x1F, 0x70, 0x5C, 0x00, 0xB3, 0x96, 0x30, 0x05, 0x28 }, /* Master key 12 encrypted with Master key 13. */ }; alignas(se::AesBlockSize) constexpr inline const u8 MasterKeySourcesDev[pkg1::KeyGeneration_Count][se::AesBlockSize] = { @@ -155,6 +159,7 @@ namespace ams::nxboot { { 0x39, 0x1E, 0x7E, 0xF8, 0x7E, 0x73, 0xEA, 0x6F, 0xAF, 0x00, 0x3A, 0xB4, 0xAA, 0xB8, 0xB7, 0x59 }, /* Master key 0F encrypted with Master key 10. */ { 0x0C, 0x75, 0x39, 0x15, 0x53, 0xEA, 0x81, 0x11, 0xA3, 0xE0, 0xDC, 0x3D, 0x0E, 0x76, 0xC6, 0xB8 }, /* Master key 10 encrypted with Master key 11. */ { 0x90, 0x64, 0xF9, 0x08, 0x29, 0x88, 0xD4, 0xDC, 0x73, 0xA4, 0xA1, 0x13, 0x9E, 0x59, 0x85, 0xA0 }, /* Master key 11 encrypted with Master key 12. */ + { 0x94, 0x46, 0x3B, 0xFA, 0x7D, 0xB9, 0xE2, 0x94, 0xC2, 0x9D, 0xB9, 0xA4, 0xB2, 0x56, 0xCA, 0xFE }, /* Master key 12 encrypted with Master key 13. */ }; alignas(se::AesBlockSize) constinit u8 MasterKeys[pkg1::OldMasterKeyCount][se::AesBlockSize] = {}; diff --git a/fusee/program/source/fusee_package2.cpp b/fusee/program/source/fusee_package2.cpp index 9735b0f0b..3a75a043f 100644 --- a/fusee/program/source/fusee_package2.cpp +++ b/fusee/program/source/fusee_package2.cpp @@ -80,7 +80,7 @@ namespace ams::nxboot { } /* Check that the key generation is one that we can use. */ - static_assert(pkg1::KeyGeneration_Count == 19); + static_assert(pkg1::KeyGeneration_Count == 20); if (key_generation >= pkg1::KeyGeneration_Count) { return false; } diff --git a/fusee/program/source/fusee_setup_horizon.cpp b/fusee/program/source/fusee_setup_horizon.cpp index 6d0d6a384..000bbe524 100644 --- a/fusee/program/source/fusee_setup_horizon.cpp +++ b/fusee/program/source/fusee_setup_horizon.cpp @@ -263,6 +263,8 @@ namespace ams::nxboot { return ams::TargetFirmware_18_0_0; } else if (std::memcmp(package1 + 0x10, "20240808", 8) == 0) { return ams::TargetFirmware_19_0_0; + } else if (std::memcmp(package1 + 0x10, "20250206", 8) == 0) { + return ams::TargetFirmware_20_0_0; } break; default: diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index 99fea38bd..ff9388c4d 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -180,6 +180,9 @@ namespace ams::nxboot { FsVersion_19_0_0, FsVersion_19_0_0_Exfat, + FsVersion_20_0_0, + FsVersion_20_0_0_Exfat, + FsVersion_Count, }; @@ -272,6 +275,9 @@ namespace ams::nxboot { { 0xD9, 0x4C, 0x68, 0x15, 0xF8, 0xF5, 0x0A, 0x20 }, /* FsVersion_19_0_0 */ { 0xED, 0xA8, 0x78, 0x68, 0xA4, 0x49, 0x07, 0x50 }, /* FsVersion_19_0_0_Exfat */ + + { 0x63, 0x54, 0x96, 0x9E, 0x60, 0xA7, 0x97, 0x7B }, /* FsVersion_20_0_0 */ + { 0x47, 0x41, 0x07, 0x10, 0x65, 0x4F, 0xA4, 0x3F }, /* FsVersion_20_0_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -661,6 +667,16 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x1A16A5, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1)); break; + case FsVersion_20_0_0: + AddPatch(fs_meta, 0x1A7E25, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1A8025, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1)); + break; + case FsVersion_20_0_0_Exfat: + AddPatch(fs_meta, 0x1B3744, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1B3944, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1)); + break; default: break; } diff --git a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp index 92aea986e..282c2332b 100644 --- a/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp +++ b/libraries/libexosphere/include/exosphere/pkg1/pkg1_key_generation.hpp @@ -39,6 +39,7 @@ namespace ams::pkg1 { KeyGeneration_17_0_0 = 0x10, KeyGeneration_18_0_0 = 0x11, KeyGeneration_19_0_0 = 0x12, + KeyGeneration_20_0_0 = 0x13, KeyGeneration_Count, diff --git a/libraries/libexosphere/include/exosphere/pkg2.hpp b/libraries/libexosphere/include/exosphere/pkg2.hpp index d72ce1f03..d6649d9d0 100644 --- a/libraries/libexosphere/include/exosphere/pkg2.hpp +++ b/libraries/libexosphere/include/exosphere/pkg2.hpp @@ -24,7 +24,7 @@ namespace ams::pkg2 { constexpr inline int PayloadCount = 3; constexpr inline int MinimumValidDataVersion = 0; /* We allow older package2 to load; this value is currently 0x18 in Nintendo's code. */ - constexpr inline int CurrentBootloaderVersion = 0x16; + constexpr inline int CurrentBootloaderVersion = 0x17; struct Package2Meta { using Magic = util::FourCC<'P','K','2','1'>; diff --git a/libraries/libexosphere/source/fuse/fuse_api.cpp b/libraries/libexosphere/source/fuse/fuse_api.cpp index e20dddcc0..837ad7351 100644 --- a/libraries/libexosphere/source/fuse/fuse_api.cpp +++ b/libraries/libexosphere/source/fuse/fuse_api.cpp @@ -177,6 +177,7 @@ namespace ams::fuse { } constexpr const TargetFirmware FuseVersionIncrementFirmwares[] = { + TargetFirmware_20_0_0, TargetFirmware_19_0_0, TargetFirmware_17_0_0, TargetFirmware_16_0_0, diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index a096237a8..cf455c814 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -85,6 +85,8 @@ namespace ams::hos { Version_18_0_0 = ::ams::TargetFirmware_18_0_0, Version_18_1_0 = ::ams::TargetFirmware_18_1_0, Version_19_0_0 = ::ams::TargetFirmware_19_0_0, + Version_19_0_1 = ::ams::TargetFirmware_19_0_1, + Version_20_0_0 = ::ams::TargetFirmware_20_0_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp index 5e2d9b60f..15dc8c246 100644 --- a/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp +++ b/libraries/libstratosphere/source/fs/impl/fs_id_string_impl.os.generic.cpp @@ -21,7 +21,7 @@ namespace ams::fs::impl { #define ADD_ENUM_CASE(v) case v: return #v template<> const char *IdString::ToString(pkg1::KeyGeneration id) { - static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_19_0_0); + static_assert(pkg1::KeyGeneration_Current == pkg1::KeyGeneration_20_0_0); switch (id) { using enum pkg1::KeyGeneration; case KeyGeneration_1_0_0: return "1.0.0-2.3.0"; @@ -42,7 +42,8 @@ namespace ams::fs::impl { case KeyGeneration_16_0_0: return "16.0.0-16.0.3"; case KeyGeneration_17_0_0: return "17.0.0-17.0.1"; case KeyGeneration_18_0_0: return "18.0.0-18.1.0"; - case KeyGeneration_19_0_0: return "19.0.0-"; + case KeyGeneration_19_0_0: return "19.0.0-19.0.1"; + case KeyGeneration_20_0_0: return "20.0.0-"; default: return "Unknown"; } } diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index 978b1622e..dbd4a2cfe 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -16,11 +16,11 @@ #pragma once #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 -#define ATMOSPHERE_RELEASE_VERSION_MINOR 8 +#define ATMOSPHERE_RELEASE_VERSION_MINOR 9 #define ATMOSPHERE_RELEASE_VERSION_MICRO 0 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 19 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 484f76f8b..0dcbac068 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -83,8 +83,10 @@ #define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0) #define ATMOSPHERE_TARGET_FIRMWARE_19_0_0 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_19_0_1 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 1) +#define ATMOSPHERE_TARGET_FIRMWARE_20_0_0 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_19_0_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_0_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -160,6 +162,8 @@ namespace ams { TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0, TargetFirmware_19_0_0 = ATMOSPHERE_TARGET_FIRMWARE_19_0_0, + TargetFirmware_19_0_1 = ATMOSPHERE_TARGET_FIRMWARE_19_0_1, + TargetFirmware_20_0_0 = ATMOSPHERE_TARGET_FIRMWARE_20_0_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From 6352397203247ec0ce0ec3dd5a4e6e4ffabb6ff9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Apr 2025 22:50:28 -0700 Subject: [PATCH 182/238] emummc: add offsets for 20.0.0 (untested) --- emummc/README.md | 2 +- emummc/source/FS/FS_offsets.c | 8 ++++ emummc/source/FS/FS_versions.h | 3 ++ emummc/source/FS/offsets/2000.h | 59 +++++++++++++++++++++++++++ emummc/source/FS/offsets/2000_exfat.h | 59 +++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 emummc/source/FS/offsets/2000.h create mode 100644 emummc/source/FS/offsets/2000_exfat.h diff --git a/emummc/README.md b/emummc/README.md index cada2cdb5..ea9a91d7c 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 19.0.0** +**1.0.0 - 20.0.0** ## Features * Arbitrary SDMMC backend selection diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index 64ac34562..3ceca0f8e 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -75,6 +75,8 @@ #include "offsets/1810_exfat.h" #include "offsets/1900.h" #include "offsets/1900_exfat.h" +#include "offsets/2000.h" +#include "offsets/2000_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -161,6 +163,8 @@ DEFINE_OFFSET_STRUCT(_1810); DEFINE_OFFSET_STRUCT(_1810_EXFAT); DEFINE_OFFSET_STRUCT(_1900); DEFINE_OFFSET_STRUCT(_1900_EXFAT); +DEFINE_OFFSET_STRUCT(_2000); +DEFINE_OFFSET_STRUCT(_2000_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -282,6 +286,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_1900)); case FS_VER_19_0_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_1900_EXFAT)); + case FS_VER_20_0_0: + return &(GET_OFFSET_STRUCT_NAME(_2000)); + case FS_VER_20_0_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_2000_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index 6eebac186..5b2dfc508 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -110,6 +110,9 @@ enum FS_VER FS_VER_19_0_0, FS_VER_19_0_0_EXFAT, + FS_VER_20_0_0, + FS_VER_20_0_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/2000.h b/emummc/source/FS/offsets/2000.h new file mode 100644 index 000000000..b4fe302d7 --- /dev/null +++ b/emummc/source/FS/offsets/2000.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_2000_H__ +#define __FS_2000_H__ + +// Accessor vtable getters +#define FS_OFFSET_2000_SDMMC_ACCESSOR_GC 0x1A7DB0 +#define FS_OFFSET_2000_SDMMC_ACCESSOR_SD 0x1AA130 +#define FS_OFFSET_2000_SDMMC_ACCESSOR_NAND 0x1A8560 + +// Hooks +#define FS_OFFSET_2000_SDMMC_WRAPPER_READ 0x1A3C20 +#define FS_OFFSET_2000_SDMMC_WRAPPER_WRITE 0x1A3C80 +#define FS_OFFSET_2000_RTLD 0x2B594 +#define FS_OFFSET_2000_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2000_CLKRST_SET_MIN_V_CLK_RATE 0x1C6150 + +// Misc funcs +#define FS_OFFSET_2000_LOCK_MUTEX 0x19CD80 +#define FS_OFFSET_2000_UNLOCK_MUTEX 0x19CDD0 + +#define FS_OFFSET_2000_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A3BE0 +#define FS_OFFSET_2000_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A3C00 + +// Misc Data +#define FS_OFFSET_2000_SD_MUTEX 0xFF5408 +#define FS_OFFSET_2000_NAND_MUTEX 0xFF0CF0 +#define FS_OFFSET_2000_ACTIVE_PARTITION 0xFF0D30 +#define FS_OFFSET_2000_SDMMC_DAS_HANDLE 0xFD2B08 + +// NOPs +#define FS_OFFSET_2000_SD_DAS_INIT 0x289F4 + +// Nintendo Paths +#define FS_OFFSET_2000_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2000_H__ diff --git a/emummc/source/FS/offsets/2000_exfat.h b/emummc/source/FS/offsets/2000_exfat.h new file mode 100644 index 000000000..97b04c67b --- /dev/null +++ b/emummc/source/FS/offsets/2000_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_2000_EXFAT_H__ +#define __FS_2000_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_2000_EXFAT_SDMMC_ACCESSOR_GC 0x1B36D0 +#define FS_OFFSET_2000_EXFAT_SDMMC_ACCESSOR_SD 0x1B5A50 +#define FS_OFFSET_2000_EXFAT_SDMMC_ACCESSOR_NAND 0x1B3E80 + +// Hooks +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_READ 0x1AF540 +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_WRITE 0x1AF5A0 +#define FS_OFFSET_2000_EXFAT_RTLD 0x2B594 +#define FS_OFFSET_2000_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2000_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D1A70 + +// Misc funcs +#define FS_OFFSET_2000_EXFAT_LOCK_MUTEX 0x1A86A0 +#define FS_OFFSET_2000_EXFAT_UNLOCK_MUTEX 0x1A86F0 + +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF500 +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF880 + +// Misc Data +#define FS_OFFSET_2000_EXFAT_SD_MUTEX 0x1006408 +#define FS_OFFSET_2000_EXFAT_NAND_MUTEX 0x1001CF0 +#define FS_OFFSET_2000_EXFAT_ACTIVE_PARTITION 0x1001D30 +#define FS_OFFSET_2000_EXFAT_SDMMC_DAS_HANDLE 0xFDFB08 + +// NOPs +#define FS_OFFSET_2000_EXFAT_SD_DAS_INIT 0x289F4 + +// Nintendo Paths +#define FS_OFFSET_2000_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2000_EXFAT_H__ From b9b01bbbd18dba3ddd8e46e86d92d730c36d9bf9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Apr 2025 23:01:44 -0700 Subject: [PATCH 183/238] loader: add usb 3.0 enable patches for 20.0.0 --- stratosphere/loader/source/ldr_embedded_usb_patches.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index e51b60a10..f91f1da82 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -69,6 +69,11 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_19_0_0[] = { { 0x6E10, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_20_0_0[] = { + { 0x7010, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x7090, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 }, @@ -82,4 +87,5 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("70D4C2ABCD049F16B301186924367F813DA70248"), util::size(Usb30ForceEnablePatches_17_0_0), Usb30ForceEnablePatches_17_0_0 }, /* 17.0.0 */ { ParseModuleId("4F21AE15E814FA46515C0401BB23D4F7ADCBF3F4"), util::size(Usb30ForceEnablePatches_18_0_0), Usb30ForceEnablePatches_18_0_0 }, /* 18.0.0 */ { ParseModuleId("54BB9BB32C958E02752DC5E4AE8D016BFE1F5418"), util::size(Usb30ForceEnablePatches_19_0_0), Usb30ForceEnablePatches_19_0_0 }, /* 19.0.0 */ + { ParseModuleId("40E80E7442C0DFC985315E6F9E8C77229818AC0F"), util::size(Usb30ForceEnablePatches_20_0_0), Usb30ForceEnablePatches_20_0_0 }, /* 20.0.0 */ }; From 3dd5c98f5265a617328cb292c8a99d7c2f5f1062 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Apr 2025 23:06:56 -0700 Subject: [PATCH 184/238] readme: sept has not been in the project for many years --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index bfae12a27..e17945104 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,6 @@ Components Atmosphère consists of multiple components, each of which replaces/modifies a different component of the system: * Fusée: First-stage Loader, responsible for loading and validating stage 2 (custom TrustZone) plus package2 (Kernel/FIRM sysmodules), and patching them as needed. This replaces all functionality normally in Package1loader/NX Bootloader. - * Sept: Payload used to enable support for runtime key derivation on 7.0.0. * Exosphère: Customized TrustZone, to run a customized Secure Monitor * Thermosphère: EL2 EmuNAND support, i.e. backing up and using virtualized/redirected NAND images * Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions From d147f6f93bb2e95c0f11422cab421d29350118b7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 15:04:19 -0700 Subject: [PATCH 185/238] erpt: update ids for 20.0.0 --- .../stratosphere/erpt/erpt_ids.autogen.hpp | 62 +++++++++++++++++-- utilities/erpt.py | 7 +++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index c7e5eef6b..c4dd26ea8 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -181,6 +181,13 @@ HANDLER(NANDTypeInfoDeprecated, 140 ) \ HANDLER(MicroSDTypeInfo, 141 ) \ HANDLER(AttachmentFileInfo, 142 ) \ + HANDLER(WlanInfo, 143 ) \ + HANDLER(HalfAwakeStateInfo, 144 ) \ + HANDLER(PctlSettingInfo, 145 ) \ + HANDLER(GameCardLogInfo, 146 ) \ + HANDLER(WlanIoctlErrorInfo, 147 ) \ + HANDLER(SdCardActivationInfo, 148 ) \ + HANDLER(GameCardDetailedErrorInfo, 149 ) \ HANDLER(TestNx, 1000) \ HANDLER(NANDTypeInfo, 1001) \ HANDLER(NANDExtendedCsd, 1002) \ @@ -342,7 +349,7 @@ HANDLER(TemperaturePcb, 153, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(TemperatureSoc, 154, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(CurrentFanDuty, 155, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ - HANDLER(LastDvfsThresholdTripped, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTrippedDeprecated, 156, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(CradlePdcHFwVersion, 157, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(CradlePdcAFwVersion, 158, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(CradleMcuFwVersion, 159, CradleFirmwareInfo, FieldType_NumericU32, FieldFlag_None ) \ @@ -448,7 +455,7 @@ HANDLER(AdspExceptionStackAddressDeprecated, 259, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(AdspExceptionStackDumpDeprecated, 260, AdspErrorInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(AdspExceptionReasonDeprecated, 261, AdspErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(OscillatorClock, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClockDeprecated, 262, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(CpuDvfsTableClocksDeprecated, 263, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(CpuDvfsTableVoltagesDeprecated, 264, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(GpuDvfsTableClocksDeprecated, 265, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ @@ -456,8 +463,8 @@ HANDLER(EmcDvfsTableClocksDeprecated, 267, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(EmcDvfsTableVoltagesDeprecated, 268, PowerClockInfo, FieldType_I32Array, FieldFlag_None ) \ HANDLER(ModuleClockFrequencies, 269, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ - HANDLER(ModuleClockEnableFlags, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(ModulePowerEnableFlags, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlagsDeprecated, 270, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlagsDeprecated, 271, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModuleResetAssertFlags, 272, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(ModuleMinimumVoltageClockRates, 273, PowerClockInfo, FieldType_U32Array, FieldFlag_None ) \ HANDLER(PowerDomainEnableFlagsDeprecated, 274, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ @@ -726,7 +733,7 @@ HANDLER(EncryptedExceptionInfo2, 537, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(EncryptedExceptionInfo3, 538, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ HANDLER(EncryptedDyingMessage, 539, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ - HANDLER(DramId, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DramIdDeprecated, 540, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NifmConnectionTestRedirectUrl, 541, NifmConnectionTestInfo, FieldType_String, FieldFlag_None ) \ HANDLER(AcpRequiredNetworkServiceLicenseOnLaunchFlag, 542, AcpUserAccountSettingsInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(PciePort0Flags, 543, PcieLoggedStateInfo, FieldType_NumericU32, FieldFlag_None ) \ @@ -881,6 +888,44 @@ HANDLER(LastConnectionTestDownloadSpeed64, 692, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(LastConnectionTestUploadSpeed64, 693, ConnectionInfo, FieldType_NumericU64, FieldFlag_None ) \ HANDLER(EncryptionKeyV1, 694, ErrorInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GpuCrashDumpAttachmentId, 695, GpuCrashInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GpuCrashDumpIsAttached, 696, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(CallerIdentifier, 697, ErrorInfo, FieldType_NumericU64, FieldFlag_None ) \ + HANDLER(WlanMainState, 698, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(WlanSubState, 699, WlanInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(AdspSyslogIsAttached, 702, AttachmentFileInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(LastHalfAwakeTime, 703, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(LastHalfAwakeTimeAfterBackgroundTaskDone, 704, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(LastHalfAwakeTimeAfterStateUnlocked, 705, HalfAwakeStateInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(LastHalfAwakePowerStateMessage, 706, HalfAwakeStateInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FastlyRequestId, 707, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(CloudflareCfRay, 708, ErrorInfo, FieldType_String, FieldFlag_None ) \ + HANDLER(WlanCommandEventHistory, 709, WlanInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(FsSaveDataAttributeCheckFailureCount, 710, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlIsRestrictionEnabled, 711, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlIsPairingActive, 712, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlSafetyLevel, 713, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlRatingAge, 714, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlRatingOrganization, 715, PctlSettingInfo, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(PctlIsSnsPostRestricted, 716, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlIsFreeCommunicationRestrictedByDefault, 717, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlIsStereoVisionRestricted, 718, PctlSettingInfo, FieldType_Bool, FieldFlag_None ) \ + HANDLER(PctlRestrictedFreeCommunicationApplicationIdList, 719, PctlSettingInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(PctlExemptApplicationIdList, 720, PctlSettingInfo, FieldType_U64Array, FieldFlag_None ) \ + HANDLER(GameCardLogEncryptionKeyIndex, 721, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLogEncryptedKey, 722, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardAsicHandlerLogLength, 723, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardWorkerLogLength, 724, GameCardLogInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardAsicHandlerLogTimeStamp, 725, GameCardLogInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardWorkerLogTimeStamp, 726, GameCardLogInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardEncryptedAsicHandlerLog, 727, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(GameCardEncryptedWorkerLog, 728, GameCardLogInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(WlanIoctlErrno, 729, ErrorInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(FsSaveDataCertificateVerificationFailureCount, 730, FsProxyErrorInfo2, FieldType_NumericU8, FieldFlag_None ) \ + HANDLER(SdCardActivationMilliSeconds, 731, SdCardActivationInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardLastAwakenFailureResult, 732, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(GameCardPreviousInsertedTimestamp, 734, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \ HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ @@ -909,5 +954,10 @@ HANDLER(BluetoothLePairingInfoCount, 1025, BluetoothPairingCountInfo, FieldType_NumericU8, FieldFlag_None ) \ HANDLER(NANDPreEolInfo, 1026, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(NANDDeviceLifeTimeEstTypA, 1027, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ - HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) + HANDLER(NANDDeviceLifeTimeEstTypB, 1028, NANDExtendedCsd, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(OscillatorClock, 1029, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(DramId, 1030, PowerClockInfo, FieldType_NumericU32, FieldFlag_None ) \ + HANDLER(LastDvfsThresholdTripped, 1031, ThermalInfo, FieldType_NumericI32, FieldFlag_None ) \ + HANDLER(ModuleClockEnableFlags, 1032, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ + HANDLER(ModulePowerEnableFlags, 1033, PowerClockInfo, FieldType_U8Array, FieldFlag_None ) \ diff --git a/utilities/erpt.py b/utilities/erpt.py index fb697cb13..a69e6e915 100644 --- a/utilities/erpt.py +++ b/utilities/erpt.py @@ -239,6 +239,13 @@ CATEGORIES = { 140 : 'NANDTypeInfo', 141 : 'MicroSDTypeInfo', 142 : 'AttachmentFileInfo', + 143 : 'WlanInfo', + 144 : 'HalfAwakeStateInfo', + 145 : 'PctlSettingInfo', + 146 : 'GameCardLogInfo', + 147 : 'WlanIoctlErrorInfo', + 148 : 'SdCardActivationInfo', + 149 : 'GameCardDetailedErrorInfo', 1000 : 'TestNx', 1001 : 'NANDTypeInfo', 1002 : 'NANDExtendedCsd', From 66fcf33a2c97ca7fa889a18dee39594a6875bbf8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 18:23:16 -0700 Subject: [PATCH 186/238] kern: invert meaning of KTargetSystem/KSystemControl bools --- .../mesosphere/kern_k_system_control_base.hpp | 2 +- .../mesosphere/kern_k_target_system.hpp | 46 +++++++++---------- .../nintendo/nx/kern_k_system_control.cpp | 22 ++++----- .../source/kern_k_system_control_base.cpp | 12 ++--- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp index ab3a18c5b..3d7ea5310 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_control_base.hpp @@ -41,7 +41,7 @@ namespace ams::kern { /* Nintendo uses std::mt19937_t for randomness. */ /* To save space (and because mt19337_t isn't secure anyway), */ /* We will use TinyMT. */ - static constinit inline bool s_initialized_random_generator; + static constinit inline bool s_uninitialized_random_generator{true}; static constinit inline util::TinyMT s_random_generator{util::ConstantInitialize}; static constinit inline KSpinLock s_random_lock; public: diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp index 24220bed0..949fd45ba 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_target_system.hpp @@ -25,35 +25,35 @@ namespace ams::kern { friend class KSystemControl; private: struct KTargetSystemData { - bool is_debug_mode; - bool enable_debug_logging; - bool enable_user_exception_handlers; - bool enable_debug_memory_fill; - bool enable_user_pmu_access; - bool enable_kernel_debugging; - bool enable_dynamic_resource_limits; + bool is_not_debug_mode; + bool disable_debug_logging; + bool disable_user_exception_handlers; + bool disable_debug_memory_fill; + bool disable_user_pmu_access; + bool disable_kernel_debugging; + bool disable_dynamic_resource_limits; }; private: - static inline constinit bool s_is_initialized = false; + static inline constinit bool s_is_uninitialized = true; static inline constinit const volatile KTargetSystemData s_data = { - .is_debug_mode = true, - .enable_debug_logging = true, - .enable_user_exception_handlers = true, - .enable_debug_memory_fill = true, - .enable_user_pmu_access = true, - .enable_kernel_debugging = true, - .enable_dynamic_resource_limits = false, + .is_not_debug_mode = false, + .disable_debug_logging = false, + .disable_user_exception_handlers = false, + .disable_debug_memory_fill = false, + .disable_user_pmu_access = false, + .disable_kernel_debugging = false, + .disable_dynamic_resource_limits = true, }; private: - static ALWAYS_INLINE void SetInitialized() { s_is_initialized = true; } + static ALWAYS_INLINE void SetInitialized() { s_is_uninitialized = false; } public: - static ALWAYS_INLINE bool IsDebugMode() { return s_is_initialized && s_data.is_debug_mode; } - static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return s_is_initialized && s_data.enable_debug_logging; } - static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return s_is_initialized && s_data.enable_user_exception_handlers; } - static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return s_is_initialized && s_data.enable_debug_memory_fill; } - static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return s_is_initialized && s_data.enable_user_pmu_access; } - static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return s_is_initialized && s_data.enable_kernel_debugging; } - static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return s_is_initialized && s_data.enable_dynamic_resource_limits; } + static ALWAYS_INLINE bool IsDebugMode() { return !(s_is_uninitialized | s_data.is_not_debug_mode); } + static ALWAYS_INLINE bool IsDebugLoggingEnabled() { return !(s_is_uninitialized | s_data.disable_debug_logging); } + static ALWAYS_INLINE bool IsUserExceptionHandlersEnabled() { return !(s_is_uninitialized | s_data.disable_user_exception_handlers); } + static ALWAYS_INLINE bool IsDebugMemoryFillEnabled() { return !(s_is_uninitialized | s_data.disable_debug_memory_fill); } + static ALWAYS_INLINE bool IsUserPmuAccessEnabled() { return !(s_is_uninitialized | s_data.disable_user_pmu_access); } + static ALWAYS_INLINE bool IsKernelDebuggingEnabled() { return !(s_is_uninitialized | s_data.disable_kernel_debugging); } + static ALWAYS_INLINE bool IsDynamicResourceLimitsEnabled() { return !(s_is_uninitialized | s_data.disable_dynamic_resource_limits); } }; } \ No newline at end of file diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index b82518e6e..22e99faf0 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -405,22 +405,22 @@ namespace ams::kern::board::nintendo::nx { /* Configure KTargetSystem. */ volatile auto *ts = const_cast(std::addressof(KTargetSystem::s_data)); { - /* Set IsDebugMode. */ + /* Set whether we're in debug mode. */ { - ts->is_debug_mode = GetConfigBool(smc::ConfigItem::IsDebugMode); + ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode); - /* If debug mode, we want to initialize uart logging. */ - ts->enable_debug_logging = ts->is_debug_mode; + /* If we're not in debug mode, we don't want to initialize uart logging. */ + ts->disable_debug_logging = ts->is_not_debug_mode; } /* Set Kernel Configuration. */ { const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)}; - ts->enable_debug_memory_fill = kernel_config.Get(); - ts->enable_user_exception_handlers = kernel_config.Get(); - ts->enable_dynamic_resource_limits = !kernel_config.Get(); - ts->enable_user_pmu_access = kernel_config.Get(); + ts->disable_debug_memory_fill = !kernel_config.Get(); + ts->disable_user_exception_handlers = !kernel_config.Get(); + ts->disable_dynamic_resource_limits = kernel_config.Get(); + ts->disable_user_pmu_access = !kernel_config.Get(); /* Configure call smc on panic. */ *const_cast(std::addressof(g_call_smc_on_panic)) = kernel_config.Get(); @@ -430,7 +430,7 @@ namespace ams::kern::board::nintendo::nx { { /* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */ /* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */ - ts->enable_kernel_debugging = GetConfigBool(smc::ConfigItem::DisableProgramVerification); + ts->disable_kernel_debugging = !GetConfigBool(smc::ConfigItem::DisableProgramVerification); } } } @@ -524,7 +524,7 @@ namespace ams::kern::board::nintendo::nx { KScopedSpinLock lk(s_random_lock); - if (AMS_LIKELY(s_initialized_random_generator)) { + if (AMS_LIKELY(!s_uninitialized_random_generator)) { return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); } else { return KSystemControlBase::GenerateUniformRange(min, max, GenerateRandomU64FromSmc); @@ -535,7 +535,7 @@ namespace ams::kern::board::nintendo::nx { KScopedInterruptDisable intr_disable; KScopedSpinLock lk(s_random_lock); - if (AMS_LIKELY(s_initialized_random_generator)) { + if (AMS_LIKELY(!s_uninitialized_random_generator)) { return s_random_generator.GenerateRandomU64(); } else { return GenerateRandomU64FromSmc(); diff --git a/libraries/libmesosphere/source/kern_k_system_control_base.cpp b/libraries/libmesosphere/source/kern_k_system_control_base.cpp index 025ec4f9c..dece074ef 100644 --- a/libraries/libmesosphere/source/kern_k_system_control_base.cpp +++ b/libraries/libmesosphere/source/kern_k_system_control_base.cpp @@ -102,10 +102,10 @@ namespace ams::kern { /* Randomness for Initialization. */ void KSystemControlBase::Init::GenerateRandom(u64 *dst, size_t count) { - if (AMS_UNLIKELY(!s_initialized_random_generator)) { + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { const u64 seed = KHardwareTimer::GetTick(); s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_initialized_random_generator = true; + s_uninitialized_random_generator = false; } for (size_t i = 0; i < count; ++i) { @@ -114,10 +114,10 @@ namespace ams::kern { } u64 KSystemControlBase::Init::GenerateRandomRange(u64 min, u64 max) { - if (AMS_UNLIKELY(!s_initialized_random_generator)) { + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { const u64 seed = KHardwareTimer::GetTick(); s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_initialized_random_generator = true; + s_uninitialized_random_generator = false; } return KSystemControlBase::GenerateUniformRange(min, max, []() ALWAYS_INLINE_LAMBDA -> u64 { return s_random_generator.GenerateRandomU64(); }); @@ -140,9 +140,9 @@ namespace ams::kern { void KSystemControlBase::InitializePhase1Base(u64 seed) { /* Initialize the rng, if we somehow haven't already. */ - if (AMS_UNLIKELY(!s_initialized_random_generator)) { + if (AMS_UNLIKELY(s_uninitialized_random_generator)) { s_random_generator.Initialize(reinterpret_cast(std::addressof(seed)), sizeof(seed) / sizeof(u32)); - s_initialized_random_generator = true; + s_uninitialized_random_generator = false; } /* Initialize debug logging. */ From 3e19e4d004755f94aeb4dc8fce6c98455e68e2a9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 18:56:47 -0700 Subject: [PATCH 187/238] kern: update KAddressSpaceInfo to reflect 20.0.0 changes --- .../mesosphere/kern_k_address_space_info.hpp | 2 +- .../source/kern_k_address_space_info.cpp | 31 +++++++++++++++++-- .../source/kern_k_initial_process_reader.cpp | 5 ++- .../source/kern_k_page_table_base.cpp | 8 +---- .../libmesosphere/source/kern_k_process.cpp | 2 +- .../source/svc/kern_svc_process.cpp | 8 ++--- 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp index 8af8404cc..775c0054c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_address_space_info.hpp @@ -37,7 +37,7 @@ namespace ams::kern { size_t m_size; Type m_type; public: - static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type); + static uintptr_t GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, Type type, size_t code_size); static size_t GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, Type type); static void SetAddressSpaceSize(size_t width, Type type, size_t size); diff --git a/libraries/libmesosphere/source/kern_k_address_space_info.cpp b/libraries/libmesosphere/source/kern_k_address_space_info.cpp index b23f6e929..3aa24c5de 100644 --- a/libraries/libmesosphere/source/kern_k_address_space_info.cpp +++ b/libraries/libmesosphere/source/kern_k_address_space_info.cpp @@ -66,12 +66,39 @@ namespace ams::kern { } - uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { + uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type, size_t code_size) { + MESOSPHERE_UNUSED(code_size); return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetAddress(); } size_t KAddressSpaceInfo::GetAddressSpaceSize(ams::svc::CreateProcessFlag flags, KAddressSpaceInfo::Type type) { - return GetAddressSpaceInfo(GetAddressSpaceWidth(flags), type).GetSize(); + /* Extract the address space from the create process flags. */ + const auto as_flags = (flags & ams::svc::CreateProcessFlag_AddressSpaceMask); + + /* Get the address space width. */ + const auto as_width = GetAddressSpaceWidth(flags); + + /* Get the size. */ + size_t as_size = GetAddressSpaceInfo(as_width, type).GetSize(); + + /* If we're getting size for 32-bit without alias, adjust the sizes accordingly. */ + if (as_flags == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { + switch (type) { + /* The heap space receives space that would otherwise go to the alias space. */ + case KAddressSpaceInfo::Type_Heap: + as_size += GetAddressSpaceInfo(as_width, KAddressSpaceInfo::Type_Alias).GetSize(); + break; + /* The alias space doesn't exist. */ + case KAddressSpaceInfo::Type_Alias: + as_size = 0; + break; + /* Nothing to do by default. */ + default: + break; + } + } + + return as_size; } void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) { diff --git a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp index 9c91889f9..5d9164efb 100644 --- a/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp +++ b/libraries/libmesosphere/source/kern_k_initial_process_reader.cpp @@ -229,9 +229,12 @@ namespace ams::kern { out->flags |= ams::svc::CreateProcessFlag_DisableDeviceAddressSpaceMerge; /* Set and check code address. */ + /* NOTE: Even though Nintendo passes a size to GetAddressSpaceStart at other call sites, they pass */ + /* a number of pages here. Even though this is presumably only used for debug assertions, this is */ + /* almost certainly a bug. */ using ASType = KAddressSpaceInfo::Type; const ASType as_type = this->Is64BitAddressSpace() ? ((GetTargetFirmware() >= TargetFirmware_2_0_0) ? KAddressSpaceInfo::Type_Map39Bit : KAddressSpaceInfo::Type_MapSmall) : KAddressSpaceInfo::Type_MapSmall; - const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(out->flags), as_type); + const uintptr_t map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(out->flags), as_type, out->code_num_pages); const size_t map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(out->flags), as_type); const uintptr_t map_end = map_start + map_size; out->code_address = map_start + start_address; diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 4ebaad0bd..d7068a763 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -141,7 +141,7 @@ namespace ams::kern { /* Define helpers. */ auto GetSpaceStart = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { - return KAddressSpaceInfo::GetAddressSpaceStart(flags, type); + return KAddressSpaceInfo::GetAddressSpaceStart(flags, type, code_size); }; auto GetSpaceSize = [&](KAddressSpaceInfo::Type type) ALWAYS_INLINE_LAMBDA { return KAddressSpaceInfo::GetAddressSpaceSize(flags, type); @@ -155,12 +155,6 @@ namespace ams::kern { size_t alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Alias); size_t heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type_Heap); - /* Adjust heap/alias size if we don't have an alias region. */ - if ((flags & ams::svc::CreateProcessFlag_AddressSpaceMask) == ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias) { - heap_region_size += alias_region_size; - alias_region_size = 0; - } - /* Set code regions and determine remaining sizes. */ KProcessAddress process_code_start; KProcessAddress process_code_end; diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 19a9fd85e..08a79f5c0 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -221,7 +221,7 @@ namespace ams::kern { } /* Set max memory. */ - m_max_process_memory = m_page_table.GetHeapRegionSize(); + m_max_process_memory = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(m_flags), KAddressSpaceInfo::Type_Heap); /* Generate random entropy. */ KSystemControl::GenerateRandom(m_entropy, util::size(m_entropy)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_process.cpp b/libraries/libmesosphere/source/svc/kern_svc_process.cpp index 27ff14b4f..6e516a51f 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_process.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_process.cpp @@ -109,11 +109,12 @@ namespace ams::kern::svc { /* Decide on an address space map region. */ uintptr_t map_start, map_end; size_t map_size; + const size_t code_size = params.code_num_pages * PageSize; switch (params.flags & ams::svc::CreateProcessFlag_AddressSpaceMask) { case ams::svc::CreateProcessFlag_AddressSpace32Bit: case ams::svc::CreateProcessFlag_AddressSpace32BitWithoutAlias: { - map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } @@ -123,7 +124,7 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall, code_size); map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_MapSmall); map_end = map_start + map_size; } @@ -133,7 +134,7 @@ namespace ams::kern::svc { /* 64-bit address space requires 64-bit process. */ R_UNLESS(is_64_bit, svc::ResultInvalidCombination()); - map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit); + map_start = KAddressSpaceInfo::GetAddressSpaceStart(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit, code_size); map_end = map_start + KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Map39Bit); map_size = KAddressSpaceInfo::GetAddressSpaceSize(static_cast(params.flags), KAddressSpaceInfo::Type_Heap); @@ -181,7 +182,6 @@ namespace ams::kern::svc { const size_t code_num_pages = params.code_num_pages; const size_t system_resource_num_pages = params.system_resource_num_pages; const size_t total_pages = code_num_pages + system_resource_num_pages; - const size_t code_size = code_num_pages * PageSize; const size_t system_resource_size = system_resource_num_pages * PageSize; const size_t total_size = code_size + system_resource_size; From 4c5c5c85e3cff661a1a7df2e7524795ccafa6ed3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 19:15:23 -0700 Subject: [PATCH 188/238] kern: update crt0 to reflect 20.0.0 changes --- .../kernel/source/arch/arm64/init/start.s | 123 ++++++++++-------- 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index 5d9084b08..ad483ffc2 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -112,6 +112,14 @@ _ZN3ams4kern4init10StartCore0Emm: #endif 2: /* We're EL1. */ + /* Flush the entire data cache and invalidate the entire TLB. */ + bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv + + /* Invalidate the instruction cache, and ensure instruction consistency. */ + ic ialluis + dsb sy + isb + /* Disable the MMU/Caches. */ bl _ZN3ams4kern4init19DisableMmuAndCachesEv @@ -146,11 +154,15 @@ _ZN3ams4kern4init10StartCore0Emm: /* Save the offset to virtual address from this page's physical address for our use. */ mov x24, x1 + /* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */ + mov x18, #0 + /* At this point kernelldr has been invoked, and we are relocated at a random virtual address. */ /* Next thing to do is to set up our memory management and slabheaps -- all the other core initialization. */ /* Call ams::kern::init::InitializeCore(uintptr_t, void **) */ mov x1, x0 /* Kernelldr returns a state object for the kernel to re-use. */ mov x0, x21 /* Use the address we determined earlier. */ + nop INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase1EmPPv) /* Get the init arguments for core 0. */ @@ -164,6 +176,7 @@ _ZN3ams4kern4init10StartCore0Emm: /* Perform further initialization with the stack pointer set up, as required. */ /* This will include e.g. unmapping the identity mapping. */ + nop INDIRECT_RELATIVE_CALL(x16, x24, _ZN3ams4kern4init20InitializeCorePhase2Ev) /* Get the init arguments for core 0. */ @@ -220,6 +233,14 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: #endif 2: /* We're EL1. */ + /* Flush the entire data cache and invalidate the entire TLB. */ + bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv + + /* Invalidate the instruction cache, and ensure instruction consistency. */ + ic ialluis + dsb sy + isb + /* Disable the MMU/Caches. */ bl _ZN3ams4kern4init19DisableMmuAndCachesEv @@ -241,6 +262,7 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: b.eq 3f b 4f 3: /* We're running on a Cortex-A53/Cortex-A57. */ + /* NOTE: Nintendo compares these values instead of setting them, infinite looping on incorrect value. */ ldr x1, [x20, #(INIT_ARGUMENTS_CPUACTLR)] msr cpuactlr_el1, x1 ldr x1, [x20, #(INIT_ARGUMENTS_CPUECTLR)] @@ -265,6 +287,9 @@ _ZN3ams4kern4init14StartOtherCoreEPKNS1_14KInitArgumentsE: /* Set the stack pointer. */ mov sp, x2 + /* Clear the platform register (used for Kernel::GetCurrentThreadPointer()) */ + mov x18, #0 + /* Invoke the entrypoint. */ blr x1 @@ -388,14 +413,6 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv: /* The stack isn't set up, so we'll need to trash a register. */ mov x22, x30 - /* Flush the entire data cache and invalidate the entire TLB. */ - bl _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv - - /* Invalidate the instruction cache, and ensure instruction consistency. */ - ic ialluis - dsb sy - isb - /* Set SCTLR_EL1 to disable the caches and mmu. */ /* SCTLR_EL1: */ /* - M = 0 */ @@ -413,27 +430,44 @@ _ZN3ams4kern4init19DisableMmuAndCachesEv: mov x30, x22 ret -/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */ -.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits -.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv -.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function -_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv: +/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */ +.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits +.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv +.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function +_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv: /* The stack isn't set up, so we'll need to trash a register. */ - mov x23, x30 + mov x24, x30 - /* Ensure that the cache is coherent. */ - bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv + /* CacheLineIdAccessor clidr_el1; */ + mrs x10, clidr_el1 + /* const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency(); */ + ubfx x9, x10, #0x15, 3 + /* const int levels_of_unification = clidr_el1.GetLevelsOfUnification(); */ + ubfx x10, x10, #0x18, 3 - bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv + /* int level = levels_of_unification */ - bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv + /* while (level <= levels_of_coherency) { */ + cmp w9, w10 + b.hi 1f - /* Invalidate the entire TLB, and ensure instruction consistency. */ - tlbi vmalle1is +0: + /* FlushEntireDataCacheImplWithoutStack(level); */ + mov w0, w9 + bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv + + /* level++; */ + cmp w9, w10 + add w9, w9, #1 + + /* } */ + b.cc 0b + + /* cpu::DataSynchronizationBarrier(); */ dsb sy - isb - mov x30, x23 +1: + mov x30, x24 ret /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheLocalWithoutStack() */ @@ -475,44 +509,27 @@ _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv: mov x30, x24 ret -/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheSharedWithoutStack() */ -.section .crt0.text._ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, "ax", %progbits -.global _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv -.type _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv, %function -_ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv: +/* ams::kern::arch::arm64::cpu::FlushEntireDataCacheWithoutStack() */ +.section .crt0.text._ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, "ax", %progbits +.global _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv +.type _ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv, %function +_ZN3ams4kern4arch5arm643cpu32FlushEntireDataCacheWithoutStackEv: /* The stack isn't set up, so we'll need to trash a register. */ - mov x24, x30 + mov x23, x30 - /* CacheLineIdAccessor clidr_el1; */ - mrs x10, clidr_el1 - /* const int levels_of_coherency = clidr_el1.GetLevelsOfCoherency(); */ - ubfx x9, x10, #0x15, 3 - /* const int levels_of_unification = clidr_el1.GetLevelsOfUnification(); */ - ubfx x10, x10, #0x18, 3 + /* Ensure that the cache is coherent. */ + bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv - /* int level = levels_of_unification */ + bl _ZN3ams4kern4arch5arm643cpu38FlushEntireDataCacheSharedWithoutStackEv - /* while (level <= levels_of_coherency) { */ - cmp w9, w10 - b.hi 1f + bl _ZN3ams4kern4arch5arm643cpu37FlushEntireDataCacheLocalWithoutStackEv -0: - /* FlushEntireDataCacheImplWithoutStack(level); */ - mov w0, w9 - bl _ZN3ams4kern4arch5arm643cpu36FlushEntireDataCacheImplWithoutStackEv - - /* level++; */ - cmp w9, w10 - add w9, w9, #1 - - /* } */ - b.cc 0b - - /* cpu::DataSynchronizationBarrier(); */ + /* Invalidate the entire TLB, and ensure instruction consistency. */ + tlbi vmalle1is dsb sy + isb -1: - mov x30, x24 + mov x30, x23 ret /* ams::kern::arch::arm64::cpu::FlushEntireDataCacheImplWithoutStack() */ From 98e5bd4411412b3ff5598821413a121811a13a07 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 19:33:49 -0700 Subject: [PATCH 189/238] kern: update UserspaceAccess functions for 20.0.0 changes --- .../arm64/kern_userspace_memory_access.hpp | 148 ++++++-- .../arm64/kern_userspace_memory_access_asm.s | 356 +++++++----------- 2 files changed, 246 insertions(+), 258 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp index 6afabe51c..17c6c6a44 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_userspace_memory_access.hpp @@ -22,49 +22,139 @@ namespace ams::kern::arch::arm64 { class UserspaceAccess { private: - static bool CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src); + class Impl { + public: + static bool CopyMemoryFromUser(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src); + static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src); + static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src); + static s32 CopyStringFromUser(void *dst, const void *src, size_t size); + + static bool CopyMemoryToUser(void *dst, const void *src, size_t size); + static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size); + static bool CopyMemoryToUserSize32Bit(void *dst, const void *src); + static s32 CopyStringToUser(void *dst, const void *src, size_t size); + + static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask); + static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value); + static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare); + + static bool StoreDataCache(uintptr_t start, uintptr_t end); + static bool FlushDataCache(uintptr_t start, uintptr_t end); + static bool InvalidateDataCache(uintptr_t start, uintptr_t end); + + static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size); + static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size); + static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size); + static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size); + static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size); + static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size); + }; public: + static bool CopyMemoryFromUser(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryFromUser(dst, src, size); + } + + static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryFromUserAligned32Bit(dst, src, size); + } + + static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryFromUserAligned64Bit(dst, src, size); + } + + static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src) { + return Impl::CopyMemoryFromUserSize64Bit(dst, src); + } + + static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src) { + return Impl::CopyMemoryFromUserSize32Bit(dst, src); + } + + static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) { /* Check that the address is within the valid userspace range. */ if (const uintptr_t src_uptr = reinterpret_cast(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) { return false; } - return CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(dst, src); + return Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(dst, src); } - static bool CopyMemoryFromUser(void *dst, const void *src, size_t size); - static bool CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryFromUserSize64Bit(void *dst, const void *src); - static bool CopyMemoryFromUserSize32Bit(void *dst, const void *src); - static s32 CopyStringFromUser(void *dst, const void *src, size_t size); + static s32 CopyStringFromUser(void *dst, const void *src, size_t size) { + return Impl::CopyStringFromUser(dst, src, size); + } - static bool CopyMemoryToUser(void *dst, const void *src, size_t size); - static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size); - static bool CopyMemoryToUserSize32Bit(void *dst, const void *src); - static s32 CopyStringToUser(void *dst, const void *src, size_t size); + static bool CopyMemoryToUser(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryToUser(dst, src, size); + } - static bool ClearMemory(void *dst, size_t size); - static bool ClearMemoryAligned32Bit(void *dst, size_t size); - static bool ClearMemoryAligned64Bit(void *dst, size_t size); - static bool ClearMemorySize32Bit(void *dst); + static bool CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryToUserAligned32Bit(dst, src, size); + } - static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask); - static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value); - static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare); + static bool CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) { + return Impl::CopyMemoryToUserAligned64Bit(dst, src, size); + } - static bool StoreDataCache(uintptr_t start, uintptr_t end); - static bool FlushDataCache(uintptr_t start, uintptr_t end); - static bool InvalidateDataCache(uintptr_t start, uintptr_t end); + static bool CopyMemoryToUserSize32Bit(void *dst, const void *src) { + return Impl::CopyMemoryToUserSize32Bit(dst, src); + } - static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size); - static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size); - static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size); - static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size); - static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size); - static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size); + static s32 CopyStringToUser(void *dst, const void *src, size_t size) { + return Impl::CopyStringToUser(dst, src, size); + } + + static bool UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) { + return Impl::UpdateLockAtomic(out, address, if_zero, new_orr_mask); + } + + static bool UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) { + return Impl::UpdateIfEqualAtomic(out, address, compare_value, new_value); + } + + static bool DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) { + return Impl::DecrementIfLessThanAtomic(out, address, compare); + } + + static bool StoreDataCache(uintptr_t start, uintptr_t end) { + return Impl::StoreDataCache(start, end); + } + + static bool FlushDataCache(uintptr_t start, uintptr_t end) { + return Impl::FlushDataCache(start, end); + } + + static bool InvalidateDataCache(uintptr_t start, uintptr_t end) { + return Impl::InvalidateDataCache(start, end); + } + + static bool ReadIoMemory32Bit(void *dst, const void *src, size_t size) { + return Impl::ReadIoMemory32Bit(dst, src, size); + } + + static bool ReadIoMemory16Bit(void *dst, const void *src, size_t size) { + return Impl::ReadIoMemory16Bit(dst, src, size); + } + + static bool ReadIoMemory8Bit(void *dst, const void *src, size_t size) { + return Impl::ReadIoMemory8Bit(dst, src, size); + } + + static bool WriteIoMemory32Bit(void *dst, const void *src, size_t size) { + return Impl::WriteIoMemory32Bit(dst, src, size); + } + + static bool WriteIoMemory16Bit(void *dst, const void *src, size_t size) { + return Impl::WriteIoMemory16Bit(dst, src, size); + } + + static bool WriteIoMemory8Bit(void *dst, const void *src, size_t size) { + return Impl::WriteIoMemory8Bit(dst, src, size); + } }; diff --git a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s index 01104deb9..1d9d2c5da 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s +++ b/libraries/libmesosphere/source/arch/arm64/kern_userspace_memory_access_asm.s @@ -24,12 +24,12 @@ _ZN3ams4kern4arch5arm6432UserspaceAccessFunctionAreaBeginEv: /* ================ All Userspace Access Functions after this line. ================ */ -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyMemoryFromUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 2f @@ -48,12 +48,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyMemoryFromUserEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserAligned32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -72,7 +72,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned32BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -87,12 +87,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned32BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserAligned64Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -111,7 +111,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl30CopyMemoryFromUserAligned64BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -126,12 +126,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess30CopyMemoryFromUserAligned64BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize64Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize64BitEPvPKv: /* Just load and store a u64. */ ldtr x2, [x1] str x2, [x0] @@ -140,12 +140,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize64BitEPvPKv: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl27CopyMemoryFromUserSize32BitEPvPKv: /* Just load and store a u32. */ ldtr w2, [x1] str w2, [x0] @@ -154,12 +154,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess27CopyMemoryFromUserSize32BitEPvPKv: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryFromUserSize32BitWithSupervisorAccessImpl(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervisorAccessImplEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl47CopyMemoryFromUserSize32BitWithSupervisorAccessEPvPKv: /* Just load and store a u32. */ /* NOTE: This is done with supervisor access permissions. */ ldr w2, [x1] @@ -169,12 +169,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess51CopyMemoryFromUserSize32BitWithSupervi mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyStringFromUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyStringFromUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18CopyStringFromUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 3f @@ -204,12 +204,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18CopyStringFromUserEPvPKvm: mov x0, #0 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyMemoryToUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 2f @@ -228,12 +228,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyMemoryToUserEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserAligned32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -252,7 +252,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned32BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -267,12 +267,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned32BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserAligned64Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm: /* Check if there are 0x40 bytes to copy */ cmp x2, #0x3F b.ls 1f @@ -291,7 +291,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: add x0, x0, #0x40 add x1, x1, #0x40 sub x2, x2, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm + b _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl28CopyMemoryToUserAligned64BitEPvPKvm 1: /* We have less than 0x40 bytes to copy. */ cmp x2, #0 @@ -306,12 +306,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess28CopyMemoryToUserAligned64BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyMemoryToUserSize32Bit(void *dst, const void *src) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyMemoryToUserSize32Bit(void *dst, const void *src) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25CopyMemoryToUserSize32BitEPvPKv: /* Just load and store a u32. */ ldr w2, [x1] sttr w2, [x0] @@ -320,12 +320,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess25CopyMemoryToUserSize32BitEPvPKv: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::CopyStringToUser(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::CopyStringToUser(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16CopyStringToUserEPvPKvm: /* Check if there's anything to copy. */ cmp x2, #0 b.eq 3f @@ -355,114 +355,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16CopyStringToUserEPvPKvm: mov x0, #0 ret -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemory(void *dst, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess11ClearMemoryEPvm: - /* Check if there's anything to clear. */ - cmp x1, #0 - b.eq 2f - - /* Keep track of the last address. */ - add x2, x0, x1 - -1: /* We're copying memory byte-by-byte. */ - sttrb wzr, [x0] - add x0, x0, #1 - cmp x0, x2 - b.ne 1b - -2: /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemoryAligned32Bit(void *dst, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm: - /* Check if there are 0x40 bytes to clear. */ - cmp x1, #0x3F - b.ls 2f - sttr xzr, [x0, #0x00] - sttr xzr, [x0, #0x08] - sttr xzr, [x0, #0x10] - sttr xzr, [x0, #0x18] - sttr xzr, [x0, #0x20] - sttr xzr, [x0, #0x28] - sttr xzr, [x0, #0x30] - sttr xzr, [x0, #0x38] - add x0, x0, #0x40 - sub x1, x1, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned32BitEPvm - -1: /* We have less than 0x40 bytes to clear. */ - cmp x1, #0 - b.eq 2f - sttr wzr, [x0] - add x0, x0, #4 - sub x1, x1, #4 - b 1b - -2: /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemoryAligned64Bit(void *dst, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm: - /* Check if there are 0x40 bytes to clear. */ - cmp x1, #0x3F - b.ls 2f - sttr xzr, [x0, #0x00] - sttr xzr, [x0, #0x08] - sttr xzr, [x0, #0x10] - sttr xzr, [x0, #0x18] - sttr xzr, [x0, #0x20] - sttr xzr, [x0, #0x28] - sttr xzr, [x0, #0x30] - sttr xzr, [x0, #0x38] - add x0, x0, #0x40 - sub x1, x1, #0x40 - b _ZN3ams4kern4arch5arm6415UserspaceAccess23ClearMemoryAligned64BitEPvm - -1: /* We have less than 0x40 bytes to clear. */ - cmp x1, #0 - b.eq 2f - sttr xzr, [x0] - add x0, x0, #8 - sub x1, x1, #8 - b 1b - -2: /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::ClearMemorySize32Bit(void *dst) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv -.type _ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess20ClearMemorySize32BitEPv: - /* Just store a zero. */ - sttr wzr, [x0] - - /* We're done. */ - mov x0, #1 - ret - -/* ams::kern::arch::arm64::UserspaceAccess::UpdateLockAtomic(u32 *out, u32 *address, u32 if_zero, u32 new_orr_mask) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj, %function -.balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj: /* Load the value from the address. */ ldaxr w4, [x1] @@ -477,7 +375,7 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj: stlxr w6, w5, [x1] /* If we failed to store, try again. */ - cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj + cbnz w6, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16UpdateLockAtomicEPjS5_jj /* We're done. */ str w4, [x0] @@ -485,12 +383,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16UpdateLockAtomicEPjS4_jj: ret -/* ams::kern::arch::arm64::UserspaceAccess::UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii -.type _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::UpdateIfEqualAtomic(s32 *out, s32 *address, s32 compare_value, s32 new_value) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii: /* Load the value from the address. */ ldaxr w4, [x1] @@ -508,19 +406,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii: stlxr w5, w3, [x1] /* If we failed to store, try again. */ - cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess19UpdateIfEqualAtomicEPiS4_ii + cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19UpdateIfEqualAtomicEPiS5_ii 2: /* We're done. */ str w4, [x0] mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i -.type _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::DecrementIfLessThanAtomic(s32 *out, s32 *address, s32 compare) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i: /* Load the value from the address. */ ldaxr w3, [x1] @@ -539,19 +437,19 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i: stlxr w5, w4, [x1] /* If we failed to store, try again. */ - cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess25DecrementIfLessThanAtomicEPiS4_i + cbnz w5, _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl25DecrementIfLessThanAtomicEPiS5_i 2: /* We're done. */ str w3, [x0] mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::StoreDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::StoreDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14StoreDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -566,12 +464,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess14StoreDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::FlushDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::FlushDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl14FlushDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -586,12 +484,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess14FlushDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::InvalidateDataCache(uintptr_t start, uintptr_t end) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::InvalidateDataCache(uintptr_t start, uintptr_t end) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl19InvalidateDataCacheEmm: /* Check if we have any work to do. */ cmp x1, x0 b.eq 2f @@ -606,12 +504,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess19InvalidateDataCacheEmm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory32BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -656,12 +554,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory32BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory16Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17ReadIoMemory16BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -706,12 +604,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess17ReadIoMemory16BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* ams::kern::arch::arm64::UserspaceAccess::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::ReadIoMemory8Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl16ReadIoMemory8BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -756,12 +654,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess16ReadIoMemory8BitEPvPKvm: mov w9, #0xFFFFFFFF b 2b -/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory32Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory32BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -801,12 +699,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory32BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory16Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl18WriteIoMemory16BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f @@ -846,12 +744,12 @@ _ZN3ams4kern4arch5arm6415UserspaceAccess18WriteIoMemory16BitEPvPKvm: mov x0, #1 ret -/* ams::kern::arch::arm64::UserspaceAccess::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */ -.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, "ax", %progbits -.global _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm -.type _ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm, %function +/* ams::kern::arch::arm64::UserspaceAccess::Impl::WriteIoMemory8Bit(void *dst, const void *src, size_t size) */ +.section .text._ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm, "ax", %progbits +.global _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm +.type _ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm, %function .balign 0x10 -_ZN3ams4kern4arch5arm6415UserspaceAccess17WriteIoMemory8BitEPvPKvm: +_ZN3ams4kern4arch5arm6415UserspaceAccess4Impl17WriteIoMemory8BitEPvPKvm: /* Check if we have any work to do. */ cmp x2, #0 b.eq 3f From b27999a116553c4c4accabdbd928964f89a10403 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 19:57:45 -0700 Subject: [PATCH 190/238] kern: adjust system registers during exception handling on MTE-violation or kernel address fault --- .../arch/arm64/kern_exception_handlers.cpp | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index 0fc25c741..b745d5ab3 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -109,12 +109,28 @@ namespace ams::kern::arch::arm64 { return insn; } - void HandleUserException(KExceptionContext *context, u64 esr, u64 far, u64 afsr0, u64 afsr1, u32 data) { + void HandleUserException(KExceptionContext *context, u64 raw_esr, u64 raw_far, u64 afsr0, u64 afsr1, u32 data) { + /* Pre-process exception registers as needed. */ + u64 esr = raw_esr; + u64 far = raw_far; + const u64 ec = (esr >> 26) & 0x3F; + if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) { + /* Adjust registers if a memory tagging exception has occurred. */ + /* TODO: How would we perform this check using named register accesses? */ + if ((esr & 0x43F) == 0x410) { + /* Clear the faulting register on memory tagging exception. */ + far = 0; + } else { + /* If the faulting address is a kernel address, set ISFC = 4. */ + if (far >= ams::svc::AddressMemoryRegion39Size) { + esr = (esr & 0xFFFFFFC0) | 4; + } + } + } + KProcess &cur_process = GetCurrentProcess(); bool should_process_user_exception = KTargetSystem::IsUserExceptionHandlersEnabled(); - const u64 ec = (esr >> 26) & 0x3F; - /* In the event that we return from this exception, we want SPSR.SS set so that we advance an instruction if single-stepping. */ #if defined(MESOSPHERE_ENABLE_HARDWARE_SINGLE_STEP) context->psr |= (1ul << 21); @@ -165,7 +181,7 @@ namespace ams::kern::arch::arm64 { } /* Save the debug parameters to the current thread. */ - GetCurrentThread().SaveDebugParams(far, esr, data); + GetCurrentThread().SaveDebugParams(raw_far, raw_esr, data); /* Get the exception type. */ u32 type; @@ -387,7 +403,6 @@ namespace ams::kern::arch::arm64 { ams::svc::aarch32::ExceptionInfo info32; } info = {}; - const bool is_aarch64 = (e_ctx->psr & 0x10) == 0; if (is_aarch64) { /* We're 64-bit. */ @@ -432,9 +447,25 @@ namespace ams::kern::arch::arm64 { uintptr_t far, esr, data; GetCurrentThread().RestoreDebugParams(std::addressof(far), std::addressof(esr), std::addressof(data)); + /* Pre-process exception registers as needed. */ + const u64 ec = (esr >> 26) & 0x3F; + if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) { + /* Adjust registers if a memory tagging exception has occurred. */ + /* TODO: How would we perform this check using named register accesses? */ + if ((esr & 0x43F) == 0x410) { + /* Clear the faulting register on memory tagging exception. */ + far = 0; + } else { + /* If the faulting address is a kernel address, set ISFC = 4. */ + if (far >= ams::svc::AddressMemoryRegion39Size) { + esr = (esr & 0xFFFFFFC0) | 4; + } + } + } + /* Collect additional information based on the ec. */ uintptr_t params[3] = {}; - switch ((esr >> 26) & 0x3F) { + switch (ec) { case EsrEc_Unknown: case EsrEc_IllegalExecution: case EsrEc_BkptInstruction: From 2e204ccbafa2f77934ff1b625fcc0d84b032c09b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 20:05:25 -0700 Subject: [PATCH 191/238] kern: update synchronous exception handlers to assume FAR validity on TLB conflict --- .../arch/arm64/kern_exception_handlers_asm.s | 30 ++----------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s index a3a877b7e..5a6b3e7ca 100644 --- a/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s +++ b/mesosphere/kernel/source/arch/arm64/kern_exception_handlers_asm.s @@ -354,21 +354,12 @@ _ZN3ams4kern4arch5arm6430EL0SynchronousExceptionHandlerEv: mrs x17, ttbr0_el1 and x17, x17, #(0xFFFF << 48) - /* Check if FAR is valid by examining the FnV bit. */ - tbnz x16, #10, 8f - - /* FAR is valid, so we can invalidate the address it holds. */ + /* Invalidate the address held by FAR (and assume it is valid). */ mrs x16, far_el1 lsr x16, x16, #12 orr x17, x16, x17 tlbi vae1, x17 - b 9f -8: /* There's a TLB conflict and FAR isn't valid. */ - /* Invalidate the entire TLB. */ - tlbi aside1, x17 - -9: /* Return from a TLB conflict. */ /* Ensure instruction consistency. */ dsb ish isb @@ -485,33 +476,16 @@ _ZN3ams4kern4arch5arm6430EL1SynchronousExceptionHandlerEv: b 3b 4: /* Check if there's a TLB conflict that caused the abort. */ - /* NOTE: There is a Nintendo bug in this code that we correct. */ - /* Nintendo compares the low 6 bits of x0 without restoring the value. */ - /* They intend to check the DFSC/IFSC bits of esr_el1, but because they */ - /* shifted esr earlier, the check is invalid and always fails. */ mrs x0, esr_el1 and x0, x0, #0x3F cmp x0, #0x30 b.ne 1b - /* Check if FAR is valid by examining the FnV bit. */ - /* NOTE: Nintendo again has a bug here, the same as above. */ - /* They do not refresh the value of x0, and again compare with */ - /* the relevant bit already masked out of x0. */ - mrs x0, esr_el1 - tbnz x0, #10, 5f - - /* FAR is valid, so we can invalidate the address it holds. */ + /* Invalidate the address held by FAR (and assume it is valid). */ mrs x0, far_el1 lsr x0, x0, #12 tlbi vaae1, x0 - b 6f -5: /* There's a TLB conflict and FAR isn't valid. */ - /* Invalidate the entire TLB. */ - tlbi vmalle1 - -6: /* Return from a TLB conflict. */ /* Ensure instruction consistency. */ dsb ish isb From 86e4bed056ea3084adbe0d5d94f8e80279cbbc3c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 20:24:22 -0700 Subject: [PATCH 192/238] kern: support null resource limit in KSecureSystemResource --- .../include/mesosphere/kern_k_system_resource.hpp | 6 +++++- .../source/kern_k_system_resource.cpp | 15 ++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp index d0ba5ca10..628d1724b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_system_resource.hpp @@ -94,7 +94,11 @@ namespace ams::kern { static void PostDestroy(uintptr_t arg) { MESOSPHERE_UNUSED(arg); /* ... */ } ALWAYS_INLINE size_t CalculateRequiredSecureMemorySize() const { - return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); + if (m_resource_limit != nullptr) { + return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); + } else { + return 0; + } } ALWAYS_INLINE size_t GetSize() const { return m_resource_size; } diff --git a/libraries/libmesosphere/source/kern_k_system_resource.cpp b/libraries/libmesosphere/source/kern_k_system_resource.cpp index 876d6129d..fc4876252 100644 --- a/libraries/libmesosphere/source/kern_k_system_resource.cpp +++ b/libraries/libmesosphere/source/kern_k_system_resource.cpp @@ -59,7 +59,9 @@ namespace ams::kern { memory_reservation.Commit(); /* Open reference to our resource limit. */ - m_resource_limit->Open(); + if (m_resource_limit != nullptr) { + m_resource_limit->Open(); + } /* Set ourselves as initialized. */ m_is_initialized = true; @@ -76,11 +78,14 @@ namespace ams::kern { /* Free our secure memory. */ KSystemControl::FreeSecureMemory(m_resource_address, m_resource_size, m_resource_pool); - /* Release the memory reservation. */ - m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize()); + /* Clean up our resource usage. */ + if (m_resource_limit != nullptr) { + /* Release the memory reservation. */ + m_resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize()); - /* Close reference to our resource limit. */ - m_resource_limit->Close(); + /* Close reference to our resource limit. */ + m_resource_limit->Close(); + } } size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool) { From 96d4546498de0ddae729828fb424646c16a3e2df Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 20:37:42 -0700 Subject: [PATCH 193/238] kern: reorder resource manager implementation --- .../libmesosphere/source/kern_kernel.cpp | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/libraries/libmesosphere/source/kern_kernel.cpp b/libraries/libmesosphere/source/kern_kernel.cpp index cc80d9fbe..9660d906d 100644 --- a/libraries/libmesosphere/source/kern_kernel.cpp +++ b/libraries/libmesosphere/source/kern_kernel.cpp @@ -74,43 +74,45 @@ namespace ams::kern { MESOSPHERE_ABORT_UNLESS(rc_size < size); size -= rc_size; + /* Determine dynamic page managers. */ + KDynamicPageManager * const app_dynamic_page_manager = nullptr; + KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr; + /* Initialize the resource managers' shared page manager. */ g_resource_manager_page_manager.Initialize(address, size, std::max(PageSize, KPageBufferSlabHeap::BufferSize)); /* Initialize the KPageBuffer slab heap. */ KPageBuffer::InitializeSlabHeap(g_resource_manager_page_manager); - /* Initialize the fixed-size slabheaps. */ - s_app_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize); - s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize); + /* Initialize the block info heap. */ s_block_info_heap.Initialize(std::addressof(g_resource_manager_page_manager), BlockInfoSlabHeapSize); + /* Initialize the system slab managers. */ + s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap)); + s_sys_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), SystemMemoryBlockSlabHeapSize); + s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap)); + + /* Initialize the application slab managers. */ + s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap)); + s_app_memory_block_heap.Initialize(std::addressof(g_resource_manager_page_manager), ApplicationMemoryBlockSlabHeapSize); + s_app_memory_block_manager.Initialize(app_dynamic_page_manager, std::addressof(s_app_memory_block_heap)); + /* Reserve all but a fixed number of remaining pages for the page table heap. */ const size_t num_pt_pages = g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed() - ReservedDynamicPageCount; s_page_table_heap.Initialize(std::addressof(g_resource_manager_page_manager), num_pt_pages, GetPointer(address + size)); - /* Setup the slab managers. */ - KDynamicPageManager * const app_dynamic_page_manager = nullptr; - KDynamicPageManager * const sys_dynamic_page_manager = KTargetSystem::IsDynamicResourceLimitsEnabled() ? std::addressof(g_resource_manager_page_manager) : nullptr; - s_app_memory_block_manager.Initialize(app_dynamic_page_manager, std::addressof(s_app_memory_block_heap)); - s_sys_memory_block_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_sys_memory_block_heap)); - - s_app_block_info_manager.Initialize(app_dynamic_page_manager, std::addressof(s_block_info_heap)); - s_sys_block_info_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_block_info_heap)); - - s_app_page_table_manager.Initialize(app_dynamic_page_manager, std::addressof(s_page_table_heap)); + /* Create and initialize the system system resource. */ s_sys_page_table_manager.Initialize(sys_dynamic_page_manager, std::addressof(s_page_table_heap)); + KAutoObject::Create(std::addressof(s_sys_system_resource)); + s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager); + + /* Create and initialize the application system resource. */ + s_app_page_table_manager.Initialize(app_dynamic_page_manager, std::addressof(s_page_table_heap)); + KAutoObject::Create(std::addressof(s_app_system_resource)); + s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager); /* Check that we have the correct number of dynamic pages available. */ MESOSPHERE_ABORT_UNLESS(g_resource_manager_page_manager.GetCount() - g_resource_manager_page_manager.GetUsed() == ReservedDynamicPageCount); - - /* Create the system page table managers. */ - KAutoObject::Create(std::addressof(s_app_system_resource)); - KAutoObject::Create(std::addressof(s_sys_system_resource)); - - /* Set the managers for the system resources. */ - s_app_system_resource.SetManagers(s_app_memory_block_manager, s_app_block_info_manager, s_app_page_table_manager); - s_sys_system_resource.SetManagers(s_sys_memory_block_manager, s_sys_block_info_manager, s_sys_page_table_manager); } void Kernel::PrintLayout() { From b80f0944aba5ce8cc6b9bf76756403f1d2a68078 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 20:54:56 -0700 Subject: [PATCH 194/238] kern: update instruction cache invalidation logic in KPageTableBase to reflect 20.0.0 changes --- .../source/kern_k_page_table_base.cpp | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index d7068a763..11cc68ee7 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1786,19 +1786,24 @@ namespace ams::kern { KScopedSchedulerLock sl; } + /* Ensure cache coherency, if we're setting pages as executable. */ + if (is_x) { + for (const auto &block : pg) { + cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()); + } + cpu::InvalidateEntireInstructionCache(); + } + /* Perform mapping operation. */ const KPageProperties properties = { new_perm, false, false, DisableMergeAttribute_None }; - const auto operation = was_x ? OperationType_ChangePermissionsAndRefreshAndFlush : OperationType_ChangePermissions; + const auto operation = was_x ? OperationType_ChangePermissionsAndRefresh : OperationType_ChangePermissions; R_TRY(this->Operate(updater.GetPageList(), addr, num_pages, Null, false, properties, operation, false)); /* Update the blocks. */ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_None); /* Ensure cache coherency, if we're setting pages as executable. */ - if (is_x) { - for (const auto &block : pg) { - cpu::StoreDataCache(GetVoidPointer(GetHeapVirtualAddress(block.GetAddress())), block.GetSize()); - } + if (was_x) { cpu::InvalidateEntireInstructionCache(); } @@ -2540,6 +2545,11 @@ namespace ams::kern { /* We're going to perform an update, so create a helper. */ KScopedPageTableUpdater updater(this); + /* Ensure cache coherency, if we're mapping executable pages. */ + if ((perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) { + cpu::InvalidateEntireInstructionCache(); + } + /* Perform mapping operation. */ const KPageProperties properties = { perm, false, false, DisableMergeAttribute_DisableHead }; R_TRY(this->MapPageGroupImpl(updater.GetPageList(), addr, pg, properties, false)); @@ -2563,8 +2573,9 @@ namespace ams::kern { KScopedLightLock lk(m_general_lock); /* Check if state allows us to unmap. */ + KMemoryPermission old_perm; size_t num_allocator_blocks; - R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); + R_TRY(this->CheckMemoryState(nullptr, std::addressof(old_perm), nullptr, std::addressof(num_allocator_blocks), address, size, KMemoryState_All, state, KMemoryPermission_None, KMemoryPermission_None, KMemoryAttribute_All, KMemoryAttribute_None)); /* Check that the page group is valid. */ R_UNLESS(this->IsValidPageGroup(pg, address, num_pages), svc::ResultInvalidCurrentMemory()); @@ -2581,6 +2592,11 @@ namespace ams::kern { const KPageProperties properties = { KMemoryPermission_None, false, false, DisableMergeAttribute_None }; R_TRY(this->Operate(updater.GetPageList(), address, num_pages, Null, false, properties, OperationType_Unmap, false)); + /* Ensure cache coherency, if we're mapping executable pages. */ + if ((old_perm & KMemoryPermission_UserExecute) == KMemoryPermission_UserExecute) { + cpu::InvalidateEntireInstructionCache(); + } + /* Update the blocks. */ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState_Free, KMemoryPermission_None, KMemoryAttribute_None, KMemoryBlockDisableMergeAttribute_None, KMemoryBlockDisableMergeAttribute_Normal); From 28296e2aac0fce924e368151fb5faa03cc410ee2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 21:52:01 -0700 Subject: [PATCH 195/238] kern: refactor FindFreeArea region search logic per 20.0.0 changes --- .../kern_k_memory_block_manager.hpp | 1 + .../source/kern_k_memory_block_manager.cpp | 77 +++++++++++++++---- .../source/kern_k_page_table_base.cpp | 17 ++-- 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp index 4a67e86f5..f2888ec65 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_memory_block_manager.hpp @@ -99,6 +99,7 @@ namespace ams::kern { Result Initialize(KProcessAddress st, KProcessAddress nd, KMemoryBlockSlabManager *slab_manager); void Finalize(KMemoryBlockSlabManager *slab_manager); + static bool GetRegionForFindFreeArea(KProcessAddress *out_start, KProcessAddress *out_end, KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages); KProcessAddress FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const; void Update(KMemoryBlockManagerUpdateAllocator *allocator, KProcessAddress address, size_t num_pages, KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr, KMemoryBlockDisableMergeAttribute set_disable_attr, KMemoryBlockDisableMergeAttribute clear_disable_attr); diff --git a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp index 2c5bd962d..639c047d3 100644 --- a/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_memory_block_manager.cpp @@ -118,29 +118,78 @@ namespace ams::kern { MESOSPHERE_ASSERT(m_memory_block_tree.empty()); } + bool KMemoryBlockManager::GetRegionForFindFreeArea(KProcessAddress *out_start, KProcessAddress *out_end, KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) { + /* Check that there's room for the pages in the specified region. */ + if (num_pages + 2 * guard_pages > region_num_pages) { + return false; + } + + /* Determine the aligned start of the guarded region. */ + const KProcessAddress guarded_start = region_start + guard_pages * PageSize; + const KProcessAddress aligned_guarded_start = util::AlignDown(GetInteger(guarded_start), alignment); + KProcessAddress aligned_guarded_start_with_offset = aligned_guarded_start + offset; + if (guarded_start > aligned_guarded_start_with_offset) { + if (!util::CanAddWithoutOverflow(GetInteger(aligned_guarded_start), alignment)) { + return false; + } + aligned_guarded_start_with_offset += alignment; + } + + /* Determine the aligned end of the guarded region. */ + const KProcessAddress guarded_end = region_start + ((region_num_pages - (num_pages + guard_pages)) * PageSize); + const KProcessAddress aligned_guarded_end = util::AlignDown(GetInteger(guarded_end), alignment); + KProcessAddress aligned_guarded_end_with_offset = aligned_guarded_end + offset; + if (aligned_guarded_end_with_offset > guarded_end) { + if (aligned_guarded_end < alignment) { + return false; + } + aligned_guarded_end_with_offset -= alignment; + } + + /* Check that the extents are valid. */ + if (aligned_guarded_end_with_offset < aligned_guarded_start_with_offset) { + return false; + } + + /* Set the output extents. */ + *out_start = aligned_guarded_start_with_offset; + *out_end = aligned_guarded_end_with_offset; + return true; + } + KProcessAddress KMemoryBlockManager::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const { - if (num_pages > 0) { - const KProcessAddress region_end = region_start + region_num_pages * PageSize; - const KProcessAddress region_last = region_end - 1; - for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend(); it++) { - if (region_last < it->GetAddress()) { + /* Determine the range to search in. */ + KProcessAddress search_start = Null; + KProcessAddress search_end = Null; + if (this->GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) { + /* Iterate over blocks in the search space, looking for a suitable one. */ + for (const_iterator it = this->FindIterator(search_start); it != m_memory_block_tree.cend(); it++) { + /* If our block is past the end of our search space, we're done. */ + if (search_end < it->GetAddress()) { break; } + + /* We only want to consider free blocks. */ if (it->GetState() != KMemoryState_Free) { continue; } - KProcessAddress area = (it->GetAddress() <= GetInteger(region_start)) ? region_start : it->GetAddress(); - area += guard_pages * PageSize; + /* Determine the candidate range. */ + KProcessAddress candidate_start = Null; + KProcessAddress candidate_end = Null; + if (!this->GetRegionForFindFreeArea(std::addressof(candidate_start), std::addressof(candidate_end), it->GetAddress(), it->GetNumPages(), num_pages, alignment, offset, guard_pages)) { + continue; + } - const KProcessAddress offset_area = util::AlignDown(GetInteger(area), alignment) + offset; - area = (area <= offset_area) ? offset_area : offset_area + alignment; + /* Try the suggested candidate (coercing into the search region if needed). */ + KProcessAddress candidate = candidate_start; + if (candidate < search_start) { + candidate = search_start; + } - const KProcessAddress area_end = area + num_pages * PageSize + guard_pages * PageSize; - const KProcessAddress area_last = area_end - 1; - - if (GetInteger(it->GetAddress()) <= GetInteger(area) && area < area_last && area_last <= region_last && GetInteger(area_last) <= GetInteger(it->GetLastAddress())) { - return area; + /* Check if the candidate is valid. */ + if (candidate <= search_end && candidate <= candidate_end) { + return candidate; } } } diff --git a/libraries/libmesosphere/source/kern_k_page_table_base.cpp b/libraries/libmesosphere/source/kern_k_page_table_base.cpp index 11cc68ee7..ad42a62a4 100644 --- a/libraries/libmesosphere/source/kern_k_page_table_base.cpp +++ b/libraries/libmesosphere/source/kern_k_page_table_base.cpp @@ -1333,34 +1333,37 @@ namespace ams::kern { KProcessAddress KPageTableBase::FindFreeArea(KProcessAddress region_start, size_t region_num_pages, size_t num_pages, size_t alignment, size_t offset, size_t guard_pages) const { KProcessAddress address = Null; - if (num_pages <= region_num_pages) { + KProcessAddress search_start = Null; + KProcessAddress search_end = Null; + if (m_memory_block_manager.GetRegionForFindFreeArea(std::addressof(search_start), std::addressof(search_end), region_start, region_num_pages, num_pages, alignment, offset, guard_pages)) { if (this->IsAslrEnabled()) { /* Try to directly find a free area up to 8 times. */ for (size_t i = 0; i < 8; i++) { - const size_t random_offset = KSystemControl::GenerateRandomRange(0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) * alignment; - const KProcessAddress candidate = util::AlignDown(GetInteger(region_start + random_offset), alignment) + offset; + const size_t random_offset = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment) * alignment; + const KProcessAddress candidate = search_start + random_offset; KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(candidate); MESOSPHERE_ABORT_UNLESS(it != m_memory_block_manager.end()); if (it->GetState() != KMemoryState_Free) { continue; } - if (!(region_start <= candidate)) { continue; } if (!(it->GetAddress() + guard_pages * PageSize <= GetInteger(candidate))) { continue; } if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= it->GetLastAddress())) { continue; } - if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= region_start + region_num_pages * PageSize - 1)) { continue; } address = candidate; break; } + /* Fall back to finding the first free area with a random offset. */ if (address == Null) { /* NOTE: Nintendo does not account for guard pages here. */ /* This may theoretically cause an offset to be chosen that cannot be mapped. */ /* We will account for guard pages. */ - const size_t offset_pages = KSystemControl::GenerateRandomRange(0, region_num_pages - num_pages - guard_pages); - address = m_memory_block_manager.FindFreeArea(region_start + offset_pages * PageSize, region_num_pages - offset_pages, num_pages, alignment, offset, guard_pages); + const size_t offset_blocks = KSystemControl::GenerateRandomRange(0, (search_end - search_start) / alignment); + const auto region_end = region_start + region_num_pages * PageSize; + address = m_memory_block_manager.FindFreeArea(search_start + offset_blocks * alignment, (region_end - (search_start + offset_blocks * alignment)) / PageSize, num_pages, alignment, offset, guard_pages); } } + /* Find the first free area. */ if (address == Null) { address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages, alignment, offset, guard_pages); From 4580a352c09dcd5dde6c2916e617ad4c0ecbf899 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 22:31:25 -0700 Subject: [PATCH 196/238] kern: use callback to note pte updates in KPageTableImpl --- .../mesosphere/arch/arm64/kern_k_page_table.hpp | 5 +++++ .../mesosphere/arch/arm64/kern_k_page_table_impl.hpp | 6 ++++-- .../source/arch/arm64/kern_k_page_table.cpp | 11 +++++------ .../source/arch/arm64/kern_k_page_table_impl.cpp | 11 +++++++---- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp index f889d199a..7bc1a96f1 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table.hpp @@ -200,6 +200,11 @@ namespace ams::kern::arch::arm64 { NOINLINE Result InitializeForKernel(void *table, KVirtualAddress start, KVirtualAddress end); NOINLINE Result InitializeForProcess(ams::svc::CreateProcessFlag flags, bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, size_t code_size, KSystemResource *system_resource, KResourceLimit *resource_limit, size_t process_index); Result Finalize(); + + static void NoteUpdatedCallback(const void *pt) { + /* Note the update. */ + static_cast(pt)->NoteUpdated(); + } private: Result Unmap(KProcessAddress virt_addr, size_t num_pages, PageLinkedList *page_list, bool force, bool reuse_ll); diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp index e8965c4d8..b1a97fca0 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm64/kern_k_page_table_impl.hpp @@ -49,6 +49,8 @@ namespace ams::kern::arch::arm64 { EntryLevel level; bool is_contiguous; }; + + using EntryUpdatedCallback = void (*)(const void *); private: static constexpr size_t PageBits = util::CountTrailingZeros(PageSize); static constexpr size_t NumLevels = 3; @@ -144,8 +146,8 @@ namespace ams::kern::arch::arm64 { bool GetPhysicalAddress(KPhysicalAddress *out, KProcessAddress virt_addr) const; - static bool MergePages(KVirtualAddress *out, TraversalContext *context); - void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const; + static bool MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt); + void SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const; KProcessAddress GetAddressForContext(const TraversalContext *context) const { KProcessAddress addr = m_is_kernel ? static_cast(-GetBlockSize(EntryLevel_L1)) * m_num_entries : 0; diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp index d13f81979..abc3b1076 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table.cpp @@ -752,13 +752,10 @@ namespace ams::kern::arch::arm64 { while (true) { /* Try to merge. */ KVirtualAddress freed_table = Null; - if (!impl.MergePages(std::addressof(freed_table), context)) { + if (!impl.MergePages(std::addressof(freed_table), context, &KPageTable::NoteUpdatedCallback, this)) { break; } - /* Note that we updated. */ - this->NoteUpdated(); - /* Free the page. */ if (freed_table != Null) { ClearPageTable(freed_table); @@ -816,8 +813,7 @@ namespace ams::kern::arch::arm64 { } /* Separate. */ - impl.SeparatePages(entry, context, virt_addr, GetPointer(table)); - this->NoteUpdated(); + impl.SeparatePages(entry, context, virt_addr, GetPointer(table), &KPageTable::NoteUpdatedCallback, this); } R_SUCCEED(); @@ -1025,6 +1021,9 @@ namespace ams::kern::arch::arm64 { /* Finally, apply the changes as directed, flushing the mappings before they're applied (if we should). */ ApplyEntryTemplate(entry_template, flush_mapping ? ApplyOption_FlushDataCache : ApplyOption_None); + + /* Wait for pending stores to complete. */ + cpu::DataSynchronizationBarrierInnerShareableStore(); } /* We've succeeded, now perform what coalescing we can. */ diff --git a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp index 150aa1d1c..5ce64e3f6 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_k_page_table_impl.cpp @@ -219,7 +219,7 @@ namespace ams::kern::arch::arm64 { return is_block; } - bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context) { + bool KPageTableImpl::MergePages(KVirtualAddress *out, TraversalContext *context, EntryUpdatedCallback on_entry_updated, const void *pt) { /* We want to upgrade the pages by one step. */ if (context->is_contiguous) { /* We can't merge an L1 table. */ @@ -251,6 +251,7 @@ namespace ams::kern::arch::arm64 { const auto sw_reserved_bits = PageTableEntry::EncodeSoftwareReservedBits(head_pte->IsHeadMergeDisabled(), head_pte->IsHeadAndBodyMergeDisabled(), tail_pte->IsTailMergeDisabled()); *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr, PageTableEntry(entry_template), sw_reserved_bits, false, false); + on_entry_updated(pt); /* Update our context. */ context->is_contiguous = false; @@ -285,6 +286,7 @@ namespace ams::kern::arch::arm64 { for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, phys_addr + (i << (PageBits + LevelBits * context->level)), PageTableEntry(entry_template), sw_reserved_bits, true, context->level == EntryLevel_L3); } + on_entry_updated(pt); /* Update our context. */ context->level_entries[context->level] = pte; @@ -294,7 +296,7 @@ namespace ams::kern::arch::arm64 { return true; } - void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte) const { + void KPageTableImpl::SeparatePages(TraversalEntry *entry, TraversalContext *context, KProcessAddress address, PageTableEntry *pte, EntryUpdatedCallback on_entry_updated, const void *pt) const { /* We want to downgrade the pages by one step. */ if (context->is_contiguous) { /* We want to downgrade a contiguous mapping to a non-contiguous mapping. */ @@ -305,6 +307,7 @@ namespace ams::kern::arch::arm64 { for (size_t i = 0; i < BlocksPerContiguousBlock; ++i) { pte[i] = PageTableEntry(PageTableEntry::BlockTag{}, block + (i << (PageBits + LevelBits * context->level)), PageTableEntry(first->GetEntryTemplateForSeparateContiguous(i)), PageTableEntry::SeparateContiguousTag{}); } + on_entry_updated(pt); context->is_contiguous = false; @@ -325,12 +328,12 @@ namespace ams::kern::arch::arm64 { /* Update the block entry to be a table entry. */ *context->level_entries[context->level + 1] = PageTableEntry(PageTableEntry::TableTag{}, KPageTable::GetPageTablePhysicalAddress(KVirtualAddress(pte)), m_is_kernel, true, BlocksPerTable); - + on_entry_updated(pt); context->level_entries[context->level] = pte + this->GetLevelIndex(address, context->level); } - entry->sw_reserved_bits = 0; + entry->sw_reserved_bits = context->level_entries[context->level]->GetSoftwareReservedBits(); entry->attr = 0; entry->phys_addr = this->GetBlock(context->level_entries[context->level], context->level) + this->GetOffset(address, context->level); entry->block_size = static_cast(1) << (PageBits + LevelBits * context->level + 4 * context->is_contiguous); From b1ca5b40496620f514d310d42e3c1307091ebfcc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 22:33:40 -0700 Subject: [PATCH 197/238] kern: plutoo is an intellectual, I am a fool, fix chicanery --- .../source/arch/arm64/kern_exception_handlers.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp index b745d5ab3..6c21b455b 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_exception_handlers.cpp @@ -115,7 +115,10 @@ namespace ams::kern::arch::arm64 { u64 far = raw_far; const u64 ec = (esr >> 26) & 0x3F; if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) { - /* Adjust registers if a memory tagging exception has occurred. */ + /* Adjust registers if a synchronous external abort has occurred with far not valid. */ + /* Mask 0x03F = Low 6 bits IFSC == 0x10: "Synchronous External abort, */ + /* not on translation table walk or hardware update of translation table. */ + /* Mask 0x400 = FnV = "FAR Not Valid" */ /* TODO: How would we perform this check using named register accesses? */ if ((esr & 0x43F) == 0x410) { /* Clear the faulting register on memory tagging exception. */ @@ -450,7 +453,10 @@ namespace ams::kern::arch::arm64 { /* Pre-process exception registers as needed. */ const u64 ec = (esr >> 26) & 0x3F; if (ec == EsrEc_InstructionAbortEl0 || ec == EsrEc_DataAbortEl0) { - /* Adjust registers if a memory tagging exception has occurred. */ + /* Adjust registers if a synchronous external abort has occurred with far not valid. */ + /* Mask 0x03F = Low 6 bits IFSC == 0x10: "Synchronous External abort, */ + /* not on translation table walk or hardware update of translation table. */ + /* Mask 0x400 = FnV = "FAR Not Valid" */ /* TODO: How would we perform this check using named register accesses? */ if ((esr & 0x43F) == 0x410) { /* Clear the faulting register on memory tagging exception. */ From 791edf87a07bd24123500bcf1ad795404df89f1d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 30 Apr 2025 23:27:36 -0700 Subject: [PATCH 198/238] ncm: update to implement new ContentMetaDatabase function for 20.0.0 --- .../ncm/ncm_content_meta_database.hpp | 5 ++++ .../ncm/ncm_i_content_meta_database.hpp | 3 +- ..._integrated_content_meta_database_impl.hpp | 1 + .../ncm/ncm_content_meta_database_impl.cpp | 30 +++++++++++++++++++ .../ncm/ncm_content_meta_database_impl.hpp | 1 + .../ncm_content_meta_database_impl_base.hpp | 1 + ..._integrated_content_meta_database_impl.cpp | 24 +++++++++++++++ .../ncm_remote_content_meta_database_impl.hpp | 6 ++++ 8 files changed, 70 insertions(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp index fde547802..6c6a8adec 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_database.hpp @@ -226,6 +226,11 @@ namespace ams::ncm { AMS_ASSERT(m_interface != nullptr); R_RETURN(m_interface->GetPlatform(out, key)); } + + Result HasAttributes(u8 *out, u8 attr_mask) { + AMS_ASSERT(m_interface != nullptr); + R_RETURN(m_interface->HasAttributes(out, attr_mask)); + } }; } diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp index 099de50fb..39c04cd03 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_i_content_meta_database.hpp @@ -44,7 +44,8 @@ AMS_SF_METHOD_INFO(C, H, 23, Result, GetContentAccessibilities, (sf::Out out_accessibilities, const ncm::ContentMetaKey &key), (out_accessibilities, key), hos::Version_15_0_0) \ AMS_SF_METHOD_INFO(C, H, 24, Result, GetContentInfoByType, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type), (out_content_info, key, type), hos::Version_15_0_0) \ AMS_SF_METHOD_INFO(C, H, 25, Result, GetContentInfoByTypeAndIdOffset, (sf::Out out_content_info, const ncm::ContentMetaKey &key, ncm::ContentType type, u8 id_offset), (out_content_info, key, type, id_offset), hos::Version_15_0_0) \ - AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) + AMS_SF_METHOD_INFO(C, H, 26, Result, GetPlatform, (sf::Out out, const ncm::ContentMetaKey &key), (out, key), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 27, Result, HasAttributes, (sf::Out out, u8 attr_mask), (out, attr_mask), hos::Version_20_0_0) AMS_SF_DEFINE_INTERFACE(ams::ncm, IContentMetaDatabase, AMS_NCM_I_CONTENT_META_DATABASE_INTERFACE_INFO, 0x58021FEC) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp index 38bfc154f..8d0e79ff0 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_integrated_content_meta_database_impl.hpp @@ -72,6 +72,7 @@ namespace ams::ncm { Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type); Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset); Result GetPlatform(sf::Out out, const ContentMetaKey &key); + Result HasAttributes(sf::Out out, u8 attr_mask); }; static_assert(ncm::IsIContentMetaDatabase); diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp index da23ce454..4cf5175b2 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.cpp @@ -534,4 +534,34 @@ namespace ams::ncm { R_SUCCEED(); } + Result ContentMetaDatabaseImpl::HasAttributes(sf::Out out, u8 attribute_mask) { + R_TRY(this->EnsureEnabled()); + + /* Create a variable to hold the combined attributes. */ + u8 combined_attributes = 0; + + /* Iterate over all entries. */ + for (auto &entry : *m_kvs) { + /* Obtain the content meta for the key. */ + const void *meta; + size_t meta_size; + R_TRY(this->GetContentMetaPointer(&meta, &meta_size, entry.GetKey())); + + /* Create a reader. */ + ContentMetaReader reader(meta, meta_size); + + /* Accumulate the set attributes from the current entry. */ + combined_attributes |= (reader.GetHeader()->attributes) & attribute_mask; + + /* If all the attributes we're looking for have been found, we're done. */ + if ((combined_attributes & attribute_mask) == attribute_mask) { + break; + } + } + + /* Set the output. */ + *out = combined_attributes; + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp index 9d6bcfb46..b4e3803d7 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl.hpp @@ -65,6 +65,7 @@ namespace ams::ncm { virtual Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type) override; virtual Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) override; virtual Result GetPlatform(sf::Out out, const ContentMetaKey &key) override; + virtual Result HasAttributes(sf::Out out, u8 attr_mask) override; }; } diff --git a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp index 7c0d57c30..59d6130e9 100644 --- a/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_content_meta_database_impl_base.hpp @@ -81,6 +81,7 @@ namespace ams::ncm { virtual Result GetContentInfoByType(sf::Out out_content_info, const ContentMetaKey &key, ContentType type) = 0; virtual Result GetContentInfoByTypeAndIdOffset(sf::Out out_content_info, const ContentMetaKey &key, ContentType type, u8 id_offset) = 0; virtual Result GetPlatform(sf::Out out, const ContentMetaKey &key) = 0; + virtual Result HasAttributes(sf::Out out, u8 attr_mask) = 0; }; static_assert(ncm::IsIContentMetaDatabase); diff --git a/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp b/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp index b498464cf..148471e86 100644 --- a/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp +++ b/libraries/libstratosphere/source/ncm/ncm_integrated_content_meta_database_impl.cpp @@ -463,4 +463,28 @@ namespace ams::ncm { })); } + Result IntegratedContentMetaDatabaseImpl::HasAttributes(sf::Out out, u8 attr_mask) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + /* Check that we're enabled. */ + R_TRY(this->EnsureEnabled()); + + /* Test whether we have the attributes on all databases. */ + u8 combined_attributes = 0; + R_TRY(m_list.ForAll([&](const auto &data) { + /* Check the current database. */ + u8 cur_attr = 0; + R_TRY(data.interface->HasAttributes(std::addressof(cur_attr), attr_mask)); + + /* Accumulate the attributes found in the current interface. */ + combined_attributes |= cur_attr; + R_SUCCEED(); + })); + + /* Set the output. */ + *out = combined_attributes; + R_SUCCEED(); + } + } diff --git a/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp b/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp index a0d8a4286..abba78c73 100644 --- a/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp +++ b/libraries/libstratosphere/source/ncm/ncm_remote_content_meta_database_impl.hpp @@ -191,6 +191,12 @@ namespace ams::ncm { static_assert(sizeof(ncm::ContentMetaPlatform) == sizeof(u8)); R_RETURN(ncmContentMetaDatabaseGetPlatform(std::addressof(m_srv), reinterpret_cast(out.GetPointer()), Convert(key))); } + + Result HasAttributes(sf::Out out, u8 attr_mask) { + /* TODO: libnx bindings */ + AMS_UNUSED(out, attr_mask); + AMS_ABORT(); + } }; static_assert(ncm::IsIContentMetaDatabase); #endif From 07df13e2a0d7149065e27f0c647ac9ccfb35d1da Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 1 May 2025 18:05:10 -0700 Subject: [PATCH 199/238] strat: update for fsp-ldr 20.0.0 changes --- .../include/stratosphere/fs/fs_code.hpp | 6 ++-- .../fssrv/fssrv_file_system_proxy_impl.hpp | 10 ++++-- ...ssrv_sf_i_file_system_proxy_for_loader.hpp | 15 +++++---- .../libstratosphere/source/fs/fs_code.cpp | 32 +++++++++++-------- ...fs_remote_file_system_proxy_for_loader.hpp | 18 ++++++++--- .../fssrv/fssrv_file_system_proxy_impl.cpp | 7 +++- .../loader/source/ldr_content_management.cpp | 6 ++-- 7 files changed, 60 insertions(+), 34 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp index dd5e5b33d..1bc47d4b2 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp @@ -21,9 +21,9 @@ namespace ams::fs { /* ACCURATE_TO_VERSION: 16.2.0.0 */ - Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id); - Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific); - Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific); + Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id); } diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp index f5373ac8d..7a2778a9e 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -150,7 +150,8 @@ namespace ams::fssrv { Result OpenCodeFileSystemDeprecated(ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id); Result OpenCodeFileSystemDeprecated2(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id); Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); - Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id); + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id); Result IsArchivedProgram(ams::sf::Out out, u64 process_id); }; static_assert(sf::IsIFileSystemProxy); @@ -174,11 +175,16 @@ namespace ams::fssrv { R_THROW(fs::ResultPortAcceptableCountLimited()); } - Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { AMS_UNUSED(out_fs, out_verif, path, attr, program_id); R_THROW(fs::ResultPortAcceptableCountLimited()); } + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + AMS_UNUSED(out_fs, out_verif, attr, program_id, storage_id); + R_THROW(fs::ResultPortAcceptableCountLimited()); + } + Result IsArchivedProgram(ams::sf::Out out, u64 process_id) { AMS_UNUSED(out, process_id); R_THROW(fs::ResultPortAcceptableCountLimited()); diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp index 488b49639..0e55e2562 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp @@ -21,12 +21,13 @@ #include /* ACCURATE_TO_VERSION: 17.5.0.0 */ -#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) +#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated2, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0, hos::Version_15_0_1) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated3, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_16_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated4, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id), (out_fs, out_verif, path, attr, program_id), hos::Version_17_0_0, hos::Version_19_0_1) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id), (out_fs, out_verif, attr, program_id, storage_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IFileSystemProxyForLoader, AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO, 0xDC92EE15) diff --git a/libraries/libstratosphere/source/fs/fs_code.cpp b/libraries/libstratosphere/source/fs/fs_code.cpp index a8015cd6a..e7c694e0f 100644 --- a/libraries/libstratosphere/source/fs/fs_code.cpp +++ b/libraries/libstratosphere/source/fs/fs_code.cpp @@ -69,7 +69,7 @@ namespace ams::fs { return GetReference(g_stratosphere_romfs_fs); } - Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { /* Print a path suitable for the remote service. */ fssrv::sf::Path sf_path; R_TRY(FormatToFspPath(std::addressof(sf_path), "%s", path)); @@ -79,7 +79,11 @@ namespace ams::fs { R_TRY(fsp->SetCurrentProcess({})); sf::SharedPointer fs; - R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id)); + if (hos::GetVersion() >= hos::Version_20_0_0) { + R_TRY(fsp->OpenCodeFileSystem(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), attr, program_id, storage_id)); + } else { + R_TRY(fsp->OpenCodeFileSystemDeprecated4(std::addressof(fs), ams::sf::OutBuffer(out_verification_data, sizeof(*out_verification_data)), sf_path, attr, program_id)); + } /* Allocate a new filesystem wrapper. */ auto fsa = std::make_unique(std::move(fs)); @@ -148,7 +152,7 @@ namespace ams::fs { R_SUCCEED(); } - Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(CodeVerificationData *out_verification_data, std::unique_ptr *out, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { /* If we can open an sd card code fs, use it. */ R_SUCCEED_IF(R_SUCCEEDED(OpenSdCardCodeFileSystemImpl(out, program_id))); @@ -156,7 +160,7 @@ namespace ams::fs { R_SUCCEED_IF(R_SUCCEEDED(OpenStratosphereCodeFileSystemImpl(out, program_id))); /* Otherwise, fall back to a normal code fs. */ - R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id)); + R_RETURN(OpenCodeFileSystemImpl(out_verification_data, out, path, attr, program_id, storage_id)); } Result OpenHblCodeFileSystemImpl(std::unique_ptr *out) { @@ -334,11 +338,12 @@ namespace ams::fs { util::optional m_code_fs; util::optional m_hbl_fs; ncm::ProgramId m_program_id; + ncm::StorageId m_storage_id; bool m_initialized; public: AtmosphereCodeFileSystem() : m_initialized(false) { /* ... */ } - Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) { + Result Initialize(CodeVerificationData *out_verification_data, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific) { AMS_ABORT_UNLESS(!m_initialized); /* If we're hbl, we need to open a hbl fs. */ @@ -350,10 +355,11 @@ namespace ams::fs { /* Open the code filesystem. */ std::unique_ptr fsa; - R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id)); + R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out_verification_data, std::addressof(fsa), path, attr, program_id, storage_id)); m_code_fs.emplace(std::move(fsa), program_id, is_specific); - m_program_id = program_id; + m_program_id = program_id; + m_storage_id = storage_id; m_initialized = true; R_SUCCEED(); @@ -386,7 +392,7 @@ namespace ams::fs { } - Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result MountCode(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -399,7 +405,7 @@ namespace ams::fs { /* Open the code file system. */ std::unique_ptr fsa; - R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id)); + R_TRY(OpenCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id)); /* Register. */ R_RETURN(fsa::Register(name, std::move(fsa))); @@ -414,7 +420,7 @@ namespace ams::fs { R_SUCCEED(); } - Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, bool is_hbl, bool is_specific) { + Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id, bool is_hbl, bool is_specific) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -430,7 +436,7 @@ namespace ams::fs { R_UNLESS(ams_code_fs != nullptr, fs::ResultAllocationMemoryFailedInCodeA()); /* Initialize the code file system. */ - R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, is_hbl, is_specific)); + R_TRY(ams_code_fs->Initialize(out, path, attr, program_id, storage_id, is_hbl, is_specific)); /* Register. */ R_RETURN(fsa::Register(name, std::move(ams_code_fs))); @@ -445,7 +451,7 @@ namespace ams::fs { R_SUCCEED(); } - Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result MountCodeForAtmosphere(CodeVerificationData *out, const char *name, const char *path, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { auto mount_impl = [=]() -> Result { /* Clear the output. */ std::memset(out, 0, sizeof(*out)); @@ -458,7 +464,7 @@ namespace ams::fs { /* Open the code file system. */ std::unique_ptr fsa; - R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id)); + R_TRY(OpenSdCardCodeOrStratosphereCodeOrCodeFileSystemImpl(out, std::addressof(fsa), path, attr, program_id, storage_id)); /* Create a wrapper fs. */ auto wrap_fsa = std::make_unique(std::move(fsa), program_id, false); diff --git a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp index 71edaeb4f..528b1a92b 100644 --- a/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp +++ b/libraries/libstratosphere/source/fs/fs_remote_file_system_proxy_for_loader.hpp @@ -33,7 +33,7 @@ namespace ams::fs { Result OpenCodeFileSystemDeprecated(ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id) { ::FsCodeInfo dummy; ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(std::addressof(dummy), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); @@ -41,7 +41,7 @@ namespace ams::fs { Result OpenCodeFileSystemDeprecated2(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id) { ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(fs::ContentAttributes_None)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); @@ -49,15 +49,23 @@ namespace ams::fs { Result OpenCodeFileSystemDeprecated3(ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); } - Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { ::FsFileSystem fs; - R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, ::NcmStorageId_None, path.str, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); + + out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); + R_SUCCEED(); + } + + Result OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + ::FsFileSystem fs; + R_TRY(fsldrOpenCodeFileSystem(reinterpret_cast<::FsCodeInfo *>(out_verif.GetPointer()), program_id.value, static_cast<::NcmStorageId>(static_cast(storage_id)), nullptr, static_cast<::FsContentAttributes>(static_cast(attr)), std::addressof(fs))); out_fs.SetValue(ObjectFactory::CreateSharedEmplaced(fs)); R_SUCCEED(); diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp index 39b784d52..a22a2d888 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_impl.cpp @@ -482,11 +482,16 @@ namespace ams::fssrv { AMS_UNUSED(out_fs, out_verif, path, attr, program_id); } - Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { + Result FileSystemProxyImpl::OpenCodeFileSystemDeprecated4(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, const fssrv::sf::Path &path, fs::ContentAttributes attr, ncm::ProgramId program_id) { AMS_ABORT("TODO"); AMS_UNUSED(out_fs, out_verif, path, attr, program_id); } + Result FileSystemProxyImpl::OpenCodeFileSystem(ams::sf::Out> out_fs, const ams::sf::OutBuffer &out_verif, fs::ContentAttributes attr, ncm::ProgramId program_id, ncm::StorageId storage_id) { + AMS_ABORT("TODO"); + AMS_UNUSED(out_fs, out_verif, attr, program_id, storage_id); + } + Result FileSystemProxyImpl::IsArchivedProgram(ams::sf::Out out, u64 process_id) { AMS_ABORT("TODO"); AMS_UNUSED(out, process_id); diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index dbab1983f..a08ddf6aa 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -59,15 +59,15 @@ namespace ams::ldr { const auto content_attributes = GetPlatformContentAttributes(platform); /* Mount the atmosphere code file system. */ - R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); + R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id), m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); m_mounted_ams = true; /* Mount the sd or base code file system. */ - R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id)); + R_TRY(fs::MountCodeForAtmosphere(std::addressof(m_sd_or_base_code_verification_data), SdOrCodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id))); m_mounted_sd_or_code = true; /* Mount the base code file system. */ - if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id))) { + if (R_SUCCEEDED(fs::MountCode(std::addressof(m_base_code_verification_data), CodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id)))) { m_mounted_code = true; } From f55cf42433eb0eee671804919df9b655ef836ab3 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 1 May 2025 20:41:17 -0700 Subject: [PATCH 200/238] ldr/pm: update for 20.0.0 abi changes --- .../impl/ldr_process_manager_interface.hpp | 18 +-- .../include/stratosphere/ldr/ldr_pm_api.hpp | 6 +- .../include/stratosphere/ldr/ldr_types.hpp | 7 ++ .../source/ldr/ldr_ams.os.horizon.c | 10 +- .../source/ldr/ldr_ams.os.horizon.h | 2 +- .../source/ldr/ldr_pm_api.os.horizon.cpp | 13 +- .../vapours/results/loader_results.hpp | 26 ++-- .../loader/source/ldr_content_management.cpp | 26 ++-- .../loader/source/ldr_content_management.hpp | 10 +- .../loader/source/ldr_loader_service.cpp | 114 +++++++++--------- .../loader/source/ldr_loader_service.hpp | 16 +-- .../loader/source/ldr_process_creation.cpp | 12 +- .../loader/source/ldr_process_creation.hpp | 4 +- .../pm/source/impl/pm_process_attributes.hpp | 35 ++++++ .../pm/source/impl/pm_process_info.cpp | 6 +- .../pm/source/impl/pm_process_info.hpp | 10 +- .../pm/source/impl/pm_process_manager.cpp | 12 +- 17 files changed, 186 insertions(+), 141 deletions(-) create mode 100644 stratosphere/pm/source/impl/pm_process_attributes.hpp diff --git a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp index 651b25bff..39c0bc3da 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/impl/ldr_process_manager_interface.hpp @@ -19,14 +19,14 @@ #include #include -#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle &&reslimit_h), (proc_h, id, flags, std::move(reslimit_h))) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out out_program_info, const ncm::ProgramLocation &loc), (out_program_info, loc)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \ - AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ - AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc), (out_program_info, out_status, loc)) \ - AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status)) +#define AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, CreateProcess, (sf::OutMoveHandle proc_h, ldr::PinId id, u32 flags, sf::CopyHandle &&reslimit_h, const ldr::ProgramAttributes &attrs), (proc_h, id, flags, std::move(reslimit_h), attrs)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetProgramInfo, (sf::Out out_program_info, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs), (out_program_info, loc, attrs)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, PinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc), (out_id, loc)) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, UnpinProgram, (ldr::PinId id), (id)) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, SetEnabledProgramVerification, (bool enabled), (enabled), hos::Version_10_0_0) \ + AMS_SF_METHOD_INFO(C, H, 65000, void, AtmosphereHasLaunchedBootProgram, (sf::Out out, ncm::ProgramId program_id), (out, program_id)) \ + AMS_SF_METHOD_INFO(C, H, 65001, Result, AtmosphereGetProgramInfo, (sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs), (out_program_info, out_status, loc, attrs)) \ + AMS_SF_METHOD_INFO(C, H, 65002, Result, AtmospherePinProgram, (sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status), (out_id, loc, override_status)) AMS_SF_DEFINE_INTERFACE(ams::ldr::impl, IProcessManagerInterface, AMS_LDR_I_PROCESS_MANAGER_INTERFACE_INTERFACE_INFO, 0x01518B8E) diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp index dd5d34b9a..310c6fa51 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_pm_api.hpp @@ -20,15 +20,15 @@ namespace ams::ldr::pm { /* Process Manager API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit); - Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle reslimit, ldr::ProgramAttributes attrs); + Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc); Result UnpinProgram(PinId pin_id); Result SetEnabledProgramVerification(bool enabled); Result HasLaunchedBootProgram(bool *out, ncm::ProgramId program_id); /* Atmosphere extension API. */ - Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs); Result AtmospherePinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); } diff --git a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp index 524657042..5cc2fbb8b 100644 --- a/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/ldr/ldr_types.hpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace ams::ldr { @@ -265,4 +266,10 @@ namespace ams::ldr { }; static_assert(sizeof(Npdm) == 0x80 && util::is_pod::value, "Npdm definition!"); + struct ProgramAttributes { + ncm::ContentMetaPlatform platform; + fs::ContentAttributes content_attributes; + }; + static_assert(sizeof(ProgramAttributes) == 2 && util::is_pod::value, "ProgramAttributes definition!"); + } diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c index 7d0b4f907..3a0dca194 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c +++ b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.c @@ -32,8 +32,14 @@ Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id) { return _ldrAtmosphereHasLaunchedBootProgram(ldrPmGetServiceSession(), out, program_id); } -Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc) { - return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, *loc, *out_status, +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out_program_info, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr) { + const struct { + LoaderProgramAttributes attr; + u16 pad1; + u32 pad2; + NcmProgramLocation loc; + } in = { *attr, 0, 0, *loc }; + return serviceDispatchInOut(ldrPmGetServiceSession(), 65001, in, *out_status, .buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize }, .buffers = { { out_program_info, sizeof(*out_program_info) } }, ); diff --git a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h index 30a5e4163..b52807112 100644 --- a/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h +++ b/libraries/libstratosphere/source/ldr/ldr_ams.os.horizon.h @@ -19,7 +19,7 @@ typedef struct { Result ldrPmAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); Result ldrDmntAtmosphereHasLaunchedBootProgram(bool *out, u64 program_id); -Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc); +Result ldrPmAtmosphereGetProgramInfo(LoaderProgramInfo *out, CfgOverrideStatus *out_status, const NcmProgramLocation *loc, const LoaderProgramAttributes *attr); Result ldrPmAtmospherePinProgram(u64 *out, const NcmProgramLocation *loc, const CfgOverrideStatus *status); #ifdef __cplusplus diff --git a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp index 2e00417de..f461f9f7f 100644 --- a/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp +++ b/libraries/libstratosphere/source/ldr/ldr_pm_api.os.horizon.cpp @@ -19,13 +19,14 @@ namespace ams::ldr::pm { /* Information API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit) { - R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, out)); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, Handle reslimit, ldr::ProgramAttributes attrs) { + static_assert(sizeof(attrs) == sizeof(::LoaderProgramAttributes)); + R_RETURN(ldrPmCreateProcess(pin_id.value, flags, reslimit, reinterpret_cast(std::addressof(attrs)), out)); } - Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc) { + Result GetProgramInfo(ProgramInfo *out, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) { static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); - R_RETURN(ldrPmGetProgramInfo(reinterpret_cast(std::addressof(loc)), reinterpret_cast(out))); + R_RETURN(ldrPmGetProgramInfo(reinterpret_cast(std::addressof(loc)), reinterpret_cast(std::addressof(attrs)), reinterpret_cast(out))); } Result PinProgram(PinId *out, const ncm::ProgramLocation &loc) { @@ -41,10 +42,10 @@ namespace ams::ldr::pm { R_RETURN(ldrPmAtmosphereHasLaunchedBootProgram(out, static_cast(program_id))); } - Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { + Result AtmosphereGetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ldr::ProgramAttributes attrs) { static_assert(sizeof(*out_status) == sizeof(CfgOverrideStatus), "CfgOverrideStatus definition!"); static_assert(sizeof(*out) == sizeof(LoaderProgramInfo)); - R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(std::addressof(loc)))); + R_RETURN(ldrPmAtmosphereGetProgramInfo(reinterpret_cast(out), reinterpret_cast(out_status), reinterpret_cast(std::addressof(loc)), reinterpret_cast(std::addressof(attrs)))); } Result SetEnabledProgramVerification(bool enabled) { diff --git a/libraries/libvapours/include/vapours/results/loader_results.hpp b/libraries/libvapours/include/vapours/results/loader_results.hpp index d9cfa62b5..25e3debee 100644 --- a/libraries/libvapours/include/vapours/results/loader_results.hpp +++ b/libraries/libvapours/include/vapours/results/loader_results.hpp @@ -21,20 +21,20 @@ R_DEFINE_NAMESPACE_RESULT_MODULE(ams::ldr, 9); namespace ams::ldr { - R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1); - R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2); - R_DEFINE_ERROR_RESULT(MetaOverflow, 3); - R_DEFINE_ERROR_RESULT(InvalidMeta, 4); - R_DEFINE_ERROR_RESULT(InvalidNso, 5); - R_DEFINE_ERROR_RESULT(InvalidPath, 6); - R_DEFINE_ERROR_RESULT(MaxProcess, 7); - R_DEFINE_ERROR_RESULT(NotPinned, 8); - R_DEFINE_ERROR_RESULT(InvalidProgramId, 9); - R_DEFINE_ERROR_RESULT(InvalidVersion, 10); - R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11); - R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12); + R_DEFINE_ERROR_RESULT(ArgumentOverflow, 1); + R_DEFINE_ERROR_RESULT(ArgumentCountOverflow, 2); + R_DEFINE_ERROR_RESULT(MetaOverflow, 3); + R_DEFINE_ERROR_RESULT(InvalidMeta, 4); + R_DEFINE_ERROR_RESULT(InvalidNso, 5); + R_DEFINE_ERROR_RESULT(InvalidPath, 6); + R_DEFINE_ERROR_RESULT(MaxProcess, 7); + R_DEFINE_ERROR_RESULT(NotPinned, 8); + R_DEFINE_ERROR_RESULT(InvalidProgramId, 9); + R_DEFINE_ERROR_RESULT(InvalidVersion, 10); + R_DEFINE_ERROR_RESULT(InvalidAcidSignature, 11); + R_DEFINE_ERROR_RESULT(InvalidNcaSignature, 12); - R_DEFINE_ERROR_RESULT(InvalidPlatformId, 14); + R_DEFINE_ERROR_RESULT(InvalidProgramAttributes, 14); R_DEFINE_ERROR_RESULT(OutOfAddressSpace, 51); R_DEFINE_ERROR_RESULT(InvalidNroImage, 52); diff --git a/stratosphere/loader/source/ldr_content_management.cpp b/stratosphere/loader/source/ldr_content_management.cpp index a08ddf6aa..f1d0dfa14 100644 --- a/stratosphere/loader/source/ldr_content_management.cpp +++ b/stratosphere/loader/source/ldr_content_management.cpp @@ -25,12 +25,12 @@ namespace ams::ldr { } /* ScopedCodeMount functionality. */ - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { - m_result = this->Initialize(loc, platform); + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) : m_lk(g_scoped_code_mount_lock), m_has_status(false), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + m_result = this->Initialize(loc, attrs); } - ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, ncm::ContentMetaPlatform platform) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { - m_result = this->Initialize(loc, platform); + ScopedCodeMount::ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &o, const ldr::ProgramAttributes &attrs) : m_lk(g_scoped_code_mount_lock), m_override_status(o), m_has_status(true), m_mounted_ams(false), m_mounted_sd_or_code(false), m_mounted_code(false) { + m_result = this->Initialize(loc, attrs); } ScopedCodeMount::~ScopedCodeMount() { @@ -46,17 +46,17 @@ namespace ams::ldr { } } - Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) { + Result ScopedCodeMount::Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) { /* Capture override status, if necessary. */ this->EnsureOverrideStatus(loc); AMS_ABORT_UNLESS(m_has_status); /* Get the content path. */ char content_path[fs::EntryNameLengthMax + 1]; - R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, platform)); + R_TRY(GetProgramPath(content_path, sizeof(content_path), loc, attrs)); /* Get the content attributes. */ - const auto content_attributes = GetPlatformContentAttributes(platform); + const auto content_attributes = attrs.content_attributes; /* Mount the atmosphere code file system. */ R_TRY(fs::MountCodeForAtmosphereWithRedirection(std::addressof(m_ams_code_verification_data), AtmosphereCodeMountName, content_path, content_attributes, loc.program_id, static_cast(loc.storage_id), m_override_status.IsHbl(), m_override_status.IsProgramSpecific())); @@ -83,7 +83,7 @@ namespace ams::ldr { } /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) { + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs) { /* Check for storage id none. */ if (static_cast(loc.storage_id) == ncm::StorageId::None) { std::memset(out_path, 0, out_size); @@ -92,7 +92,7 @@ namespace ams::ldr { } /* Get the content attributes. */ - const auto content_attributes = GetPlatformContentAttributes(platform); + const auto content_attributes = attrs.content_attributes; AMS_UNUSED(content_attributes); lr::Path path; @@ -166,12 +166,4 @@ namespace ams::ldr { R_SUCCEED(); } - fs::ContentAttributes GetPlatformContentAttributes(ncm::ContentMetaPlatform platform) { - switch (platform) { - case ncm::ContentMetaPlatform::Nx: - return fs::ContentAttributes_None; - AMS_UNREACHABLE_DEFAULT_CASE(); - } - } - } diff --git a/stratosphere/loader/source/ldr_content_management.hpp b/stratosphere/loader/source/ldr_content_management.hpp index f44ef738e..d20c80709 100644 --- a/stratosphere/loader/source/ldr_content_management.hpp +++ b/stratosphere/loader/source/ldr_content_management.hpp @@ -34,8 +34,8 @@ namespace ams::ldr { bool m_mounted_sd_or_code; bool m_mounted_code; public: - ScopedCodeMount(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform); - ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, ncm::ContentMetaPlatform platform); + ScopedCodeMount(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); + ScopedCodeMount(const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const ldr::ProgramAttributes &attrs); ~ScopedCodeMount(); Result GetResult() const { @@ -59,7 +59,7 @@ namespace ams::ldr { return m_base_code_verification_data; } private: - Result Initialize(const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform); + Result Initialize(const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); void EnsureOverrideStatus(const ncm::ProgramLocation &loc); }; @@ -76,10 +76,8 @@ namespace ams::ldr { #define ENCODE_CMPT_PATH(relative) "cmpt:" relative /* Redirection API. */ - Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform); + Result GetProgramPath(char *out_path, size_t out_size, const ncm::ProgramLocation &loc, const ldr::ProgramAttributes &attrs); Result RedirectProgramPath(const char *path, size_t size, const ncm::ProgramLocation &loc); Result RedirectHtmlDocumentPathForHbl(const ncm::ProgramLocation &loc); - fs::ContentAttributes GetPlatformContentAttributes(ncm::ContentMetaPlatform platform); - } diff --git a/stratosphere/loader/source/ldr_loader_service.cpp b/stratosphere/loader/source/ldr_loader_service.cpp index b363d6b13..17a4a9160 100644 --- a/stratosphere/loader/source/ldr_loader_service.cpp +++ b/stratosphere/loader/source/ldr_loader_service.cpp @@ -27,72 +27,72 @@ namespace ams::ldr { constinit ArgumentStore g_argument_store; - bool IsValidPlatform(ncm::ContentMetaPlatform platform) { - return platform == ncm::ContentMetaPlatform::Nx; - } - - Result CreateProcessByPlatform(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) { - /* Check that the platform is valid. */ - R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); - - /* Get the location and override status. */ - ncm::ProgramLocation loc; - cfg::OverrideStatus override_status; - R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id)); - - /* Get the program path. */ - char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc, platform)); - path[sizeof(path) - 1] = '\x00'; - - /* Create the process. */ - R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, platform)); - } - - Result GetProgramInfoByPlatform(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, ncm::ContentMetaPlatform platform) { - /* Check that the platform is valid. */ - R_UNLESS(IsValidPlatform(platform), ldr::ResultInvalidPlatformId()); - - /* Zero output. */ - std::memset(out, 0, sizeof(*out)); - - /* Get the program path. */ - char path[fs::EntryNameLengthMax]; - R_TRY(GetProgramPath(path, sizeof(path), loc, platform)); - path[sizeof(path) - 1] = '\x00'; - - /* Get the program info. */ - cfg::OverrideStatus status; - R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, platform)); - - if (loc.program_id != out->program_id) { - /* Redirect the program path. */ - const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast(loc.storage_id)); - R_TRY(RedirectProgramPath(path, sizeof(path), new_loc)); - - /* Update the arguments, as needed. */ - if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) { - R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size)); - } + bool IsValidProgramAttributes(const ldr::ProgramAttributes &attrs) { + /* Check that the attributes are valid; on NX, this means Platform = NX + no content attrs. */ + if (attrs.platform != ncm::ContentMetaPlatform::Nx) { + return false; + } + if (attrs.content_attributes != fs::ContentAttributes_None) { + return false; } - /* If we should, set the output status. */ - if (out_status != nullptr) { - *out_status = status; - } - - R_SUCCEED(); + return true; } } - Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit) { - R_RETURN(CreateProcessByPlatform(out, pin_id, flags, resource_limit, ncm::ContentMetaPlatform::Nx)); + Result LoaderService::CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, const ProgramAttributes &attrs) { + /* Check that the program attributes are valid. */ + R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes()); + + /* Get the location and override status. */ + ncm::ProgramLocation loc; + cfg::OverrideStatus override_status; + R_TRY(ldr::GetProgramLocationAndOverrideStatusFromPinId(std::addressof(loc), std::addressof(override_status), pin_id)); + + /* Get the program path. */ + char path[fs::EntryNameLengthMax]; + R_TRY(GetProgramPath(path, sizeof(path), loc, attrs)); + path[sizeof(path) - 1] = '\x00'; + + /* Create the process. */ + R_RETURN(ldr::CreateProcess(out, pin_id, loc, override_status, path, g_argument_store.Get(loc.program_id), flags, resource_limit, attrs)); } - Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc) { - R_RETURN(GetProgramInfoByPlatform(out, out_status, loc, ncm::ContentMetaPlatform::Nx)); + Result LoaderService::GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { + /* Check that the program attributes are valid. */ + R_UNLESS(IsValidProgramAttributes(attrs), ldr::ResultInvalidProgramAttributes()); + + /* Zero output. */ + std::memset(out, 0, sizeof(*out)); + + /* Get the program path. */ + char path[fs::EntryNameLengthMax]; + R_TRY(GetProgramPath(path, sizeof(path), loc, attrs)); + path[sizeof(path) - 1] = '\x00'; + + /* Get the program info. */ + cfg::OverrideStatus status; + R_TRY(ldr::GetProgramInfo(out, std::addressof(status), loc, path, attrs)); + + if (loc.program_id != out->program_id) { + /* Redirect the program path. */ + const ncm::ProgramLocation new_loc = ncm::ProgramLocation::Make(out->program_id, static_cast(loc.storage_id)); + R_TRY(RedirectProgramPath(path, sizeof(path), new_loc)); + + /* Update the arguments, as needed. */ + if (const auto *entry = g_argument_store.Get(loc.program_id); entry != nullptr) { + R_TRY(g_argument_store.Set(new_loc.program_id, entry->argument, entry->argument_size)); + } + } + + /* If we should, set the output status. */ + if (out_status != nullptr) { + *out_status = status; + } + + R_SUCCEED(); } Result LoaderService::PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status) { diff --git a/stratosphere/loader/source/ldr_loader_service.hpp b/stratosphere/loader/source/ldr_loader_service.hpp index bad74cd80..9f5314c55 100644 --- a/stratosphere/loader/source/ldr_loader_service.hpp +++ b/stratosphere/loader/source/ldr_loader_service.hpp @@ -21,16 +21,16 @@ namespace ams::ldr { class LoaderService { public: /* Official commands. */ - Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h) { + Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle &&reslimit_h, const ProgramAttributes &attrs) { /* Create a handle to set the output to when done. */ os::NativeHandle handle = os::InvalidNativeHandle; ON_SCOPE_EXIT { proc_h.SetValue(handle, true); }; - R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle())); + R_RETURN(this->CreateProcess(std::addressof(handle), id, flags, reslimit_h.GetOsHandle(), attrs)); } - Result GetProgramInfo(sf::Out out_program_info, const ncm::ProgramLocation &loc) { - R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc)); + Result GetProgramInfo(sf::Out out_program_info, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { + R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), nullptr, loc, attrs)); } Result PinProgram(sf::Out out_id, const ncm::ProgramLocation &loc) { @@ -75,16 +75,16 @@ namespace ams::ldr { return this->HasLaunchedBootProgram(out.GetPointer(), program_id); } - Result AtmosphereGetProgramInfo(sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc) { - R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc)); + Result AtmosphereGetProgramInfo(sf::Out out_program_info, sf::Out out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs) { + R_RETURN(this->GetProgramInfo(out_program_info.GetPointer(), out_status.GetPointer(), loc, attrs)); } Result AtmospherePinProgram(sf::Out out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status) { R_RETURN(this->PinProgram(out_id.GetPointer(), loc, override_status)); } private: - Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, u32 flags, os::NativeHandle resource_limit, const ProgramAttributes &attrs); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const ProgramAttributes &attrs); Result PinProgram(PinId *out, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &status); Result SetProgramArgument(ncm::ProgramId program_id, const void *argument, size_t size); Result GetProcessModuleInfo(u32 *out_count, ModuleInfo *out, size_t max_out_count, os::ProcessId process_id); diff --git a/stratosphere/loader/source/ldr_process_creation.cpp b/stratosphere/loader/source/ldr_process_creation.cpp index ad94e85d6..5f6f2226b 100644 --- a/stratosphere/loader/source/ldr_process_creation.cpp +++ b/stratosphere/loader/source/ldr_process_creation.cpp @@ -664,15 +664,15 @@ namespace ams::ldr { } /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform) { + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, const ldr::ProgramAttributes &attrs) { /* Mount code. */ AMS_UNUSED(path); - ScopedCodeMount mount(loc, override_status, platform); + ScopedCodeMount mount(loc, override_status, attrs); R_TRY(mount.GetResult()); /* Load meta, possibly from cache. */ Meta meta; - R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, platform)); + R_TRY(LoadMetaFromCache(std::addressof(meta), loc, override_status, attrs.platform)); /* Validate meta. */ R_TRY(ValidateMeta(std::addressof(meta), loc, mount.GetCodeVerificationData())); @@ -720,16 +720,16 @@ namespace ams::ldr { R_SUCCEED(); } - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform) { + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs) { Meta meta; /* Load Meta. */ { AMS_UNUSED(path); - ScopedCodeMount mount(loc, platform); + ScopedCodeMount mount(loc, attrs); R_TRY(mount.GetResult()); - R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), platform, false)); + R_TRY(LoadMeta(std::addressof(meta), loc, mount.GetOverrideStatus(), attrs.platform, false)); if (out_status != nullptr) { *out_status = mount.GetOverrideStatus(); } diff --git a/stratosphere/loader/source/ldr_process_creation.hpp b/stratosphere/loader/source/ldr_process_creation.hpp index 5e224a72a..0d24c7720 100644 --- a/stratosphere/loader/source/ldr_process_creation.hpp +++ b/stratosphere/loader/source/ldr_process_creation.hpp @@ -19,8 +19,8 @@ namespace ams::ldr { /* Process Creation API. */ - Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, ncm::ContentMetaPlatform platform); - Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, ncm::ContentMetaPlatform platform); + Result CreateProcess(os::NativeHandle *out, PinId pin_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status, const char *path, const ArgumentStore::Entry *argument, u32 flags, os::NativeHandle resource_limit, const ldr::ProgramAttributes &attrs); + Result GetProgramInfo(ProgramInfo *out, cfg::OverrideStatus *out_status, const ncm::ProgramLocation &loc, const char *path, const ldr::ProgramAttributes &attrs); Result PinProgram(PinId *out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status); Result UnpinProgram(PinId id); diff --git a/stratosphere/pm/source/impl/pm_process_attributes.hpp b/stratosphere/pm/source/impl/pm_process_attributes.hpp new file mode 100644 index 000000000..b622be264 --- /dev/null +++ b/stratosphere/pm/source/impl/pm_process_attributes.hpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::pm::impl { + + struct ProcessAttributes { + u8 unknown[3]; + ldr::ProgramAttributes program_attrs; + }; + static_assert(sizeof(ProcessAttributes) == 5); + + constexpr inline ProcessAttributes ProcessAttributes_Nx = { + .unknown = {}, + .program_attrs = { + .platform = ncm::ContentMetaPlatform::Nx, + .content_attributes = fs::ContentAttributes_None, + }, + }; + +} diff --git a/stratosphere/pm/source/impl/pm_process_info.cpp b/stratosphere/pm/source/impl/pm_process_info.cpp index 90373b55a..d472803dc 100644 --- a/stratosphere/pm/source/impl/pm_process_info.cpp +++ b/stratosphere/pm/source/impl/pm_process_info.cpp @@ -76,7 +76,7 @@ namespace ams::pm::impl { } - ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : m_process_id(pid), m_pin_id(pin), m_loc(l), m_status(s), m_handle(h), m_state(svc::ProcessState_Created), m_flags(0) { + ProcessInfo::ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s, const ProcessAttributes &attrs) : m_process_id(pid), m_pin_id(pin), m_loc(l), m_status(s), m_handle(h), m_state(svc::ProcessState_Created), m_flags(0), m_attrs(attrs) { os::InitializeMultiWaitHolder(std::addressof(m_multi_wait_holder), m_handle); os::SetMultiWaitHolderUserData(std::addressof(m_multi_wait_holder), reinterpret_cast(this)); } @@ -106,8 +106,8 @@ namespace ams::pm::impl { return ProcessListAccessor(g_exit_list); } - ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status) { - return g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status); + ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status, const ProcessAttributes &attrs) { + return g_process_info_allocator.AllocateProcessInfo(process_handle, process_id, pin_id, location, override_status, attrs); } void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info) { diff --git a/stratosphere/pm/source/impl/pm_process_info.hpp b/stratosphere/pm/source/impl/pm_process_info.hpp index f2dae02ae..66e64c436 100644 --- a/stratosphere/pm/source/impl/pm_process_info.hpp +++ b/stratosphere/pm/source/impl/pm_process_info.hpp @@ -15,6 +15,7 @@ */ #pragma once #include "pm_process_manager.hpp" +#include "pm_process_attributes.hpp" namespace ams::pm::impl { @@ -46,6 +47,7 @@ namespace ams::pm::impl { os::NativeHandle m_handle; svc::ProcessState m_state; u32 m_flags; + ProcessAttributes m_attrs; os::MultiWaitHolderType m_multi_wait_holder; private: void SetFlag(Flag flag) { @@ -60,7 +62,7 @@ namespace ams::pm::impl { return (m_flags & flag); } public: - ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s); + ProcessInfo(os::NativeHandle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s, const ProcessAttributes &attrs); ~ProcessInfo(); void Cleanup(); @@ -88,6 +90,10 @@ namespace ams::pm::impl { return m_status; } + const ProcessAttributes &GetProcessAttributes() const { + return m_attrs; + } + svc::ProcessState GetState() const { return m_state; } @@ -235,7 +241,7 @@ namespace ams::pm::impl { ProcessListAccessor GetProcessList(); ProcessListAccessor GetExitList(); - ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status); + ProcessInfo *AllocateProcessInfo(svc::Handle process_handle, os::ProcessId process_id, ldr::PinId pin_id, const ncm::ProgramLocation &location, const cfg::OverrideStatus &override_status, const ProcessAttributes &attrs); void CleanupProcessInfo(ProcessListAccessor &list, ProcessInfo *process_info); } diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 32ef0feac..50600f0d4 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -117,14 +117,14 @@ namespace ams::pm::impl { R_SUCCEED(); } - Result LaunchProgramImpl(ProcessInfo **out_process_info, os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags) { + Result LaunchProgramImpl(ProcessInfo **out_process_info, os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags, const ProcessAttributes &attrs) { /* Set the output to nullptr, if we fail. */ *out_process_info = nullptr; /* Get Program Info. */ ldr::ProgramInfo program_info; cfg::OverrideStatus override_status; - R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), loc)); + R_TRY(ldr::pm::AtmosphereGetProgramInfo(std::addressof(program_info), std::addressof(override_status), loc, attrs.program_attrs)); const bool is_application = (program_info.flags & ldr::ProgramInfoFlag_ApplicationTypeMask) == ldr::ProgramInfoFlag_Application; const bool allow_debug = (program_info.flags & ldr::ProgramInfoFlag_AllowDebug) || hos::GetVersion() < hos::Version_2_0_0; @@ -166,14 +166,14 @@ namespace ams::pm::impl { WaitResourceAvailable(std::addressof(program_info)); /* Actually create the process. */ - R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(flags), GetResourceLimitHandle(std::addressof(program_info)))); + R_TRY(ldr::pm::CreateProcess(std::addressof(process_handle), pin_id, GetLoaderCreateProcessFlags(flags), GetResourceLimitHandle(std::addressof(program_info)), attrs.program_attrs)); } /* Get the process id. */ os::ProcessId process_id = os::GetProcessId(process_handle); /* Make new process info. */ - ProcessInfo *process_info = AllocateProcessInfo(process_handle, process_id, pin_id, fixed_location, override_status); + ProcessInfo *process_info = AllocateProcessInfo(process_handle, process_id, pin_id, fixed_location, override_status, attrs); AMS_ABORT_UNLESS(process_info != nullptr); /* Add the new process info to the process list. */ @@ -253,7 +253,7 @@ namespace ams::pm::impl { Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 flags) { /* Launch the program. */ ProcessInfo *process_info = nullptr; - R_TRY(LaunchProgramImpl(std::addressof(process_info), out_process_id, loc, flags)); + R_TRY(LaunchProgramImpl(std::addressof(process_info), out_process_id, loc, flags, ProcessAttributes_Nx)); /* Register the process info with the tracker. */ g_process_tracker.QueueEntry(process_info); @@ -268,7 +268,7 @@ namespace ams::pm::impl { R_UNLESS(!process_info->HasStarted(), pm::ResultAlreadyStarted()); ldr::ProgramInfo program_info; - R_TRY(ldr::pm::GetProgramInfo(std::addressof(program_info), process_info->GetProgramLocation())); + R_TRY(ldr::pm::GetProgramInfo(std::addressof(program_info), process_info->GetProgramLocation(), process_info->GetProcessAttributes().program_attrs)); R_RETURN(StartProcess(process_info, std::addressof(program_info))); } From 3af8757c3b61a0e2d00dfbffc3abced4e22b841e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 1 May 2025 20:41:56 -0700 Subject: [PATCH 201/238] erpt: initial support (incomplete) for 20.0.0 --- .../erpt/sf/erpt_sf_i_context.hpp | 42 ++++++++++--------- .../erpt/sf/erpt_sf_i_manager.hpp | 17 ++++---- .../source/erpt/srv/erpt_srv_context_impl.cpp | 32 +++++++++++++- .../source/erpt/srv/erpt_srv_context_impl.hpp | 2 + .../erpt/srv/erpt_srv_forced_shutdown.cpp | 2 +- .../source/erpt/srv/erpt_srv_journal.cpp | 4 +- .../source/erpt/srv/erpt_srv_journal.hpp | 4 +- .../srv/erpt_srv_journal_for_attachments.cpp | 13 ++++-- .../source/erpt/srv/erpt_srv_manager_impl.cpp | 17 +++++++- .../source/erpt/srv/erpt_srv_manager_impl.hpp | 4 +- .../source/erpt/srv/erpt_srv_reporter.cpp | 8 ++-- .../source/erpt/srv/erpt_srv_reporter.hpp | 4 +- 12 files changed, 102 insertions(+), 47 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp index 784bcc9da..a4fcc4dc6 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_context.hpp @@ -20,26 +20,28 @@ #include #include -#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \ - AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ - AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ - AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ - AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ - AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) +#define AMS_ERPT_I_CONTEXT_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, SubmitContext, (const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer), (ctx_buffer, str_buffer)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, CreateReportV0, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer), (report_type, ctx_buffer, str_buffer, meta_buffer)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetInitialLaunchSettingsCompletionTime, (const time::SteadyClockTimePoint &time_point), (time_point), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, ClearInitialLaunchSettingsCompletionTime, (), (), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, UpdatePowerOnTime, (), (), hos::Version_3_0_0) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, UpdateAwakeTime, (), (), hos::Version_3_0_0, hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, SubmitMultipleCategoryContext, (const erpt::MultipleCategoryContextEntry &ctx_entry, const ams::sf::InBuffer &str_buffer), (ctx_entry, str_buffer), hos::Version_5_0_0, hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 7, Result, UpdateApplicationLaunchTime, (), (), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 8, Result, ClearApplicationLaunchTime, (), (), hos::Version_6_0_0) \ + AMS_SF_METHOD_INFO(C, H, 9, Result, SubmitAttachment, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_8_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer), hos::Version_8_0_0, hos::Version_10_2_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachmentsDeprecated2, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result), hos::Version_11_0_0, hos::Version_16_1_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, CreateReportWithAttachments, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, attachment_ids_buffer, result, flags), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 11, Result, CreateReportV1, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result), (report_type, ctx_buffer, str_buffer, meta_buffer, result), hos::Version_11_0_0) \ + AMS_SF_METHOD_INFO(C, H, 12, Result, CreateReport, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags), (report_type, ctx_buffer, str_buffer, meta_buffer, result, flags), hos::Version_17_0_0) \ + AMS_SF_METHOD_INFO(C, H, 13, Result, SubmitAttachmentWithLz4Compression, (ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data), (out, attachment_name, attachment_data), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 14, Result, CreateReportWithSpecifiedReprotId, (erpt::ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &str_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const erpt::ReportId &report_id), (report_type, ctx_buffer, str_buffer, meta_buffer, attachment_ids_buffer, result, flags, report_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 20, Result, RegisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 21, Result, UnregisterRunningApplet, (ncm::ProgramId program_id), (program_id), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 22, Result, UpdateAppletSuspendedDuration, (ncm::ProgramId program_id, TimeSpanType duration), (program_id, duration), hos::Version_12_0_0) \ + AMS_SF_METHOD_INFO(C, H, 30, Result, InvalidateForcedShutdownDetection, (), (), hos::Version_12_0_0) AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IContext, AMS_ERPT_I_CONTEXT_INTERFACE_INFO, 0xDD41DD03) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp index e8ed06310..e75bfb341 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/sf/erpt_sf_i_manager.hpp @@ -17,13 +17,16 @@ #include #include -#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \ - AMS_SF_METHOD_INFO(C, H, 0, Result, GetReportList, (const ams::sf::OutBuffer &out_list, erpt::ReportType type_filter), (out_list, type_filter)) \ - AMS_SF_METHOD_INFO(C, H, 1, Result, GetEvent, (ams::sf::OutCopyHandle out), (out)) \ - AMS_SF_METHOD_INFO(C, H, 2, Result, CleanupReports, (), (), hos::Version_4_0_0) \ - AMS_SF_METHOD_INFO(C, H, 3, Result, DeleteReport, (const erpt::ReportId &report_id), (report_id), hos::Version_5_0_0) \ - AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out out), (out), hos::Version_5_0_0) \ - AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentList, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0) +#define AMS_ERPT_I_MANAGER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, GetReportList, (const ams::sf::OutBuffer &out_list, erpt::ReportType type_filter), (out_list, type_filter)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, GetEvent, (ams::sf::OutCopyHandle out), (out)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, CleanupReports, (), (), hos::Version_4_0_0) \ + AMS_SF_METHOD_INFO(C, H, 3, Result, DeleteReport, (const erpt::ReportId &report_id), (report_id), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 4, Result, GetStorageUsageStatistics, (ams::sf::Out out), (out), hos::Version_5_0_0) \ + AMS_SF_METHOD_INFO(C, H, 5, Result, GetAttachmentListDeprecated, (const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_buf, report_id), hos::Version_8_0_0, hos::Version_19_0_1) \ + AMS_SF_METHOD_INFO(C, H, 6, Result, GetAttachmentList, (ams::sf::Out out_count, const ams::sf::OutBuffer &out_buf, const erpt::ReportId &report_id), (out_count, out_buf, report_id), hos::Version_20_0_0) \ + AMS_SF_METHOD_INFO(C, H, 10, Result, GetReportSizeMax, (ams::sf::Out out), (out), hos::Version_20_0_0) + AMS_SF_DEFINE_INTERFACE(ams::erpt::sf, IManager, AMS_ERPT_I_MANAGER_INTERFACE_INFO, 0x5CFCC43F) diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp index 695b12229..77a39a5c5 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.cpp @@ -50,7 +50,7 @@ namespace ams::erpt::srv { R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument()); - R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, nullptr, 0, flags, nullptr)); ManagerImpl::NotifyAll(); @@ -142,6 +142,11 @@ namespace ams::erpt::srv { R_RETURN(JournalForAttachments::SubmitAttachment(out.GetPointer(), name_safe, data, data_size)); } + Result ContextImpl::SubmitAttachmentWithLz4Compression(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data) { + /* TODO: Implement LZ4 compression on attachments. */ + R_RETURN(this->SubmitAttachment(out, attachment_name, attachment_data)); + } + Result ContextImpl::CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags) { const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); const u8 *data = reinterpret_cast(data_buffer.GetPointer()); @@ -154,7 +159,7 @@ namespace ams::erpt::srv { R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument()); - R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags)); + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, nullptr, attachments, num_attachments, flags, nullptr)); ManagerImpl::NotifyAll(); @@ -169,6 +174,29 @@ namespace ams::erpt::srv { R_RETURN(this->CreateReportWithAttachmentsDeprecated2(report_type, ctx_buffer, data_buffer, attachment_ids_buffer, ResultSuccess())); } + Result ContextImpl::CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id) { + const ContextEntry *ctx = reinterpret_cast( ctx_buffer.GetPointer()); + const u8 *data = reinterpret_cast(data_buffer.GetPointer()); + const ReportMetaData *meta = reinterpret_cast(meta_buffer.GetPointer()); + + const u32 ctx_size = static_cast(ctx_buffer.GetSize()); + const u32 data_size = static_cast(data_buffer.GetSize()); + const u32 meta_size = static_cast(meta_buffer.GetSize()); + + const AttachmentId *attachments = reinterpret_cast(attachment_ids_buffer.GetPointer()); + const u32 num_attachments = attachment_ids_buffer.GetSize() / sizeof(*attachments); + + R_UNLESS(ctx_size == sizeof(ContextEntry), erpt::ResultInvalidArgument()); + R_UNLESS(meta_size == 0 || meta_size == sizeof(ReportMetaData), erpt::ResultInvalidArgument()); + R_UNLESS(num_attachments <= AttachmentsPerReportMax, erpt::ResultInvalidArgument()); + + R_TRY(Reporter::CreateReport(report_type, result, ctx, data, data_size, meta_size != 0 ? meta : nullptr, attachments, num_attachments, flags, std::addressof(report_id))); + + ManagerImpl::NotifyAll(); + + R_SUCCEED(); + } + Result ContextImpl::RegisterRunningApplet(ncm::ProgramId program_id) { R_RETURN(Reporter::RegisterRunningApplet(program_id)); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp index d6c98c94b..cada2ceb2 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_context_impl.hpp @@ -35,6 +35,8 @@ namespace ams::erpt::srv { Result CreateReportWithAttachments(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &attachment_ids_buffer, Result result, erpt::CreateReportOptionFlagSet flags); Result CreateReportV1(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result); Result CreateReport(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, Result result, erpt::CreateReportOptionFlagSet flags); + Result SubmitAttachmentWithLz4Compression(ams::sf::Out out, const ams::sf::InBuffer &attachment_name, const ams::sf::InBuffer &attachment_data); + Result CreateReportWithSpecifiedReprotId(ReportType report_type, const ams::sf::InBuffer &ctx_buffer, const ams::sf::InBuffer &data_buffer, const ams::sf::InBuffer &meta_buffer, const ams::sf::InBuffer &attachment_data, Result result, erpt::CreateReportOptionFlagSet flags, const ReportId &report_id); Result RegisterRunningApplet(ncm::ProgramId program_id); Result UnregisterRunningApplet(ncm::ProgramId program_id); Result UpdateAppletSuspendedDuration(ncm::ProgramId program_id, TimeSpanType duration); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp index 0b116f7ba..c41e04f36 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_forced_shutdown.cpp @@ -86,7 +86,7 @@ namespace ams::erpt::srv { R_TRY(record->Add(FieldId_ErrorCode, error_code_str, std::strlen(error_code_str))); /* Create report. */ - R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags())); + R_TRY(Reporter::CreateReport(ReportType_Invisible, ResultSuccess(), std::move(record), nullptr, nullptr, 0, erpt::srv::MakeNoCreateReportOptionFlags(), nullptr)); R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp index 446ccafca..84dd89f53 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.cpp @@ -51,8 +51,8 @@ namespace ams::erpt::srv { R_RETURN(JournalForReports::DeleteReport(report_id)); } - Result Journal::GetAttachmentList(AttachmentList *out, ReportId report_id) { - R_RETURN(JournalForAttachments::GetAttachmentList(out, report_id)); + Result Journal::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) { + R_RETURN(JournalForAttachments::GetAttachmentList(out_count, out_infos, max_out_infos, report_id)); } util::Uuid Journal::GetJournalId() { diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp index 5adfa87c0..16011e75a 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal.hpp @@ -82,7 +82,7 @@ namespace ams::erpt::srv { static void CleanupAttachments(); static Result CommitJournal(Stream *stream); static Result DeleteAttachments(ReportId report_id); - static Result GetAttachmentList(AttachmentList *out, ReportId report_id); + static Result GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id); static u32 GetUsedStorage(); static Result RestoreJournal(Stream *stream); @@ -99,7 +99,7 @@ namespace ams::erpt::srv { static void CleanupReports(); static Result Commit(); static Result Delete(ReportId report_id); - static Result GetAttachmentList(AttachmentList *out, ReportId report_id); + static Result GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id); static util::Uuid GetJournalId(); static s64 GetMaxReportSize(); static Result GetReportList(ReportList *out, ReportType type_filter); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp index 4a7c75570..402951380 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_journal_for_attachments.cpp @@ -77,14 +77,19 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result JournalForAttachments::GetAttachmentList(AttachmentList *out, ReportId report_id) { + Result JournalForAttachments::GetAttachmentList(u32 *out_count, AttachmentInfo *out_infos, size_t max_out_infos, ReportId report_id) { + if (hos::GetVersion() >= hos::Version_20_0_0) { + /* TODO: What define gives a minimum of 10? */ + R_UNLESS(max_out_infos >= 10, erpt::ResultInvalidArgument()); + } + u32 count = 0; - for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < util::size(out->attachments); it++) { + for (auto it = s_attachment_list.cbegin(); it != s_attachment_list.cend() && count < max_out_infos; it++) { if (report_id == it->m_info.owner_report_id) { - out->attachments[count++] = it->m_info; + out_infos[count++] = it->m_info; } } - out->attachment_count = count; + *out_count = count; R_SUCCEED(); } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp index 144507e42..2130a5200 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.cpp @@ -86,10 +86,23 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result ManagerImpl::GetAttachmentList(const ams::sf::OutBuffer &out_list, const ReportId &report_id) { + Result ManagerImpl::GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_list, const ReportId &report_id) { R_UNLESS(out_list.GetSize() == sizeof(AttachmentList), erpt::ResultInvalidArgument()); - R_RETURN(Journal::GetAttachmentList(reinterpret_cast(out_list.GetPointer()), report_id)); + auto *attachment_list = reinterpret_cast(out_list.GetPointer()); + + R_RETURN(Journal::GetAttachmentList(std::addressof(attachment_list->attachment_count), attachment_list->attachments, util::size(attachment_list->attachments), report_id)); + } + + Result ManagerImpl::GetAttachmentList(ams::sf::Out out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id) { + R_RETURN(Journal::GetAttachmentList(out_count.GetPointer(), reinterpret_cast(out_buf.GetPointer()), out_buf.GetSize() / sizeof(AttachmentInfo), report_id)); + } + + Result ManagerImpl::GetReportSizeMax(ams::sf::Out out) { + /* TODO: Where is this size defined? */ + constexpr size_t ReportSizeMax = 0x3FF4F; + *out = ReportSizeMax; + R_SUCCEED(); } } diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp index bbf0c254e..24046b29b 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_manager_impl.hpp @@ -34,7 +34,9 @@ namespace ams::erpt::srv { Result CleanupReports(); Result DeleteReport(const ReportId &report_id); Result GetStorageUsageStatistics(ams::sf::Out out); - Result GetAttachmentList(const ams::sf::OutBuffer &out_buf, const ReportId &report_id); + Result GetAttachmentListDeprecated(const ams::sf::OutBuffer &out_buf, const ReportId &report_id); + Result GetAttachmentList(ams::sf::Out out_count, const ams::sf::OutBuffer &out_buf, const ReportId &report_id); + Result GetReportSizeMax(ams::sf::Out out); }; static_assert(erpt::sf::IsIManager); diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp index eb291db67..a9a2871c6 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.cpp @@ -414,7 +414,7 @@ namespace ams::erpt::srv { R_SUCCEED(); } - Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) { /* Create a context record for the report. */ auto record = std::make_unique(); R_UNLESS(record != nullptr, erpt::ResultOutOfMemory()); @@ -423,10 +423,10 @@ namespace ams::erpt::srv { R_TRY(record->Initialize(ctx, data, data_size)); /* Create the report. */ - R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags)); + R_RETURN(CreateReport(type, ctx_result, std::move(record), meta, attachments, num_attachments, flags, specified_report_id)); } - Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags) { + Result Reporter::CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id) { /* Clear the automatic categories, when we're done with our report. */ ON_SCOPE_EXIT { Context::ClearContext(CategoryId_ErrorInfo); @@ -444,7 +444,7 @@ namespace ams::erpt::srv { R_TRY(SubmitReportDefaults(ctx)); /* Generate report id. */ - const ReportId report_id = { .uuid = util::GenerateUuid() }; + const ReportId report_id = specified_report_id ? *specified_report_id : ReportId{ .uuid = util::GenerateUuid() }; /* Get posix timestamps. */ time::PosixTime timestamp_user; diff --git a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp index 11913dbd5..f5db475ec 100644 --- a/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp +++ b/libraries/libstratosphere/source/erpt/srv/erpt_srv_reporter.hpp @@ -58,8 +58,8 @@ namespace ams::erpt::srv { private: static Result SubmitReportContexts(const ReportId &report_id, ReportType type, Result ctx_result, std::unique_ptr record, const time::PosixTime &user_timestamp, const time::PosixTime &network_timestamp, erpt::CreateReportOptionFlagSet flags); public: - static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags); - static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags); + static Result CreateReport(ReportType type, Result ctx_result, const ContextEntry *ctx, const u8 *data, u32 data_size, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id); + static Result CreateReport(ReportType type, Result ctx_result, std::unique_ptr record, const ReportMetaData *meta, const AttachmentId *attachments, u32 num_attachments, erpt::CreateReportOptionFlagSet flags, const ReportId *specified_report_id); }; } From a6847ca70e185c384a13a2f5c61abeda93cddd8c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 2 May 2025 17:30:05 -0700 Subject: [PATCH 202/238] ams: add enum support for 20.0.1/18.0.1 --- .../libstratosphere/include/stratosphere/hos/hos_types.hpp | 2 ++ .../libvapours/include/vapours/ams/ams_target_firmware.h | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index cf455c814..66be2b66a 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -83,10 +83,12 @@ namespace ams::hos { Version_17_0_0 = ::ams::TargetFirmware_17_0_0, Version_17_0_1 = ::ams::TargetFirmware_17_0_1, Version_18_0_0 = ::ams::TargetFirmware_18_0_0, + Version_18_0_1 = ::ams::TargetFirmware_18_0_1, Version_18_1_0 = ::ams::TargetFirmware_18_1_0, Version_19_0_0 = ::ams::TargetFirmware_19_0_0, Version_19_0_1 = ::ams::TargetFirmware_19_0_1, Version_20_0_0 = ::ams::TargetFirmware_20_0_0, + Version_20_0_1 = ::ams::TargetFirmware_20_0_1, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 0dcbac068..755fc6387 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -81,12 +81,14 @@ #define ATMOSPHERE_TARGET_FIRMWARE_17_0_0 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_17_0_1 ATMOSPHERE_TARGET_FIRMWARE(17, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_18_0_0 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_18_0_1 ATMOSPHERE_TARGET_FIRMWARE(18, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_18_1_0 ATMOSPHERE_TARGET_FIRMWARE(18, 1, 0) #define ATMOSPHERE_TARGET_FIRMWARE_19_0_0 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_19_0_1 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_20_0_0 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_20_0_1 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 1) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_0_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_0_1 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -160,10 +162,12 @@ namespace ams { TargetFirmware_17_0_0 = ATMOSPHERE_TARGET_FIRMWARE_17_0_0, TargetFirmware_17_0_1 = ATMOSPHERE_TARGET_FIRMWARE_17_0_1, TargetFirmware_18_0_0 = ATMOSPHERE_TARGET_FIRMWARE_18_0_0, + TargetFirmware_18_0_1 = ATMOSPHERE_TARGET_FIRMWARE_18_0_1, TargetFirmware_18_1_0 = ATMOSPHERE_TARGET_FIRMWARE_18_1_0, TargetFirmware_19_0_0 = ATMOSPHERE_TARGET_FIRMWARE_19_0_0, TargetFirmware_19_0_1 = ATMOSPHERE_TARGET_FIRMWARE_19_0_1, TargetFirmware_20_0_0 = ATMOSPHERE_TARGET_FIRMWARE_20_0_0, + TargetFirmware_20_0_1 = ATMOSPHERE_TARGET_FIRMWARE_20_0_1, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From bc44ffe70d4d86153c94100cb01495e0f21fc75d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 2 May 2025 17:40:02 -0700 Subject: [PATCH 203/238] emummc: fix offsets for 20.0.0-exfat --- emummc/source/FS/offsets/2000_exfat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emummc/source/FS/offsets/2000_exfat.h b/emummc/source/FS/offsets/2000_exfat.h index 97b04c67b..a8245a2a7 100644 --- a/emummc/source/FS/offsets/2000_exfat.h +++ b/emummc/source/FS/offsets/2000_exfat.h @@ -35,7 +35,7 @@ #define FS_OFFSET_2000_EXFAT_UNLOCK_MUTEX 0x1A86F0 #define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF500 -#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF880 +#define FS_OFFSET_2000_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF520 // Misc Data #define FS_OFFSET_2000_EXFAT_SD_MUTEX 0x1006408 From b7ec64ea164b85a72902f05664bc95c90ae585f1 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 2 May 2025 20:17:16 -0700 Subject: [PATCH 204/238] fs.mitm: add and use memlet module to temporarily steal applet memory while building romfs images. Starting in 20.0.0, the browser needs more applet memory to function, so we can't steal as much any more. Thus, we now steal 14 MB on 20.0.0+ instead of 40MB. However, since this reduces memory available for custom system modules, we are adjusting to compensate. ams.mitm's heap size has been reduced from 32MB to 12MB (recovering 20MB). In addition, fs.mitm now uses a new mechanism for stealing memory from the applet pool while romfs is being built. On net, we are compromising: * Custom sysmodules lose memory available to them. On 19.0.0/AMS 1.8.0, there was 30 MB available for custom sysmodules. Stealing 14 MB instead of 40 MB, we lose 26 MB of that. Reducing ams.mitm's usage will gain us back 20. Nintendo also appears to...use 4 extra MB, in 20.0.0, from my test homebrew. So on 20.0.0/AMS 1.9.0, there should be 20 MB available for custom sysmodules. On the bright side, on <20.0.0/AMS 1.9.0, I guess there will be 50 MB available for custom sysmodules now? * totk mods will lose the ability to...put every file in the romfs on sd card. There will be some unknown maximum filecount for totk mods. On the bright side, implementing the transient memory stealing should improve compatibility for some mods which strictly add files? --- atmosphere.mk | 3 + .../nintendo/nx/kern_k_system_control.cpp | 4 +- .../impl/ams_system_thread_definitions.hpp | 2 + .../ncm/ncm_system_content_meta_id.hpp | 4 +- .../boot2/boot2_api.board.nintendo_nx.cpp | 3 + .../impl/os_shared_memory_impl.os.horizon.cpp | 1 + stratosphere/ams_mitm/source/amsmitm_main.cpp | 2 +- .../ams_mitm/source/fs_mitm/fsmitm_romfs.cpp | 93 ++++++++++++- .../ams_mitm/source/fs_mitm/memlet/memlet.c | 41 ++++++ .../ams_mitm/source/fs_mitm/memlet/memlet.h | 32 +++++ .../source/fs_mitm/memlet/service_guard.h | 65 +++++++++ stratosphere/memlet/Makefile | 41 ++++++ stratosphere/memlet/memlet.json | 93 +++++++++++++ stratosphere/memlet/source/memlet_main.cpp | 75 ++++++++++ stratosphere/memlet/source/memlet_service.cpp | 58 ++++++++ stratosphere/memlet/source/memlet_service.hpp | 32 +++++ stratosphere/memlet/system_module.mk | 131 ++++++++++++++++++ stratosphere/pm/source/impl/pm_spec.cpp | 2 +- stratosphere/stratosphere.mk | 2 +- 19 files changed, 672 insertions(+), 12 deletions(-) create mode 100644 stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c create mode 100644 stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h create mode 100644 stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h create mode 100644 stratosphere/memlet/Makefile create mode 100644 stratosphere/memlet/memlet.json create mode 100644 stratosphere/memlet/source/memlet_main.cpp create mode 100644 stratosphere/memlet/source/memlet_service.cpp create mode 100644 stratosphere/memlet/source/memlet_service.hpp create mode 100644 stratosphere/memlet/system_module.mk diff --git a/atmosphere.mk b/atmosphere.mk index cca6fc106..846ca1c22 100644 --- a/atmosphere.mk +++ b/atmosphere.mk @@ -50,6 +50,7 @@ dist: dist-no-debug cp $(CURRENT_DIRECTORY)/stratosphere/sm/$(ATMOSPHERE_OUT_DIR)/sm.elf $(DIST_DIR)/sm.elf cp $(CURRENT_DIRECTORY)/stratosphere/spl/$(ATMOSPHERE_OUT_DIR)/spl.elf $(DIST_DIR)/spl.elf cp $(CURRENT_DIRECTORY)/stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.elf $(DIST_DIR)/TioServer.elf + cp $(CURRENT_DIRECTORY)/stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.elf $(DIST_DIR)/memlet.elf cp $(CURRENT_DIRECTORY)/troposphere/daybreak/daybreak.elf $(DIST_DIR)/daybreak.elf cp $(CURRENT_DIRECTORY)/troposphere/haze/haze.elf $(DIST_DIR)/haze.elf cp $(CURRENT_DIRECTORY)/troposphere/reboot_to_payload/reboot_to_payload.elf $(DIST_DIR)/reboot_to_payload.elf @@ -87,6 +88,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) #mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000003c mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000042 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000420 + mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609 mkdir -p $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623 @@ -104,6 +106,7 @@ dist-no-debug: package3 $(CURRENT_DIRECTORY)/$(ATMOSPHERE_OUT_DIR) cp stratosphere/htc/$(ATMOSPHERE_OUT_DIR)/htc.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000b240/exefs.nsp cp stratosphere/dmnt.gen2/$(ATMOSPHERE_OUT_DIR)/dmnt.gen2.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d609/exefs.nsp cp stratosphere/TioServer/$(ATMOSPHERE_OUT_DIR)/TioServer.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/010000000000d623/exefs.nsp + cp stratosphere/memlet/$(ATMOSPHERE_OUT_DIR)/memlet.nsp $(DIST_DIR)/stratosphere_romfs/atmosphere/contents/0100000000000421/exefs.nsp @build_romfs $(DIST_DIR)/stratosphere_romfs $(DIST_DIR)/atmosphere/stratosphere.romfs rm -r $(DIST_DIR)/stratosphere_romfs cp troposphere/reboot_to_payload/reboot_to_payload.nro $(DIST_DIR)/switch/reboot_to_payload.nro diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp index 22e99faf0..58e86f152 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp @@ -361,7 +361,9 @@ namespace ams::kern::board::nintendo::nx { }(); /* Return (possibly) adjusted size. */ - constexpr size_t ExtraSystemMemoryForAtmosphere = 40_MB; + /* NOTE: On 20.0.0+ the browser requires much more memory in the applet pool in order to function. */ + /* Thus, we have to reduce our extra system memory size by 26 MB to compensate. */ + const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB; return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize; } diff --git a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp index d51eb90e8..ca1c5cb5d 100644 --- a/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp +++ b/libraries/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp @@ -171,6 +171,8 @@ namespace ams::impl { AMS_DEFINE_SYSTEM_THREAD(21, TioServer, FileServerHtcsServer); AMS_DEFINE_SYSTEM_THREAD(21, TioServer, SdCardObserver); + AMS_DEFINE_SYSTEM_THREAD(16, memlet, Main); + /* ServiceProfile */ AMS_DEFINE_SYSTEM_THREAD(-1, sprofile, IpcServer); diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp index b02c38fc5..b8e7bcd41 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_system_content_meta_id.hpp @@ -121,13 +121,15 @@ namespace ams::ncm { static const AtmosphereProgramId Mitm; static const AtmosphereProgramId AtmosphereLogManager; + static const AtmosphereProgramId AtmosphereMemlet; }; inline constexpr const AtmosphereProgramId AtmosphereProgramId::Mitm = { 0x010041544D530000ul }; inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereLogManager = { 0x0100000000000420ul }; + inline constexpr const AtmosphereProgramId AtmosphereProgramId::AtmosphereMemlet = { 0x0100000000000421ul }; inline constexpr bool IsAtmosphereProgramId(const ProgramId &program_id) { - return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager; + return program_id == AtmosphereProgramId::Mitm || program_id == AtmosphereProgramId::AtmosphereLogManager || program_id == AtmosphereProgramId::AtmosphereMemlet; } inline constexpr bool IsSystemProgramId(const AtmosphereProgramId &) { diff --git a/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp b/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp index e5f27fce6..5f7f296a6 100644 --- a/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp +++ b/libraries/libstratosphere/source/boot2/boot2_api.board.nintendo_nx.cpp @@ -450,6 +450,9 @@ namespace ams::boot2 { LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::SystemProgramId::Migration, ncm::StorageId::BuiltInSystem), 0); } + /* Launch atmosphere's applet memory service program. */ + LaunchProgram(nullptr, ncm::ProgramLocation::Make(ncm::AtmosphereProgramId::AtmosphereMemlet, ncm::StorageId::None), 0); + /* Launch user programs off of the SD. */ LaunchFlaggedProgramsOnSdCard(); } diff --git a/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp b/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp index b336576f1..94450ef26 100644 --- a/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp +++ b/libraries/libstratosphere/source/os/impl/os_shared_memory_impl.os.horizon.cpp @@ -43,6 +43,7 @@ namespace ams::os::impl { R_TRY_CATCH(svc::CreateSharedMemory(std::addressof(handle), size, svc_my_perm, svc_other_perm)) { R_CONVERT(svc::ResultOutOfHandles, os::ResultOutOfHandles()) R_CONVERT(svc::ResultOutOfResource, os::ResultOutOfResource()) + R_CONVERT(svc::ResultLimitReached, os::ResultOutOfMemory()) } R_END_TRY_CATCH_WITH_ABORT_UNLESS; *out = handle; diff --git a/stratosphere/ams_mitm/source/amsmitm_main.cpp b/stratosphere/ams_mitm/source/amsmitm_main.cpp index 97e735f6e..9e0538135 100644 --- a/stratosphere/ams_mitm/source/amsmitm_main.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_main.cpp @@ -24,7 +24,7 @@ namespace ams { namespace { /* TODO: we really shouldn't be using malloc just to avoid dealing with real allocator separation. */ - constexpr size_t MallocBufferSize = 32_MB; + constexpr size_t MallocBufferSize = 12_MB; alignas(os::MemoryPageSize) constinit u8 g_malloc_buffer[MallocBufferSize]; } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp index 62fd74ef3..025fcaba3 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp @@ -17,6 +17,7 @@ #include "../amsmitm_fs_utils.hpp" #include "fsmitm_romfs.hpp" #include "fsmitm_layered_romfs_storage.hpp" +#include "memlet/memlet.h" namespace ams::mitm::fs { @@ -26,6 +27,8 @@ namespace ams::mitm::fs { namespace { + constexpr size_t MaximumRomfsBuildAppletMemorySize = 32_MB; + struct ApplicationWithDynamicHeapInfo { ncm::ProgramId program_id; size_t dynamic_app_heap_size; @@ -41,7 +44,7 @@ namespace ams::mitm::fs { /* Fire Emblem: Engage. */ /* Requirement ~32+ MB. */ /* No particular heap sensitivity. */ - { 0x0100A6301214E000, 16_MB, 0_MB }, + { 0x0100A6301214E000, 20_MB, 0_MB }, /* The Legend of Zelda: Tears of the Kingdom. */ /* Requirement ~48 MB. */ @@ -85,10 +88,12 @@ namespace ams::mitm::fs { /* NOTE: Lock not necessary, because this is the only location which do 0 -> non-zero. */ R_ABORT_UNLESS(MapImpl(std::addressof(this->heap_address), this->heap_size)); - AMS_ABORT_UNLESS(this->heap_address != 0); + AMS_ABORT_UNLESS(this->heap_address != 0 || this->heap_size == 0); /* Create heap. */ - util::ConstructAt(this->heap, reinterpret_cast(this->heap_address), this->heap_size); + if (this->heap_size > 0) { + util::ConstructAt(this->heap, reinterpret_cast(this->heap_address), this->heap_size); + } } } @@ -156,6 +161,52 @@ namespace ams::mitm::fs { R_RETURN(os::SetMemoryHeapSize(0)); } + constinit os::SharedMemoryType g_applet_shared_memory; + + Result MapAppletMemory(uintptr_t *out, size_t &size) { + /* Ensure that we can try to get a native handle for the shared memory. */ + AMS_FUNCTION_LOCAL_STATIC_CONSTINIT(bool, s_initialized_memlet, false); + if (AMS_UNLIKELY(!s_initialized_memlet)) { + R_ABORT_UNLESS(::memletInitialize()); + s_initialized_memlet = true; + } + + /* Try to get a shared handle for the memory. */ + ::Handle shmem_handle = INVALID_HANDLE; + u64 shmem_size = 0; + if (R_FAILED(::memletCreateAppletSharedMemory(std::addressof(shmem_handle), std::addressof(shmem_size), size))) { + /* If we fail, set the heap size to 0. */ + size = 0; + R_SUCCEED(); + } + + /* Set the output size. */ + size = shmem_size; + + /* Setup the shared memory. */ + os::AttachSharedMemory(std::addressof(g_applet_shared_memory), shmem_size, shmem_handle, true); + + /* Map the shared memory. */ + void *mem = os::MapSharedMemory(std::addressof(g_applet_shared_memory), os::MemoryPermission_ReadWrite); + AMS_ABORT_UNLESS(mem != nullptr); + + /* Set the output. */ + *out = reinterpret_cast(mem); + R_SUCCEED(); + } + + Result UnmapAppletMemory(uintptr_t, size_t) { + /* Check that it's possible for us to unmap. */ + AMS_ABORT_UNLESS(os::GetSharedMemoryHandle(std::addressof(g_applet_shared_memory)) != os::InvalidNativeHandle); + + /* Unmap. */ + os::DestroySharedMemory(std::addressof(g_applet_shared_memory)); + + /* Check that we unmapped successfully. */ + AMS_ABORT_UNLESS(os::GetSharedMemoryHandle(std::addressof(g_applet_shared_memory)) == os::InvalidNativeHandle); + R_SUCCEED(); + } + /* Dynamic allocation globals. */ constinit os::SdkMutex g_romfs_build_lock; constinit ncm::ProgramId g_dynamic_heap_program_id{}; @@ -164,6 +215,7 @@ namespace ams::mitm::fs { constinit DynamicHeap g_dynamic_app_heap; constinit DynamicHeap g_dynamic_sys_heap; + constinit DynamicHeap g_dynamic_let_heap; void InitializeDynamicHeapForBuildRomfs(ncm::ProgramId program_id) { if (program_id == g_dynamic_heap_program_id && g_dynamic_app_heap.heap_size > 0) { @@ -175,6 +227,10 @@ namespace ams::mitm::fs { if (g_dynamic_sys_heap.heap_size > 0) { g_dynamic_sys_heap.Map(); } + + if (g_dynamic_let_heap.heap_size > 0) { + g_dynamic_let_heap.Map(); + } } } @@ -183,15 +239,33 @@ namespace ams::mitm::fs { g_building_from_dynamic_heap = false; g_dynamic_app_heap.TryRelease(); + g_dynamic_let_heap.Reset(); + } + + constexpr bool CanAllocateFromDynamicAppletHeap(AllocationType type) { + switch (type) { + case AllocationType_FullPath: + case AllocationType_SourceInfo: + case AllocationType_Memory: + case AllocationType_TableCache: + return false; + default: + return true; + } } } void *AllocateTracked(AllocationType type, size_t size) { - AMS_UNUSED(type); - if (g_building_from_dynamic_heap) { - void *ret = g_dynamic_app_heap.Allocate(size); + void *ret = nullptr; + if (CanAllocateFromDynamicAppletHeap(type) && g_dynamic_let_heap.heap_address != 0) { + ret = g_dynamic_let_heap.Allocate(size); + } + + if (ret == nullptr && g_dynamic_app_heap.heap_address != 0) { + ret = g_dynamic_app_heap.Allocate(size); + } if (ret == nullptr && g_dynamic_sys_heap.heap_address != 0) { ret = g_dynamic_sys_heap.Allocate(size); @@ -211,7 +285,11 @@ namespace ams::mitm::fs { AMS_UNUSED(type); AMS_UNUSED(size); - if (g_dynamic_app_heap.TryFree(p)) { + if (g_dynamic_let_heap.TryFree(p)) { + if (!g_building_from_dynamic_heap) { + g_dynamic_let_heap.TryRelease(); + } + } else if (g_dynamic_app_heap.TryFree(p)) { if (!g_building_from_dynamic_heap) { g_dynamic_app_heap.TryRelease(); } @@ -1021,6 +1099,7 @@ namespace ams::mitm::fs { g_dynamic_heap_program_id = program_id; g_dynamic_app_heap.heap_size = GetDynamicAppHeapSize(g_dynamic_heap_program_id); g_dynamic_sys_heap.heap_size = GetDynamicSysHeapSize(g_dynamic_heap_program_id); + g_dynamic_let_heap.heap_size = MaximumRomfsBuildAppletMemorySize; /* Set output. */ *out_size = g_dynamic_app_heap.heap_size; diff --git a/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c new file mode 100644 index 000000000..ad14ebb2a --- /dev/null +++ b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" +#include "memlet.h" + +static Service g_memletSrv; + +NX_GENERATE_SERVICE_GUARD(memlet); + +Result _memletInitialize(void) { + return smGetService(&g_memletSrv, "memlet"); +} + +void _memletCleanup(void) { + serviceClose(&g_memletSrv); +} + +Service* memletGetServiceSession(void) { + return &g_memletSrv; +} + +Result memletCreateAppletSharedMemory(Handle *out_shmem_h, u64 *out_size, u64 desired_size) { + return serviceDispatchInOut(&g_memletSrv, 65000, desired_size, *out_size, + .out_handle_attrs = { SfOutHandleAttr_HipcMove }, + .out_handles = out_shmem_h, + ); +} diff --git a/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h new file mode 100644 index 000000000..218761936 --- /dev/null +++ b/stratosphere/ams_mitm/source/fs_mitm/memlet/memlet.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +Result memletInitialize(void); +void memletExit(void); +Service* memletGetServiceSession(void); + +Result memletCreateAppletSharedMemory(Handle *out_shmem_h, u64 *out_size, u64 desired_size); + +#ifdef __cplusplus +} +#endif diff --git a/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h b/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h new file mode 100644 index 000000000..d7ce9a7a9 --- /dev/null +++ b/stratosphere/ams_mitm/source/fs_mitm/memlet/service_guard.h @@ -0,0 +1,65 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +typedef struct ServiceGuard { + Mutex mutex; + u32 refCount; +} ServiceGuard; + +NX_INLINE bool serviceGuardBeginInit(ServiceGuard* g) +{ + mutexLock(&g->mutex); + return (g->refCount++) == 0; +} + +NX_INLINE Result serviceGuardEndInit(ServiceGuard* g, Result rc, void (*cleanupFunc)(void)) +{ + if (R_FAILED(rc)) { + cleanupFunc(); + --g->refCount; + } + mutexUnlock(&g->mutex); + return rc; +} + +NX_INLINE void serviceGuardExit(ServiceGuard* g, void (*cleanupFunc)(void)) +{ + mutexLock(&g->mutex); + if (g->refCount && (--g->refCount) == 0) + cleanupFunc(); + mutexUnlock(&g->mutex); +} + +#define NX_GENERATE_SERVICE_GUARD_PARAMS(name, _paramdecl, _parampass) \ +\ +static ServiceGuard g_##name##Guard; \ +NX_INLINE Result _##name##Initialize _paramdecl; \ +static void _##name##Cleanup(void); \ +\ +Result name##Initialize _paramdecl \ +{ \ + Result rc = 0; \ + if (serviceGuardBeginInit(&g_##name##Guard)) \ + rc = _##name##Initialize _parampass; \ + return serviceGuardEndInit(&g_##name##Guard, rc, _##name##Cleanup); \ +} \ +\ +void name##Exit(void) \ +{ \ + serviceGuardExit(&g_##name##Guard, _##name##Cleanup); \ +} + +#define NX_GENERATE_SERVICE_GUARD(name) NX_GENERATE_SERVICE_GUARD_PARAMS(name, (void), ()) + +#ifdef __cplusplus +} +#endif diff --git a/stratosphere/memlet/Makefile b/stratosphere/memlet/Makefile new file mode 100644 index 000000000..d681240e5 --- /dev/null +++ b/stratosphere/memlet/Makefile @@ -0,0 +1,41 @@ +ATMOSPHERE_BUILD_CONFIGS := +all: nx_release + +THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) +CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE))) + +define ATMOSPHERE_ADD_TARGET + +ATMOSPHERE_BUILD_CONFIGS += $(strip $1) + +$(strip $1): + @echo "Building $(strip $1)" + @$$(MAKE) -f $(CURRENT_DIRECTORY)/system_module.mk ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) + +clean-$(strip $1): + @echo "Cleaning $(strip $1)" + @$$(MAKE) -f $(CURRENT_DIRECTORY)/system_module.mk clean ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5) + +endef + +define ATMOSPHERE_ADD_TARGETS + +$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_release, release, $(strip $2), $(strip $3), \ + ATMOSPHERE_BUILD_SETTINGS="$(strip $4)" \ +)) + +$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_debug, debug, $(strip $2), $(strip $3), \ + ATMOSPHERE_BUILD_SETTINGS="$(strip $4) -DAMS_BUILD_FOR_DEBUGGING" ATMOSPHERE_BUILD_FOR_DEBUGGING=1 \ +)) + +$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_audit, audit, $(strip $2), $(strip $3), \ + ATMOSPHERE_BUILD_SETTINGS="$(strip $4) -DAMS_BUILD_FOR_AUDITING" ATMOSPHERE_BUILD_FOR_DEBUGGING=1 ATMOSPHERE_BUILD_FOR_AUDITING=1 \ +)) + +endef + +$(eval $(call ATMOSPHERE_ADD_TARGETS, nx, nx-hac-001, arm-cortex-a57,)) + +clean: $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),clean-$(config)) + +.PHONY: all clean $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS), $(config) clean-$(config)) diff --git a/stratosphere/memlet/memlet.json b/stratosphere/memlet/memlet.json new file mode 100644 index 000000000..8f44c0ce2 --- /dev/null +++ b/stratosphere/memlet/memlet.json @@ -0,0 +1,93 @@ +{ + "name": "memlet", + "title_id": "0x0100000000000421", + "title_id_range_min": "0x0100000000000421", + "title_id_range_max": "0x0100000000000421", + "main_thread_stack_size": "0x00002000", + "main_thread_priority": 44, + "default_cpu_id": 3, + "process_category": 0, + "is_retail": true, + "pool_partition": 1, + "is_64_bit": true, + "address_space_type": 3, + "disable_device_address_space_merge": true, + "filesystem_access": { + "permissions": "0xFFFFFFFFFFFFFFFF" + }, + "service_access": ["fatal:u"], + "service_host": ["memlet"], + "kernel_capabilities": [{ + "type": "kernel_flags", + "value": { + "highest_thread_priority": 63, + "lowest_thread_priority": 24, + "lowest_cpu_id": 3, + "highest_cpu_id": 3 + } + }, { + "type": "syscalls", + "value": { + "svcSetHeapSize": "0x01", + "svcSetMemoryPermission": "0x02", + "svcSetMemoryAttribute": "0x03", + "svcMapMemory": "0x04", + "svcUnmapMemory": "0x05", + "svcQueryMemory": "0x06", + "svcExitProcess": "0x07", + "svcCreateThread": "0x08", + "svcStartThread": "0x09", + "svcExitThread": "0x0a", + "svcSleepThread": "0x0b", + "svcGetThreadPriority": "0x0c", + "svcSetThreadPriority": "0x0d", + "svcGetThreadCoreMask": "0x0e", + "svcSetThreadCoreMask": "0x0f", + "svcGetCurrentProcessorNumber": "0x10", + "svcSignalEvent": "0x11", + "svcClearEvent": "0x12", + "svcMapSharedMemory": "0x13", + "svcUnmapSharedMemory": "0x14", + "svcCreateTransferMemory": "0x15", + "svcCloseHandle": "0x16", + "svcResetSignal": "0x17", + "svcWaitSynchronization": "0x18", + "svcCancelSynchronization": "0x19", + "svcArbitrateLock": "0x1a", + "svcArbitrateUnlock": "0x1b", + "svcWaitProcessWideKeyAtomic": "0x1c", + "svcSignalProcessWideKey": "0x1d", + "svcGetSystemTick": "0x1e", + "svcConnectToNamedPort": "0x1f", + "svcSendSyncRequestLight": "0x20", + "svcSendSyncRequest": "0x21", + "svcSendSyncRequestWithUserBuffer": "0x22", + "svcSendAsyncRequestWithUserBuffer": "0x23", + "svcGetProcessId": "0x24", + "svcGetThreadId": "0x25", + "svcBreak": "0x26", + "svcOutputDebugString": "0x27", + "svcReturnFromException": "0x28", + "svcGetInfo": "0x29", + "svcWaitForAddress": "0x34", + "svcSignalToAddress": "0x35", + "svcSynchronizePreemptionState": "0x36", + "svcCreateSession": "0x40", + "svcAcceptSession": "0x41", + "svcReplyAndReceiveLight": "0x42", + "svcReplyAndReceive": "0x43", + "svcReplyAndReceiveWithUserBuffer": "0x44", + "svcCreateSharedMemory": "0x50", + "svcCallSecureMonitor": "0x7f" + } + }, { + "type": "application_type", + "value": 2 + }, { + "type": "min_kernel_version", + "value": "0x0030" + }, { + "type": "handle_table_size", + "value": 0 + }] +} \ No newline at end of file diff --git a/stratosphere/memlet/source/memlet_main.cpp b/stratosphere/memlet/source/memlet_main.cpp new file mode 100644 index 000000000..ea0ee7c10 --- /dev/null +++ b/stratosphere/memlet/source/memlet_main.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "memlet_service.hpp" + +namespace ams { + + namespace memlet { + + namespace { + + using ServerOptions = sf::hipc::DefaultServerManagerOptions; + + constexpr sm::ServiceName MemServiceName = sm::ServiceName::Encode("memlet"); + constexpr size_t MemMaxSessions = 1; + + /* memlet. */ + constexpr size_t NumServers = 1; + constexpr size_t NumSessions = MemMaxSessions; + + sf::hipc::ServerManager g_server_manager; + + constinit sf::UnmanagedServiceObject g_mem_service_object; + + void InitializeAndLoopIpcServer() { + /* Create services. */ + R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_mem_service_object.GetShared(), MemServiceName, MemMaxSessions)); + + /* Loop forever, servicing our services. */ + g_server_manager.LoopProcess(); + } + + } + + } + + namespace init { + + void InitializeSystemModule() { + /* Initialize our connection to sm. */ + R_ABORT_UNLESS(sm::Initialize()); + + /* Verify that we can sanely execute. */ + ams::CheckApiVersion(); + } + + void FinalizeSystemModule() { /* ... */ } + + void Startup() { /* ... */ } + + } + + void Main() { + /* Set thread name. */ + os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(memlet, Main)); + AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(memlet, Main)); + + /* Initialize and service our ipc service. */ + memlet::InitializeAndLoopIpcServer(); + } + +} diff --git a/stratosphere/memlet/source/memlet_service.cpp b/stratosphere/memlet/source/memlet_service.cpp new file mode 100644 index 000000000..ffccc6e8e --- /dev/null +++ b/stratosphere/memlet/source/memlet_service.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "memlet_service.hpp" + +namespace ams::memlet { + + Result Service::CreateAppletSharedMemory(sf::Out out_size, sf::OutMoveHandle out_handle, u64 desired_size) { + /* Create a handle to set the output to when done. */ + os::NativeHandle handle = os::InvalidNativeHandle; + ON_SCOPE_EXIT { out_handle.SetValue(handle, true); }; + + /* Check that the requested size has megabyte alignment and isn't too big. */ + R_UNLESS(util::IsAligned(desired_size, 1_MB), os::ResultInvalidParameter()); + R_UNLESS(desired_size <= 128_MB, os::ResultInvalidParameter()); + + /* Try to create a shared memory of the desired size, giving up 1 MB each iteration. */ + os::SharedMemoryType shmem = {}; + while (true) { + /* If we have zero desired-size left, we've failed. */ + R_UNLESS(desired_size > 0, os::ResultOutOfMemory()); + + /* Try to create a shared memory. */ + if (R_FAILED(os::CreateSharedMemory(std::addressof(shmem), desired_size, os::MemoryPermission_ReadWrite, os::MemoryPermission_ReadWrite))) { + /* We failed, so decrease the size to see if that works. */ + desired_size -= 1_MB; + continue; + } + + /* We successfully created the shared memory. */ + break; + } + + /* Get the native handle for the shared memory we created. */ + handle = os::GetSharedMemoryHandle(std::addressof(shmem)); + + /* HACK: Clear the shared memory object, since we've stolen its handle, and there's no "correct" way to detach. */ + shmem = {}; + + /* We successfully created a shared memory! */ + *out_size = desired_size; + R_SUCCEED(); + } + +} diff --git a/stratosphere/memlet/source/memlet_service.hpp b/stratosphere/memlet/source/memlet_service.hpp new file mode 100644 index 000000000..6d003753e --- /dev/null +++ b/stratosphere/memlet/source/memlet_service.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +#define AMS_MEMLET_I_SERVICE_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 65000, Result, CreateAppletSharedMemory, (sf::Out out_size, sf::OutMoveHandle out_handle, u64 desired_size), (out_size, out_handle, desired_size)) + +AMS_SF_DEFINE_INTERFACE(ams::memlet::impl, IService, AMS_MEMLET_I_SERVICE_INTERFACE_INFO, 0x00000000) + +namespace ams::memlet { + + class Service { + public: + Result CreateAppletSharedMemory(sf::Out out_size, sf::OutMoveHandle out_handle, u64 desired_size); + }; + static_assert(impl::IsIService); + +} diff --git a/stratosphere/memlet/system_module.mk b/stratosphere/memlet/system_module.mk new file mode 100644 index 000000000..d6de42efc --- /dev/null +++ b/stratosphere/memlet/system_module.mk @@ -0,0 +1,131 @@ +#--------------------------------------------------------------------------------- +# pull in common stratosphere sysmodule configuration +#--------------------------------------------------------------------------------- +THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) +CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE))) +include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk + +ATMOSPHERE_SYSTEM_MODULE_TARGETS := nsp + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(__RECURSIVE__),1) +#--------------------------------------------------------------------------------- + +export TOPDIR := $(CURDIR) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) +CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) +SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) + +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + $(foreach dir,$(AMS_LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(foreach dir,$(AMS_LIBDIRS),-L$(dir)/$(ATMOSPHERE_LIBRARY_DIR)) + +export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC) + +ifeq ($(strip $(CONFIG_JSON)),) + jsons := $(wildcard *.json) + ifneq (,$(findstring $(TARGET).json,$(jsons))) + export APP_JSON := $(TOPDIR)/$(TARGET).json + else + ifneq (,$(findstring config.json,$(jsons))) + export APP_JSON := $(TOPDIR)/config.json + endif + endif +else + export APP_JSON := $(TOPDIR)/$(CONFIG_JSON) +endif + +.PHONY: clean all check_lib + +#--------------------------------------------------------------------------------- +all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a + @$(MAKE) __RECURSIVE__=1 OUTPUT=$(CURDIR)/$(ATMOSPHERE_OUT_DIR)/$(TARGET) \ + DEPSDIR=$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) \ + --no-print-directory -C $(ATMOSPHERE_BUILD_DIR) \ + -f $(THIS_MAKEFILE) + +$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib + @$(SILENTCMD)echo "Checked library." + +ifeq ($(ATMOSPHERE_CHECKED_LIBSTRATOSPHERE),1) +check_lib: +else +check_lib: + @$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/libstratosphere.mk +endif + +$(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR): + @[ -d $@ ] || mkdir -p $@ + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) + + +#--------------------------------------------------------------------------------- +else +.PHONY: all + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +all : $(foreach target,$(ATMOSPHERE_SYSTEM_MODULE_TARGETS),$(OUTPUT).$(target)) + +$(OUTPUT).kip : $(OUTPUT).elf +$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm +$(OUTPUT).nso : $(OUTPUT).elf + +$(OUTPUT).elf : $(OFILES) + +$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a + +%.npdm : %.npdm.json + @echo built ... $< $@ + @npdmtool $< $@ + @echo built ... $(notdir $@) + +#--------------------------------------------------------------------------------- +# you need a rule like this for each extension you use as binary data +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/stratosphere/pm/source/impl/pm_spec.cpp b/stratosphere/pm/source/impl/pm_spec.cpp index 9127d2e6a..ee0e38060 100644 --- a/stratosphere/pm/source/impl/pm_spec.cpp +++ b/stratosphere/pm/source/impl/pm_spec.cpp @@ -82,7 +82,7 @@ namespace ams::pm::impl { [svc::LimitableResource_ThreadCountMax] = BaseAppletThreads, [svc::LimitableResource_EventCountMax] = 0, [svc::LimitableResource_TransferMemoryCountMax] = 32, - [svc::LimitableResource_SessionCountMax] = 5, + [svc::LimitableResource_SessionCountMax] = 5 + 1, /* Add a session for atmosphere's memlet system module. */ }, }; diff --git a/stratosphere/stratosphere.mk b/stratosphere/stratosphere.mk index 5b06a6d98..b20244ec6 100644 --- a/stratosphere/stratosphere.mk +++ b/stratosphere/stratosphere.mk @@ -5,7 +5,7 @@ THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST))) CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE))) include $(CURRENT_DIRECTORY)/../libraries/config/common.mk -ALL_MODULES := loader boot ncm pm sm ams_mitm spl eclct.stub ro creport fatal dmnt boot2 erpt pgl jpegdec LogManager cs htc TioServer dmnt.gen2 +ALL_MODULES := loader boot ncm pm sm ams_mitm spl eclct.stub ro creport fatal dmnt boot2 erpt pgl jpegdec LogManager cs htc TioServer dmnt.gen2 memlet all: $(ALL_MODULES) From 8da6bc59a7fa15afb9ec613b035ae0047aafc67c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 2 May 2025 20:35:41 -0700 Subject: [PATCH 205/238] docs: add provisional changelog for ams 1.9.0 --- docs/changelog.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 9da892b07..664570043 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,28 @@ # Changelog +## 1.9.0 ++ Basic support was added for 20.0.0. + + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. + + There shouldn't be anything user visible resulting from this, but it will be addressed in a future atmosphère update. + + The same action item from 18.0.0 remains, and I believe in my heart of hearts that it will be addressed eventually. Someone has told me they're working on it. + + There aren't (to my knowledge) outstanding 19.0.0 items any more. + + **Please note**: As a result of changes made to nintendo's software in 20.0.0, there is roughly 10MB less memory available for custom system modules. + + We can only steal a maximum of 14MB from the applet pool, down from 40MB. + + To compensate for this, `ams.mitm`'s heap usage has been reduced by 20MB. + + To facilitate this, a new helper module (`memlet`) was added, so that memory may be temporarily stolen during the romfs building process. + + Hopefully, this results in relatively little breakage, however it is possible that user mods which replace extremely large numbers of files in The Legend of Zelda: Tears of the Kingdom may no longer function. + + If you are affected by this, you will see "Data abort (0x101)" when trying to launch the game with mods. + + Please reach out to `sciresm` on discord if this occurs to share your error report binary. However, some issues may be impossible to fix. + + I apologize sincerely if the issue is impossible to resolve, but I have been forced unavoidably to make compromises here, and I think this is the best balance to be struck. + + `exosphère` was updated to reflect the latest official secure monitor behavior. + + `mesosphère` was updated to reflect the latest official kernel behavior. + + `loader` was updated to reflect the latest official behavior. + + `pm` was updated to reflect the latest official behavior. + + `ncm` was partially updated to reflect the latest official behavior. + + `erpt` was updated to reflect the latest official behavior. ++ A number of improvements were made to the dmnt cheat engine. + + New instructions were added, and instructions were updated for improved/new functionality. + + Please see the documents for details -- thanks @tomvita! ++ General system stability improvements to enhance the user's experience. ## 1.8.0 + Basic support was added for 19.0.0. + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. From cb032006d50703ddac34eaccdd575679011e27bf Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 4 May 2025 13:14:58 -0700 Subject: [PATCH 206/238] fusee: fix off-by-one in nogc patches for exFAT firm --- fusee/program/source/fusee_stratosphere.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index ff9388c4d..34134ff42 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -673,8 +673,8 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1)); break; case FsVersion_20_0_0_Exfat: - AddPatch(fs_meta, 0x1B3744, NogcPatch0, sizeof(NogcPatch0)); - AddPatch(fs_meta, 0x1B3944, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1B3745, NogcPatch0, sizeof(NogcPatch0)); + AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1)); break; default: From d305d48a7ea47817acf31d9d0a05da74beb5a624 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 26 Apr 2025 14:53:08 -0700 Subject: [PATCH 207/238] ams: basic support for compiling with gcc 15 --- emummc/source/utils/types.h | 7 +------ exosphere/program/program.ld | 1 + .../stratosphere/ncm/ncm_content_meta_extended_data.hpp | 2 +- libraries/libstratosphere/source/fs/fs_scoped_setter.hpp | 8 ++++---- .../source/sf/hipc/sf_hipc_server_manager.cpp | 2 +- libraries/libvapours/include/vapours/types.hpp | 1 - .../source/crypto/crypto_memory_compare.arch.arm.cpp | 2 +- .../source/crypto/crypto_memory_compare.arch.arm64.cpp | 2 +- .../source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp | 2 +- 9 files changed, 11 insertions(+), 16 deletions(-) diff --git a/emummc/source/utils/types.h b/emummc/source/utils/types.h index ce4db820c..42bb1fad9 100644 --- a/emummc/source/utils/types.h +++ b/emummc/source/utils/types.h @@ -18,6 +18,7 @@ #define _TYPES_H_ #include +#include #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) @@ -58,12 +59,6 @@ typedef u32 Result; ///< Function error code result type. #define INVALID_HANDLE ((Handle) 0) #define CUR_PROCESS_HANDLE ((Handle) 0xFFFF8001) -#ifndef __cplusplus -typedef int bool; -#define true 1 -#define false 0 -#endif /* __cplusplus */ - #define BOOT_CFG_AUTOBOOT_EN (1 << 0) #define BOOT_CFG_FROM_LAUNCH (1 << 1) #define BOOT_CFG_SEPT_RUN (1 << 7) diff --git a/exosphere/program/program.ld b/exosphere/program/program.ld index f0ec57a71..2cbd831ef 100644 --- a/exosphere/program/program.ld +++ b/exosphere/program/program.ld @@ -106,6 +106,7 @@ SECTIONS .debug_code : { KEEP (*(.text._ZN3ams3log6PrintfEPKcz .text._ZN3ams3log7VPrintfEPKcSt9__va_list .text._ZN3ams3log4DumpEPKvm)) KEEP (*(.text._ZN3ams4util10TVSNPrintfEPcmPKcSt9__va_list .text._ZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_114TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE3_clEbm)) + KEEP (*(.text._ZN3ams4util12_GLOBAL__N_1L14TVSNPrintfImplEPcmPKcSt9__va_list .text._ZZN3ams4util12_GLOBAL__N_1L14TVSNPrintfImplEPcmPKcSt9__va_listENKUlbmE_clEbm)) KEEP(secmon_exception_handler.o(.text*)) secmon_exception_handler.o(.rodata*) secmon_exception_handler.o(.data*) diff --git a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp index dc693875a..f8888e49f 100644 --- a/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp +++ b/libraries/libstratosphere/include/stratosphere/ncm/ncm_content_meta_extended_data.hpp @@ -282,7 +282,7 @@ namespace ams::ncm { } const FragmentSet *GetFragmentSet(s32 delta_index, s32 fragment_set_index) const { - return reinterpret_cast(this->GetFragmentSetIndex(delta_index, fragment_set_index)); + return reinterpret_cast(this->GetFragmentSetAddress(delta_index, fragment_set_index)); } const FragmentIndicator *GetFragmentIndicator(s32 delta_index, s32 fragment_set_index, s32 index) const { diff --git a/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp b/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp index fc867aeb6..d488fdc93 100644 --- a/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp +++ b/libraries/libstratosphere/source/fs/fs_scoped_setter.hpp @@ -33,14 +33,14 @@ namespace ams::fs { } ALWAYS_INLINE ScopedSetter(ScopedSetter &&rhs) { - m_ptr = rhs.ptr; - m_value = rhs.value; + m_ptr = rhs.m_ptr; + m_value = rhs.m_value; rhs.Reset(); } ALWAYS_INLINE ScopedSetter &operator=(ScopedSetter &&rhs) { - m_ptr = rhs.ptr; - m_value = rhs.value; + m_ptr = rhs.m_ptr; + m_value = rhs.m_value; rhs.Reset(); return *this; } diff --git a/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp b/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp index b4d959b24..a67ae4800 100644 --- a/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp +++ b/libraries/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp @@ -21,7 +21,7 @@ namespace ams::sf::hipc { #if AMS_SF_MITM_SUPPORTED Result ServerManagerBase::InstallMitmServerImpl(os::NativeHandle *out_port_handle, sm::ServiceName service_name, ServerManagerBase::MitmQueryFunction query_func) { /* Install the Mitm. */ - os::NativeHandle query_handle; + os::NativeHandle query_handle = os::InvalidNativeHandle; R_TRY(sm::mitm::InstallMitm(out_port_handle, std::addressof(query_handle), service_name)); /* Register the query handle. */ diff --git a/libraries/libvapours/include/vapours/types.hpp b/libraries/libvapours/include/vapours/types.hpp index e7b75a8f0..d22f944ab 100644 --- a/libraries/libvapours/include/vapours/types.hpp +++ b/libraries/libvapours/include/vapours/types.hpp @@ -16,7 +16,6 @@ #pragma once #include #include -#include /* NOTE: This file serves as a substitute for libnx . */ diff --git a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp index 671e49a84..1a2d54846 100644 --- a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp +++ b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm.cpp @@ -48,7 +48,7 @@ namespace ams::crypto { " moveq %[result], #1\n" " movne %[result], #0\n" : [result]"=r"(result), [lhs]"+r"(lhs), [rhs]"+r"(rhs), [xor_acc]"=&r"(xor_acc), [index]"=&r"(index), [ltmp]"=&r"(ltmp), [rtmp]"=&r"(rtmp) - : [size]"r"(size) + : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])rhs), [size]"r"(size) : "cc" ); diff --git a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp index 2532415d4..7fdd814d1 100644 --- a/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/crypto_memory_compare.arch.arm64.cpp @@ -47,7 +47,7 @@ namespace ams::crypto { " cmp %w[xor_acc], #0\n" " cset %w[result], eq\n" : [result]"=r"(result), [lhs]"+r"(lhs), [rhs]"+r"(rhs), [xor_acc]"=&r"(xor_acc), [index]"=&r"(index), [ltmp]"=&r"(ltmp), [rtmp]"=&r"(rtmp) - : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])lhs), [size]"r"(size) + : "m"(*(const u8 (*)[size])lhs), "m"(*(const u8 (*)[size])rhs), [size]"r"(size) : "cc" ); diff --git a/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp b/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp index a332d7658..74ff84b47 100644 --- a/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp +++ b/libraries/libvapours/source/crypto/impl/crypto_sha256_impl.arch.arm64.cpp @@ -281,7 +281,7 @@ namespace ams::crypto::impl { [cur_hash0]"+w"(cur_hash0), [cur_hash1]"+w"(cur_hash1), [prev_hash0]"+w"(prev_hash0), [prev_hash1]"+w"(prev_hash1), [tmp_hash]"=w"(tmp_hash), [data]"+r"(data) - : [round_constants]"r"(RoundConstants) + : "m"(*(const u8 (*)[block_count*BlockSize])data), [round_constants]"r"(RoundConstants) : ); } while (--block_count != 0); From 2c50ef717ac25bf67a9c72caf485250793c301cd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 26 Apr 2025 14:57:10 -0700 Subject: [PATCH 208/238] fusee: use embed in mtc/sdram param scripts --- .../lz/T210SdevEmcDvfsTableH4gb01/0.lz4 | Bin 954 -> 958 bytes .../lz/T210SdevEmcDvfsTableH4gb01/1.lz4 | Bin 958 -> 962 bytes .../lz/T210SdevEmcDvfsTableH4gb01/2.lz4 | Bin 954 -> 960 bytes .../lz/T210SdevEmcDvfsTableH4gb01/3.lz4 | Bin 1003 -> 1004 bytes .../lz/T210SdevEmcDvfsTableH4gb01/4.lz4 | Bin 1008 -> 1011 bytes .../lz/T210SdevEmcDvfsTableH4gb01/5.lz4 | Bin 1026 -> 1027 bytes .../lz/T210SdevEmcDvfsTableH4gb01/6.lz4 | Bin 994 -> 995 bytes .../lz/T210SdevEmcDvfsTableH4gb01/7.lz4 | Bin 989 -> 990 bytes .../lz/T210SdevEmcDvfsTableH4gb01/8.lz4 | Bin 1010 -> 1011 bytes .../lz/T210SdevEmcDvfsTableH4gb01/9.lz4 | Bin 1013 -> 1014 bytes .../lz/T210SdevEmcDvfsTableS4gb01/0.lz4 | Bin 952 -> 956 bytes .../lz/T210SdevEmcDvfsTableS4gb01/1.lz4 | Bin 958 -> 962 bytes .../lz/T210SdevEmcDvfsTableS4gb01/2.lz4 | Bin 954 -> 958 bytes .../lz/T210SdevEmcDvfsTableS4gb01/3.lz4 | Bin 1003 -> 1004 bytes .../lz/T210SdevEmcDvfsTableS4gb01/4.lz4 | Bin 1004 -> 1007 bytes .../lz/T210SdevEmcDvfsTableS4gb01/5.lz4 | Bin 1027 -> 1028 bytes .../lz/T210SdevEmcDvfsTableS4gb01/6.lz4 | Bin 996 -> 997 bytes .../lz/T210SdevEmcDvfsTableS4gb01/7.lz4 | Bin 991 -> 992 bytes .../lz/T210SdevEmcDvfsTableS4gb01/8.lz4 | Bin 1011 -> 1012 bytes .../lz/T210SdevEmcDvfsTableS4gb01/9.lz4 | Bin 1011 -> 1012 bytes .../lz/T210SdevEmcDvfsTableS6gb01/0.lz4 | Bin 952 -> 956 bytes .../lz/T210SdevEmcDvfsTableS6gb01/1.lz4 | Bin 958 -> 962 bytes .../lz/T210SdevEmcDvfsTableS6gb01/2.lz4 | Bin 954 -> 958 bytes .../lz/T210SdevEmcDvfsTableS6gb01/3.lz4 | Bin 1003 -> 1004 bytes .../lz/T210SdevEmcDvfsTableS6gb01/4.lz4 | Bin 1004 -> 1007 bytes .../lz/T210SdevEmcDvfsTableS6gb01/5.lz4 | Bin 1027 -> 1028 bytes .../lz/T210SdevEmcDvfsTableS6gb01/6.lz4 | Bin 996 -> 997 bytes .../lz/T210SdevEmcDvfsTableS6gb01/7.lz4 | Bin 991 -> 992 bytes .../lz/T210SdevEmcDvfsTableS6gb01/8.lz4 | Bin 1011 -> 1012 bytes .../lz/T210SdevEmcDvfsTableS6gb01/9.lz4 | Bin 1011 -> 1012 bytes .../lz/T210b01SdevEmcDvfsTableH1a4gb01/0.lz4 | Bin 993 -> 997 bytes .../lz/T210b01SdevEmcDvfsTableH1a4gb01/1.lz4 | Bin 1044 -> 1046 bytes .../lz/T210b01SdevEmcDvfsTableH1a4gb01/2.lz4 | Bin 1050 -> 1053 bytes .../lz/T210b01SdevEmcDvfsTableH1y4gb01/0.lz4 | Bin 989 -> 993 bytes .../lz/T210b01SdevEmcDvfsTableH1y4gb01/1.lz4 | Bin 1043 -> 1045 bytes .../lz/T210b01SdevEmcDvfsTableH1y4gb01/2.lz4 | Bin 1048 -> 1051 bytes .../lz/T210b01SdevEmcDvfsTableH4gb03/0.lz4 | Bin 991 -> 995 bytes .../lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 | Bin 1041 -> 1044 bytes .../lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 | Bin 1044 -> 1047 bytes .../lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 | Bin 989 -> 993 bytes .../lz/T210b01SdevEmcDvfsTableM1a4gb01/1.lz4 | Bin 1043 -> 1045 bytes .../lz/T210b01SdevEmcDvfsTableM1a4gb01/2.lz4 | Bin 1048 -> 1051 bytes .../lz/T210b01SdevEmcDvfsTableM1y4gb01/0.lz4 | Bin 990 -> 995 bytes .../lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 | Bin 1044 -> 1047 bytes .../lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 | Bin 1049 -> 1052 bytes .../lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 | Bin 996 -> 1000 bytes .../lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 | Bin 1045 -> 1048 bytes .../lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 | Bin 1048 -> 1051 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 | Bin 996 -> 1000 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gb01/1.lz4 | Bin 1053 -> 1056 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gb01/2.lz4 | Bin 1055 -> 1058 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gbX03/0.lz4 | Bin 994 -> 999 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 | Bin 1045 -> 1048 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 | Bin 1051 -> 1054 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 | Bin 994 -> 998 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 | Bin 1051 -> 1054 bytes .../lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 | Bin 1049 -> 1052 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 | Bin 993 -> 996 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gb04/1.lz4 | Bin 1044 -> 1047 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 | Bin 1044 -> 1046 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gbX03/0.lz4 | Bin 988 -> 992 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gbX03/1.lz4 | Bin 1044 -> 1047 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 | Bin 1051 -> 1053 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gbY01/0.lz4 | Bin 996 -> 999 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gbY01/1.lz4 | Bin 1052 -> 1055 bytes .../lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 | Bin 1051 -> 1053 bytes .../lz/T210b01SdevEmcDvfsTableS1z4gb01/0.lz4 | Bin 993 -> 997 bytes .../lz/T210b01SdevEmcDvfsTableS1z4gb01/1.lz4 | Bin 1044 -> 1046 bytes .../lz/T210b01SdevEmcDvfsTableS1z4gb01/2.lz4 | Bin 1050 -> 1053 bytes .../lz/T210b01SdevEmcDvfsTableS4gb01/0.lz4 | Bin 992 -> 996 bytes .../lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 | Bin 1038 -> 1040 bytes .../lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 | Bin 1040 -> 1042 bytes .../lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 | Bin 991 -> 995 bytes .../lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 | Bin 1037 -> 1039 bytes .../lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 | Bin 1040 -> 1042 bytes .../lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 | Bin 1000 -> 1004 bytes .../lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 | Bin 1046 -> 1049 bytes .../lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 | Bin 1047 -> 1050 bytes .../lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 | Bin 997 -> 1001 bytes .../lz/T210b01SdevEmcDvfsTableS8gb03/1.lz4 | Bin 1045 -> 1048 bytes .../lz/T210b01SdevEmcDvfsTableS8gb03/2.lz4 | Bin 1060 -> 1062 bytes .../lz/sdram_params_erista_0_1.lz4 | Bin 970 -> 971 bytes .../lz/sdram_params_erista_2_3.lz4 | Bin 966 -> 967 bytes .../lz/sdram_params_erista_4_5.lz4 | Bin 1047 -> 1048 bytes .../lz/sdram_params_erista_6_7.lz4 | Bin 956 -> 957 bytes .../lz/sdram_params_mariko_0_1.lz4 | Bin 1004 -> 1006 bytes .../lz/sdram_params_mariko_10_11.lz4 | Bin 976 -> 978 bytes .../lz/sdram_params_mariko_12_13.lz4 | Bin 960 -> 962 bytes .../lz/sdram_params_mariko_2_3.lz4 | Bin 1095 -> 1097 bytes .../lz/sdram_params_mariko_4_5.lz4 | Bin 1013 -> 1015 bytes .../lz/sdram_params_mariko_6_7.lz4 | Bin 1061 -> 1063 bytes .../lz/sdram_params_mariko_8_9.lz4 | Bin 1062 -> 1064 bytes .../mtc/fusee_mtc_ram_training_pattern.inc | 1 + .../source/mtc/fusee_mtc_tables_erista.inc | 2781 +---------------- .../source/mtc/fusee_mtc_tables_mariko.inc | 1827 +---------- .../source/sdram/fusee_sdram_params.inc | 732 +---- fusee/program/update_mtc_tables.py | 34 +- fusee/program/update_sdram_params.py | 5 +- 98 files changed, 82 insertions(+), 5298 deletions(-) diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/0.lz4 index 0d8bf42d6b588d5823618afe123f5e6b4b2c4e8a..73e792fb2f4f2392f0412c425969d3b30a7c7bca 100644 GIT binary patch delta 54 zcmdnRzK?x_Ewj)iCPpS^24?2NMg05>1!4^G@{|3TBg6|?IRqIv7+C%=91v=daA0I$ KU?>V?U;qG7)e9H^ delta 50 zcmdnTzKeZ>EwkWdCPpS^24?2NMg05>1V? GU;qFuUF+291JXP7!GhXNH{Pu LFfcsOWMBXQQVt6+ delta 51 zcmX@azK?x_1GCU$CMHHEW(H>F<$1SS@i3G57$CowG-e#FGY$i&RR%*5BC|JhgKiQ8tS|os#Ly&>Pje+@u OPy-_a1H&sR1_l6`!3;0} diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/3.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/3.lz4 index e3b2cf75dfd36b18b40633d3763a4c5c183eff44..42e1d924dc9daa2c941a01e0f15ace39acb6012b 100644 GIT binary patch delta 34 pcmaFO{)T-+0JGR9Mn(oECPpS^1{T)Ch5Y;s1#S%S@{?1U+W?oq2n_%L delta 33 pcmaFE{+fM50JG?4Mn(oECPpS^1{T)Ch5Y;s1 diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/4.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/4.lz4 index 9e279a5f54587e8e7b4df4028d56936a2b3e2084..974d69d9cb63319fd0b89e9cdefba62528a62544 100644 GIT binary patch delta 51 zcmeys{+WHlS|%Pv1Je>_J`Q&N66V6m+nHvIePU!}W@ch$VqswCT2jc*&rlG@5HCMD How*YLV|WaP delta 48 zcmey&{(*hNS|%<#1Jec$cK#CP(#boSW{ZAiWMpP$VrF7tVCPy=$j{GEu#Cljau#zZ E098y3!TAwNGuK^#N8{Ny6$2>^e!2Y3Jg delta 33 ocmZqXXyVuq%Pjhtk&&5&nT45+fs21>AwNGu!7>*A$;HeQ0DBz=mH+?% diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/6.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/6.lz4 index 67a3ddd580897abdaa649bdd84bc8cfe56408a30..915757ed95754a5f3d0e2ffe2418ead14293e8ff 100644 GIT binary patch delta 34 pcmaFF{+NA(4YSxMMrLLfW;Paf2411ILVkXRf;fhF`N@II69JPx2jTz# delta 33 pcmaFN{)l~p4YTNHMrLLfW;Paf2411ILVkXRf@LiJlY^Ki0sxL22mk;8 diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/7.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableH4gb01/7.lz4 index 9514bc8942bbbbc1b3d36f071ada262835ebc413..35af2923070512484656a8b39b0d32d5057f4f66 100644 GIT binary patch delta 34 pcmcc1evf^F6|>kUMrLMKW)41!4^G@{@g-Bg6|?IRqIv7+C%=91v=daA0I$ KU?>V?U;qG6X$uel delta 50 zcmdnPzJq;(HM8JlCPpS^24?2NMg05>1V? GU;qFt5(-NI diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/1.lz4 index 97fe2d33f780f39c54cc51a2db19acefceec4d20..486fa90e1bba0990b2fe2a8760f6538da2a351f3 100644 GIT binary patch delta 55 zcmdnTeu#a81GDfWCMHHEW(H>F+291JXP7!GhXNH{Pu LFfcsOWMBXQQVt6+ delta 51 zcmX@azK?x_1GCU$CMHHEW(H>F+291JXf7!I&CNH{Pu LFfhE5VqgFOK?w@P delta 51 zcmdnTzKeZ>C9}|DCMHHEW(H diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/4.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/4.lz4 index 335d295143794c55dd7d2b109b4df3772c61576c..3ec06a3f4ed9e8aa9eda1a69164f6eb98a1bbebb 100644 GIT binary patch delta 51 zcmaFE{+@lqDkdI91Je>_J`Q&N66V6mTbO2vePU!}W@ch$VqswCT2jc*&rlG@5HCMD HnYj}HVB8FI delta 48 zcmaFQ{)TAwNGuK^#N8{N!Th2>^fr2YUbj delta 33 ocmZqSXy(`u$1M7pk&&61nT45+fs21>AwNGu!7>*A$tBDa0DET#nE(I) diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/6.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/6.lz4 index 488f9881288c552d2617b208873432f4804ca3b0..34f639ba5ac12f4267b0e27d2c0e7fe45d0d3355 100644 GIT binary patch delta 34 pcmaFD{*--#9kbXcMrLMaW;Paf2411ILVkXRf;fhF`N_e|69JR#2k8I+ delta 33 pcmaFL{)Byl9kb|XMrLMaW;Paf2411ILVkXRf@LiJlS7y%0sxN12nPTF diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/7.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS4gb01/7.lz4 index 50f00c13af5bd636bf9fc0329e6254692087b690..fdf298bb7214eaeb41f6c0220d49f17fb7d505a6 100644 GIT binary patch delta 34 pcmcc5{(yah4YSxMMrLLfW)41!4^G@{@g-Bg6|?IRqIv7+C%=91v=daA0I$ KU?>V?U;qG6X$uel delta 50 zcmdnPzJq;(HM8JlCPpS^24?2NMg05>1V? GU;qFt5(-NI diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/1.lz4 index 97fe2d33f780f39c54cc51a2db19acefceec4d20..486fa90e1bba0990b2fe2a8760f6538da2a351f3 100644 GIT binary patch delta 55 zcmdnTeu#a81GDfWCMHHEW(H>F+291JXP7!GhXNH{Pu LFfcsOWMBXQQVt6+ delta 51 zcmX@azK?x_1GCU$CMHHEW(H>F+291JXf7!I&CNH{Pu LFfhE5VqgFOK?w@P delta 51 zcmdnTzKeZ>C9}|DCMHHEW(H diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/4.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/4.lz4 index 335d295143794c55dd7d2b109b4df3772c61576c..3ec06a3f4ed9e8aa9eda1a69164f6eb98a1bbebb 100644 GIT binary patch delta 51 zcmaFE{+@lqDkdI91Je>_J`Q&N66V6mTbO2vePU!}W@ch$VqswCT2jc*&rlG@5HCMD HnYj}HVB8FI delta 48 zcmaFQ{)TAwNGuK^#N8{N!Th2>^fr2YUbj delta 33 ocmZqSXy(`u$1M7pk&&61nT45+fs21>AwNGu!7>*A$tBDa0DET#nE(I) diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/6.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/6.lz4 index 488f9881288c552d2617b208873432f4804ca3b0..34f639ba5ac12f4267b0e27d2c0e7fe45d0d3355 100644 GIT binary patch delta 34 pcmaFD{*--#9kbXcMrLMaW;Paf2411ILVkXRf;fhF`N_e|69JR#2k8I+ delta 33 pcmaFL{)Byl9kb|XMrLMaW;Paf2411ILVkXRf@LiJlS7y%0sxN12nPTF diff --git a/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/7.lz4 b/fusee/program/mtc_tables/lz/T210SdevEmcDvfsTableS6gb01/7.lz4 index 50f00c13af5bd636bf9fc0329e6254692087b690..fdf298bb7214eaeb41f6c0220d49f17fb7d505a6 100644 GIT binary patch delta 34 pcmcc5{(yah4YSxMMrLLfW)41c HmjMg_X(|gw diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/1.lz4 index 6d2f2ef861e59badcfb6c94c1aaffc231d71884d..8043931603de046bc8dc545d03a88276a4e82d4e 100644 GIT binary patch delta 57 zcmbQpF@$-n>rr5Ow| delta 54 zcmbQjF_B}#3??>x28IpH)syElEfjjp%EHOc%^)I|Rm9KFQ1Fb!e{wMM79Iw6h6W!N H1~32shx!aA diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableH4gb03/2.lz4 index 3ab45f9f1064f926789574d63af779689ef1fe32..0fa57ea67fb53315c29db54cd648d54079f5cacc 100644 GIT binary patch delta 49 zcmbQjF`Z+B9kaNgxfjDDHdY=EUIs~(oFaaHhJrYTc=^e}%v*U6FfcGM%wYkM3=9Ab C>OM diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1a4gb01/0.lz4 index cadd417f1969eb01f48efe3cdf48bebe2552aade..205fdbb7b065b54b23a919681268e96e13e60fb8 100644 GIT binary patch delta 59 zcmcc1{*Zlx9J9C}yAi`9CMHHEW(F44#YO!53x+ct3-v^|M6XBVq{`wU}0Tc#Lv%A@QlTO bvN>}y3)>48*2(jk&3PDj7#d=D8NdJlyXz2? diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/1.lz4 index c5ad29b66adf2a8a43859685562b399f8e2046fe..b27ed15a44cae962f3168e40fedcb1af920b8f2d 100644 GIT binary patch delta 57 zcmbQjF`Z+>bS8GzKqmeT%q5fOGA$H-#LB|S&dneqmsP~i&rlG@5HCMDfO!Y+0R{#J L1|Jp>$-n>rrZ)^Z delta 54 zcmbQvF@4ju+}h6W!N H1~32si3kiW diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM1y4gb01/2.lz4 index 3324c9e8f8e489991fe4873ede9737da4228edc1..f47ee2bf8d92404bc6d77b42687444376bb0d58d 100644 GIT binary patch delta 49 zcmbQqF^6M=J+ru=xfjDDHdY=EUIs~(oFaaHhJrYTc=^d8%sY7xFfcGM%wYkM3=9Ae CMG1re delta 46 ycmbQkF_UA1J+r8gc?HX5Rvr#s21%8iB7S~`f@duLlf#&I@-VP7G|XXP00RI7-wDM4 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/0.lz4 index db56a6486edb79689c37c8f68460d18f2a519bb9..4df1465fa1d08dd20937dd28927985ea3ed47097 100644 GIT binary patch delta 59 zcmaFD{(^mjDzmsCyAi`9CMHHEW(F44#YO!531c HmjMg_YuO7| diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/1.lz4 index 6cfeb96f46f39c6d13176c99fc7d0e8efa80c22f..77441152648fd43f51938a74508ed027ec5a6f07 100644 GIT binary patch delta 57 zcmbQrF@s~n3?_EgKqmeT%q5fOF)b8+#LB|S&dneqmsP~i&rlG@5HCMDka-910R{#J L1|Jp>$-n>rrxgr7 delta 54 zcmbQiF_mM(3??>x28IpH)syElEfjjp%EHOc%^)I|Rm9KFQ1Fb!e{wMM4ju+}h6W!N H1~32siP{V@ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableM4gb03/2.lz4 index 9df00662a68033afec2f9324251971d5ffcf25e9..cee1a8a177de7739638fc728d490845ad7831453 100644 GIT binary patch delta 49 zcmbQiF`Hw99kaNgxfjDDHdY=EUIs~(oFaaHhJrYTc=^e}%sY7xFfcGM%wYkM3=9Ad Cs0n}o delta 46 ycmbQuF@s}+9kZyAc?HX5Rvr#s21%8iB7S~`f@duLlS7$z@-VP7G|XXP00RI7ObNjN diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gb01/0.lz4 index ffe64ed60e99ecb1210d644c7ba4b501598be2fb..8188217e081e90c3fe95e6777660d2a813594c40 100644 GIT binary patch delta 59 zcmaFD{(^mjDzmsCyAi`9CMHHEW(F44#YO!531$-n>rt}YB` delta 54 zcmZ3$F_&Y*0wy+n28IpH)svSqEfRXn%EHOc%^)I|Rm9KFQ1Fb!e{u}-b{+%E%xpFnK<+Iqv~R1_p*0UIs7#0LQ}*9smFU delta 74 zcmaFP{)l};Iul<3LjxNd0|To#6aNP0s>x+c>qLdv|M6XBVq{`wU}0Tc#Lv%A@QlTO bvNdxu3)>48*2#;R&3PDj7#d=D8NdJlznc)K diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/1.lz4 index ec6b7aea0188818d879da09ad829b1e5f2ecbea8..27f2b519d1c1026efac5f4fc367ae4655949692e 100644 GIT binary patch delta 57 zcmbQrF@s~n3?_EgKqmeT%q5fOF)b8+#LB|S&dneqmsP~i&rlG@5HCMDka-910R{#J L1|Jp>$-n>rrxgr7 delta 54 zcmbQiF_mM(3??>x28IpH)syElEfjjp%EHOc%^)I|Rm9KFQ1Fb!e{wMM4ju+}h6W!N H1~32siP{V@ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbX03/2.lz4 index 82a720accd0adac9d20a82f5d1b82dcfe7e3428e..18423acefcb03b370ae4485ef4cdd228c764e6f4 100644 GIT binary patch delta 49 zcmbQuF^^+|BeS@mxfjDDHdY=EUIs~(oFaaHhJrYTc=^d;%sY7xFfcGM%wYkM3=9Af Ce+i5L delta 46 ycmbQoF`Hw9BeSTGc?HX5Rvr#s21%8iB7S~`f@duLlOvdS@-VP7G|XXP00RI91qsan diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/0.lz4 index 9aa35bb1b87d264c9a5d42a9263bdede7c80f708..5baad7694f773532809f88ec65ee14584d231964 100644 GIT binary patch delta 59 zcmaFF{)~NtGPAfKyAi`9CMHHEW(F44#YO!531c HmjMg_YD)`E diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/1.lz4 index 14d7f1b44c429f40875d5caab296d0b0054dca9e..e6ef1f3173303356c9b3978983ea4e2b1dba34ba 100644 GIT binary patch delta 57 zcmbQuF^^-zJSKM5KqmeT%q5eTFf9~*#LB|S&dneqmsP~i&rlG@5HCMDoOuWD0R{#J L1|Jp>$-n>rtVs-9 delta 54 zcmbQoF`HwZg7 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y4gbY01/2.lz4 index 631e9286814b0f69844e5130845d964ba9fc9fad..228a120f8b09887de833fc4856d9c0188eb10602 100644 GIT binary patch delta 49 zcmbQqF^6M=J+ru=xfjDDHdY=EUIs~(oFaaHhJrYTc=^d8%sY7xFfcGM%wYkM3=9Ae CMG1re delta 46 ycmbQkF_UA1J+r8gc?HX5Rvr#s21%8iB7S~`f@duLlf#&I@-VP7G|XXP00RI7-wDM4 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/0.lz4 index 260bf3d3260da860cbfdf1064e9017bb56404148..718241df0c2074981e6f66e52bc1ccd0e5eaad5b 100644 GIT binary patch delta 55 zcmaFJ{)Byl3bXJdCMHHEW(F44#YO!53|z`zj0 H%K!!dS-%P! delta 52 zcmaFD{*Zlx3bW8-CMHHEW(F44#YO!531SWRYKqmeT%q5ejF)bDQ#K_Fd%EHOc%^)I|Rm9KFP!PuuFF!eec?a(S O1_lNO9~KbFzyJWe(+o)f delta 57 zcmbQvF@j!pY9fAR?Dl#Lv%A@QlTOauD+l9tL)X K1|Jp%FaQ9a_zXP& diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gb04/2.lz4 index a97114e27a2b41ff2d9c973a8a817bae6d5255c3..e9c0433abd10d0a2dacf36de4b57654966a373d9 100644 GIT binary patch delta 48 zcmbQjF^yw`4YSxMMrLLuaR8-yM+F)=bRGqA8OF5>5BD0s%=KiQZ$ anTdDiXmWh03U}k0EWanlOk;^LL=VvH*#^OIYka;H$13N>5 J4+{er005Uz3^xD( diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbX03/2.lz4 index 3cffc39d9c12ffaf52069f86eadd15a313479d80..f11e07bcd8855eb40f1d3e181127b7d3270c305a 100644 GIT binary patch delta 48 zcmbQuF_&Y56SLSSMrLLR$3;=h;3d;Zh delta 54 zcmaFP{)BylI delta 57 zcmbQwF^6Nr3??>x28IpH)syElEfxLD$jr>j!pY9fAR?Dl#Lv%A@QlTOauo9p9tL)X K1|Jp%FaQ9h=nQ25 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS1y8gbY01/2.lz4 index 29f33852ff6e2a524dc66d492738322c28018894..74be6d5d3356d0726846e5196f6ee15b7cf43d64 100644 GIT binary patch delta 48 zcmbQuF_&Y56SLSSMrLL1c HmjMg_Y4Hn7 diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/1.lz4 index 71da3eed01c8d2764901319ae128debd6fa419f0..cfd755d17555b8d82992b1a2e2081465bd1986f7 100644 GIT binary patch delta 43 zcmeCd6b376?6NW#MG!W)P9fD&ps7D0s%=KRK9rF97Vd3q}9{ diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb01/2.lz4 index 96ff15438e4be35472027d55471437a77da8b993..410239cf6cde8a75fbbab8b3a99e686c9b5cc84d 100644 GIT binary patch delta 35 qcmbQhF^OY?Ewi|wxfjDDHdY=EUIs~(oFaaHhJrYTc=^de%=-Y0zz78Z delta 33 pcmbQlF@a-)EwiYQc?HX5Rvr#s21%8iB7S~`f@duLlS7#I0RV_+2!H?p diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/0.lz4 index f3a8aca25a062fbbf9a7d1ae596ab7e43a596568..f13389e5f5b17b1deb99e5e2244fc10caaa22e58 100644 GIT binary patch delta 59 zcmcc5{+NA(3bVK%yAi`9CMHHEW(F44#YO!531c HmjMg_X(|gw diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/1.lz4 index 1022eb947544f25d0f37d934412a2cb925c56b8a..a921719894567b701efb47f4fc1d3517d6be25aa 100644 GIT binary patch delta 43 zcmeC>=;zolor#?_kcoc-bIIhnObdk{v9fTob2Es@Wfk%BGZe%z#LG_(VBQM=`#uX2 delta 41 xcmeC@=;hcjorz7Kfnfu4_2hX>3xyuDvT(9k6g*?`pB%)z7Xa)23qSw> diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gb03/2.lz4 index ed395cd5477a6ca7ab168c9c37fd7b15ca81c18c..c4de070ce7b4a610c6eb65c82059d98d59748b52 100644 GIT binary patch delta 35 qcmbQhF^OY?Ewi|wxfjDDHdY=EUIs~(oFaaHhJrYTc=^de%=-Y0zz78Z delta 33 pcmbQlF@a-)EwiYQc?HX5Rvr#s21%8iB7S~`f@duLlS7#I0RV_+2!H?p diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/0.lz4 index f72bb75ebb1955b6ceeb768c2f8a542634a4a01f..0193ce8cf4543d3862526172ed9980cc19d34dd3 100644 GIT binary patch delta 59 zcmaFC{)T;nCbPI8yAi`9CMHHEW(F44#YO!531c HmjMg_ZuJXm diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/1.lz4 index b3b510aa269f5e4a036f7e64ddac3740a579ba26..2b1c8388400cf7b200dde169954698a026a1fa81 100644 GIT binary patch delta 57 zcmbQnF_UA%OeS{LKqmeT%q5fOGc6Q;#LB|S&dneqmsP~i&rlG@5HCMDh$-n>rr}GR$ delta 54 zcmbQqF^yxxOeQvc28IpH)sq)6Efjjp%EHOc%^)I|Rm9KFQ1Fb!e{u-(4ju+}h6W!N H1~32simVJb diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS4gbY01/2.lz4 index d04e69a2eca2da3b4884c333726bf7748c28c834..e2eec4ee310181f4d5ef40202a16bf22a44a3793 100644 GIT binary patch delta 49 zcmbQvF^gk^Ewi|wxfjDDHdY=EUIs~(oFaaHhJrYTc=^de%sY7xFfcGM%wYkM3=9Ad C3kiGx delta 46 ycmbQmF`Z+BEwiYQc?HX5Rvr#s21%8iB7S~`f@duLlS7zy@-VP7G|XXP00RI6xe2`h diff --git a/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 b/fusee/program/mtc_tables/lz/T210b01SdevEmcDvfsTableS8gb03/0.lz4 index 369a4d7b8cbc3c1322dc54d5c12e5f34b71da354..0e027354ce94b324e27494a4c88beb713dc2b1da 100644 GIT binary patch delta 77 zcmaFL{*rw|A`^crLjxNd0|P5tAQS%v=90uaRJB1!IF)=bRGqA8OF5>5BD0s%=KiP&k anT-`xu7#J8g2QXDJ0swSd2krm> delta 24 gcmX@jeu{mAD-(By63hSp>-|fZSu8dOGF34G0C4;WWB>pF diff --git a/fusee/program/sdram_params/lz/sdram_params_erista_2_3.lz4 b/fusee/program/sdram_params/lz/sdram_params_erista_2_3.lz4 index a8de51beaa06e8f4d0bfc3d7684e6897d0f02d2f..2a47d253773ed5c529cafeda5b90f163cf2d14d0 100644 GIT binary patch delta 25 hcmX@cew=-SD-%z(63hSp>-`xu7#J8g2QZZ}0swQ92jTz# delta 24 gcmX@kevEyCD-(By63hSp>-|fZSu8dOGL-`xu7#J8g2QVFH1ORK32iE`q delta 24 gcmbQiF`Z+BD-(By63hSp>-|fZSu8dOG970G0BD#9O#lD@ diff --git a/fusee/program/sdram_params/lz/sdram_params_erista_6_7.lz4 b/fusee/program/sdram_params/lz/sdram_params_erista_6_7.lz4 index 6a0fa56ac83d4b78db358e5fd313f5fa64d8ad0d..b0402b601b11847e225e603d43a4d7766909bdff 100644 GIT binary patch delta 25 hcmdnPzL$N28xv2p63hSp>-`xu7#J8g2Qp-|fZSu8dOF=aCX0B&&zI{*Lx diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_0_1.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_0_1.lz4 index b7ea6f3206e8acb591db3f1b72126ec2b1731ffa..2ff9fd5fd04cd4096cf2ed34a1b656a13c4a1d0b 100644 GIT binary patch delta 62 zcmaFE{*HZvBNJ~oqY}&i`Rn}|RTvl;C;Ku5aH^OHa53eu;g9ClhZsqY}&i`Rn}|RTvl;Cx<0Hxo}OqY}&i`Rn}!7}!lFM=%9&s+tIVVCFx=z&Lp$lY+qcMgdNZ$wo_E QqPx<|LRft#KVo_S02`ze4*&oF diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_2_3.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_2_3.lz4 index fe96451219ccdc334f43b4945c91317df8b20efe..d3cd2126ca937104cce83ed0f9463031bb7585af 100644 GIT binary patch delta 103 zcmX@kagt+$FB5M!qY}&i`Rn}|RTvl;Cr2^`n5dWta53%_Pe(mx+;u<$j|8r^aNXr7qE3>17Oz3_g?ZFuh{B!!-E>a}lo$1HT2wf5QL< G5C8xS-59X| delta 101 zcmX@fahzj=FB4A%qY}&i`Rn~Vm|09FM==E$tC|RWVCFx=z-Y+Kz^cuxB*1i+Sy)k& zMZ}?-NtR(Q6C(@D`9=Xwjmbt!U81|v%R*RvC*Naw#Zz?;kdP3y%MW0Sq7j E0B^k-^#A|> diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_4_5.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_4_5.lz4 index 12c1e6a196ea89574fa5ff120be9bb9210e8a30d..7392208b680f41be5ab2db8e00cdd68dad2d156f 100644 GIT binary patch delta 62 zcmey${+)e;7ZYzcqY}&i`Rn}|RTvl;Cx|63hSq diff --git a/fusee/program/sdram_params/lz/sdram_params_mariko_6_7.lz4 b/fusee/program/sdram_params/lz/sdram_params_mariko_6_7.lz4 index c03d9f26ae251fb8d07e976a493b7c52e6ddcd70..a1aa66a4cf9046d3e1d24babebe1ebbb7dc4efde 100644 GIT binary patch delta 62 zcmZ3=v7BRrClhZsqY}&i`Rn}|RTvl;Cx(EmcRamTrainingPatternData); diff --git a/fusee/program/source/mtc/fusee_mtc_tables_erista.inc b/fusee/program/source/mtc/fusee_mtc_tables_erista.inc index 5d3296c59..6fc664d4d 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_erista.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_erista.inc @@ -14,2784 +14,15 @@ * along with this program. If not, see . */ -constexpr const u8 T210SdevEmcDvfsTableS6gb01[0x39C0] = { - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70, - 0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, - 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, - 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, - 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30, - 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, - 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, - 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, - 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, - 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, - 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, - 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, - 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, - 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, - 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00, - 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, - 0x23, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x07, 0x00, - 0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00, - 0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, - 0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00, - 0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, - 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, - 0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, - 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, - 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48, - 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C, - 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, - 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, - 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, - 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, - 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, - 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, - 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, - 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00, - 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, - 0x26, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, - 0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00, - 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, - 0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00, - 0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00, +constexpr const u8 T210SdevEmcDvfsTableS6gb01[] = { + #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin" }; -constexpr const u8 T210SdevEmcDvfsTableH4gb01[0x39C0] = { - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70, - 0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, - 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, - 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, - 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30, - 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, - 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, - 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, - 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, - 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, - 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, - 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, - 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, - 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, - 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00, - 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, - 0x23, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x04, 0x03, 0x06, 0x04, 0x07, 0x00, - 0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00, - 0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, - 0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00, - 0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, - 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, - 0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, - 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, - 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48, - 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C, - 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, - 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, - 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x2B, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, - 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, - 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, - 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, - 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, - 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00, - 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, - 0x26, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, - 0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00, - 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, - 0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00, - 0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00, +constexpr const u8 T210SdevEmcDvfsTableH4gb01[] = { + #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin" }; -constexpr const u8 T210SdevEmcDvfsTableS4gb01[0x39C0] = { - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xE0, 0x1C, 0x03, 0x00, 0x20, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x70, - 0x5F, 0x6F, 0x75, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, - 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, - 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x37, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x33, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x05, 0x05, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, - 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, 0x10, 0x00, 0x14, 0x00, - 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, - 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x04, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, 0x13, 0x07, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x37, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x11, 0x01, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xEF, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, 0x30, - 0x02, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x1C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xA0, 0x00, 0x2C, 0x00, 0x00, 0x80, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, - 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, - 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2E, 0x00, - 0x33, 0x00, 0x30, 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x15, 0x00, 0xCC, 0x00, - 0x0A, 0x00, 0x33, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x04, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0xFF, 0x0F, 0xFF, 0x0F, - 0x13, 0x07, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x05, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x11, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x33, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, - 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x12, 0x00, - 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x92, 0x24, 0x00, - 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x49, 0x92, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, - 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, - 0x0C, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x0C, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0xC6, 0x00, 0xFF, 0x00, 0x6D, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0xE2, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x05, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x80, 0x18, 0x40, 0x01, 0x00, 0x00, 0x00, 0x5C, 0x0D, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, 0x6F, - 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, 0x2E, - 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x35, 0x0C, 0x00, 0x39, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, - 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, - 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, - 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0xC8, 0x60, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x88, 0x72, 0x72, 0x0C, 0x48, 0x72, 0x72, 0x0C, 0x48, - 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x8C, 0x72, 0x72, 0x0E, 0x4C, 0x72, 0x72, 0x0E, 0x4C, - 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, - 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, - 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x0A, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x08, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x03, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, - 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x48, - 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x91, 0xBF, 0x3B, 0x00, 0x00, - 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, 0x0C, 0x00, 0xC8, 0x00, - 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x18, 0x00, 0x80, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x01, 0x00, 0x02, - 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE2, 0xFF, 0xEF, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x05, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x40, 0x72, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x30, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, - 0x09, 0x00, 0x00, 0x00, 0x71, 0x71, 0x03, 0x08, 0x13, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0xF0, 0x0B, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xFC, 0x02, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x71, 0x71, 0x03, 0x48, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, - 0xBF, 0x3B, 0x00, 0x00, 0xBB, 0x02, 0x07, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x08, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x20, 0x03, 0x19, 0x00, 0x1F, 0x00, 0x20, 0x03, - 0x0C, 0x00, 0xC8, 0x00, 0x06, 0x03, 0xE0, 0xC1, 0x2F, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x07, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0xC8, 0x18, 0x00, 0x80, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - 0x01, 0x01, 0x00, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0x00, 0x16, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0xE2, 0xFF, 0xEF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0xC8, 0x60, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x90, 0x01, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x40, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x23, 0x00, 0x1F, 0x00, - 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, 0x23, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x23, 0x00, 0x1F, 0x00, 0x24, 0x00, 0x22, 0x00, 0x24, 0x00, 0x22, 0x00, - 0x23, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x07, 0x00, - 0x0D, 0x12, 0x86, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x68, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x02, 0x09, 0x00, 0x00, - 0x3D, 0x00, 0xFF, 0x00, 0x38, 0x00, 0xFF, 0x00, 0x41, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, - 0x05, 0x00, 0xFF, 0x00, 0x90, 0x00, 0xFF, 0x00, 0x05, 0x00, 0xFF, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0x2C, 0x00, 0x08, 0x00, 0xFF, 0x00, 0x00, 0x00, - 0x04, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x32, 0x00, 0xFF, 0x00, 0x22, 0x00, 0xFF, 0x00, - 0xB4, 0x00, 0xFF, 0x00, 0x3A, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x08, 0x12, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x72, 0x72, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x08, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x30, 0x5F, 0x31, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5F, 0x4E, - 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x39, 0x2E, 0x38, - 0x2E, 0x37, 0x5F, 0x56, 0x31, 0x2E, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x6A, 0x18, 0x00, 0x77, 0x03, 0x00, 0x00, 0x4C, 0x04, 0x00, 0x00, 0x70, 0x6C, 0x6C, 0x6D, - 0x5F, 0x75, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, - 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, - 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, - 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, - 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x90, 0x61, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, - 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, - 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, - 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, - 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x88, 0x48, 0x48, 0x0C, 0x48, 0x48, 0x48, 0x0C, 0x48, - 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x8C, 0x48, 0x48, 0x0E, 0x4C, 0x48, 0x48, 0x0E, 0x4C, - 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, - 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, - 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, - 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, - 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x42, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, - 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x80, 0x90, 0x01, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, - 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x08, 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x0E, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x48, - 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x40, 0x60, 0x99, 0xFF, 0x3B, 0x00, 0x00, - 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0C, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, - 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x0C, 0x00, 0x0C, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, - 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x30, 0x00, 0x80, - 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x33, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x00, 0x02, - 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x20, 0x20, 0x10, 0x00, - 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0xFF, 0xEF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x0A, 0x0A, 0x0A, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x1F, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x14, 0x14, 0x16, 0x08, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x06, 0x00, 0x80, 0x90, 0x00, 0x00, - 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, - 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x53, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, 0x00, 0x32, 0x10, 0x00, - 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x60, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x1D, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x10, - 0x14, 0x00, 0x00, 0x00, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, - 0x0E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, - 0x2C, 0x01, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x99, - 0xFF, 0x3B, 0x00, 0x00, 0xBB, 0x01, 0x00, 0xC0, 0x00, 0x80, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x0B, 0x08, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0A, 0x00, 0x0A, 0x00, - 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x40, 0x06, 0x00, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x0A, 0x03, 0xE0, 0xC1, 0x2F, 0x61, 0x13, 0x1F, 0x14, 0x00, 0x00, 0x00, - 0x0D, 0x08, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x20, 0xF3, 0x00, 0x00, 0x00, 0x00, - 0x8C, 0x30, 0x00, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x00, 0x02, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, - 0x20, 0x20, 0x10, 0x00, 0xFF, 0x1F, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x22, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0xDC, 0xDC, 0xDC, - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x90, 0x61, 0x18, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x3E, 0x00, 0x00, 0x00, 0x14, 0x14, 0x16, 0x08, 0x34, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, - 0x80, 0xB0, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x20, 0x03, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x53, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x14, 0x11, 0x00, 0x43, 0x00, 0x07, - 0x00, 0x32, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0x48, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x26, 0x00, 0x1E, 0x00, - 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, 0x26, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x0B, 0x00, - 0x0A, 0x00, 0x0C, 0x00, 0x26, 0x00, 0x1E, 0x00, 0x29, 0x00, 0x24, 0x00, 0x29, 0x00, 0x24, 0x00, - 0x26, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x04, 0x01, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, - 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x0A, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, - 0x19, 0x24, 0x8C, 0x71, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x1A, 0x00, 0x80, 0x00, - 0x1A, 0x00, 0x80, 0x00, 0xD0, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x80, 0x00, 0x03, 0x12, 0x00, 0x00, - 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, - 0x05, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x00, 0x80, 0x00, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x19, 0x00, 0x80, 0x00, 0x18, 0x00, 0x80, 0x00, - 0x95, 0x00, 0x80, 0x00, 0x1D, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x54, 0x00, 0x01, 0x08, 0x2D, 0x00, 0x02, 0x08, - 0x00, 0x00, 0x0D, 0x08, 0x00, 0x00, 0x00, 0xC0, 0x48, 0x48, 0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, - 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x77, 0x00, 0x35, 0x08, 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x80, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x04, 0x00, 0x00, +constexpr const u8 T210SdevEmcDvfsTableS4gb01[] = { + #embed "../../mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin" }; diff --git a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc index 83b06e808..de7f89dfb 100644 --- a/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc +++ b/fusee/program/source/mtc/fusee_mtc_tables_mariko.inc @@ -14,1830 +14,71 @@ * along with this program. If not, see . */ -constexpr const u8 T210b01SdevEmcDvfsTableM4gb03[0x681] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, - 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, - 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, - 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, - 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, - 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, - 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, - 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, - 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, - 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x2A, 0x64, 0x00, 0x57, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, - 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, - 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xD3, 0x06, 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x06, - 0x88, 0x01, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, - 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, - 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, - 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, - 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, - 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, - 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, - 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, - 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, - 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, - 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, - 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, - 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, - 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, - 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, - 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, - 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, - 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, - 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, - 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, - 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, - 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, - 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, - 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, - 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x00, 0x48, 0x00, 0x04, 0x45, 0x14, 0x13, 0x2F, 0x08, 0x00, - 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, - 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableM4gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x33, 0x2E, 0x31, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0A, 0x0B, 0x88, 0x22, 0x00, - 0x0E, 0x00, 0x10, 0x00, 0x1B, 0x00, 0x43, 0x00, 0x49, 0x00, 0x45, 0x00, 0x42, 0x00, 0x47, 0x00, - 0x49, 0x00, 0x47, 0x00, 0x46, 0xB0, 0x00, 0x3F, 0x00, 0x00, 0x10, 0x18, 0x00, 0x06, 0x20, 0x22, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x4F, 0x1B, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x8F, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0xB0, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0xA0, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, - 0x04, 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, - 0x10, 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, - 0x06, 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, - 0x20, 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, - 0x00, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, - 0x02, 0x01, 0x88, 0x02, 0x32, 0x16, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x16, 0x16, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, - 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, - 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, - 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0x42, 0xD8, 0x51, 0x1A, 0xA0, 0x0A, 0x00, 0x11, 0x88, 0x04, - 0x00, 0x26, 0x20, 0x12, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, - 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, - 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, - 0x64, 0x2C, 0x00, 0x07, 0x20, 0x80, 0x18, 0x3F, 0x01, 0x3F, 0x00, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x2A, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, - 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, - 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, - 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, - 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, - 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, - 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, - 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, - 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD5, - 0x06, 0x06, 0x0B, 0x88, 0x15, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x10, 0x00, 0x0A, 0x90, 0x0A, 0x33, - 0x02, 0x00, 0x07, 0x48, 0x03, 0x00, 0xFA, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x20, 0x15, 0x00, 0x3A, - 0x00, 0x11, 0x09, 0x22, 0x00, 0x00, 0x90, 0x09, 0x1F, 0x15, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, - 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, - 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, - 0x0D, 0x05, 0x21, 0x00, 0x06, 0x23, 0x01, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, - 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, - 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, - 0x33, 0xA4, 0x0C, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, - 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x00, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, - 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, - 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, - 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, - 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, - 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x2B, 0x00, 0x24, 0x00, 0x28, - 0x00, 0x20, 0x00, 0x29, 0x00, 0x26, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, - 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, - 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, - 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, - 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, - 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, - 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, - 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, - 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, - 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, - 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, - 0x02, 0x0C, 0x00, 0x00, 0x48, 0x00, 0x04, 0x45, 0x14, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, - 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x04, - 0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, - 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, - 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, - 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, - 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, - 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, - 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, - 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, - 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, - 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, - 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, - 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, - 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, - 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, - 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, - 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, - 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, - 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, - 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, - 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, - 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, - 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, - 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1z4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[0x68C] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x08, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0x48, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, - 0x00, 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, - 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, - 0x16, 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, - 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, - 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, - 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, - 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, - 0x14, 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, - 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, - 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x13, 0x29, 0x01, 0x00, 0x13, 0x32, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, - 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, - 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, - 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, - 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, - 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x04, 0x04, 0x00, 0x17, 0x02, 0x0C, 0x06, 0x1B, - 0x01, 0xFC, 0x05, 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, - 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, - 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, - 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, - 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, - 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, - 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, 0x03, - 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, 0xC0, - 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, - 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, - 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, - 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, - 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, - 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, - 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, - 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, - 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x0C, 0x98, 0x00, 0x13, 0x16, 0xEC, - 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, - 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x8C, 0x09, - 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, - 0x13, 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, - 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, - 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x00, 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, - 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, - 0x8C, 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x08, 0x0E, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0E, 0x00, - 0x03, 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x20, - 0x0E, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, 0x8C, 0x09, 0xA0, - 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, - 0x12, 0x61, 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x08, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, - 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, - 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, - 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, - 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, - 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, - 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, - 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, - 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, - 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xB6, - 0x04, 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, - 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, - 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0xA8, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, - 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, - 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, 0x00, 0x50, 0x06, 0xBF, - 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, - 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, - 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, - 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, - 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, - 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, - 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, - 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, - 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, - 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbY01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableM1a4gb01[0x679] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, - 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, - 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, - 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, - 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, - 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, - 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, - 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, - 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, - 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, - 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, - 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, - 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, - 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, - 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, - 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, 0x00, - 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, - 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, - 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, - 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, - 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, - 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, - 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, - 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, - 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, - 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, - 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, - 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, - 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, - 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, - 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, - 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, - 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, - 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, - 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, - 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x12, - 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, - 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, - 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, - 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, - 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, - 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, - 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, - 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, - 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, - 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, - 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, - 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, - 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, - 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, - 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, - 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, - 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, - 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableM1a4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[0x67D] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x33, 0x2E, 0x31, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x01, 0x88, 0x02, 0x32, 0x16, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x16, 0x16, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, - 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, - 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, - 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, - 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, - 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, 0x0F, - 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, 0x01, - 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, - 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, - 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, - 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, - 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, - 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, - 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, - 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, - 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, - 0xB4, 0x0B, 0x08, 0x28, 0x00, 0x42, 0xD8, 0x51, 0x1A, 0xA0, 0x0A, 0x00, 0x11, 0x88, 0x04, 0x00, - 0x26, 0x20, 0x12, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, - 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, - 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, - 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, - 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, - 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, 0x2D, - 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, - 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x44, - 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, 0x07, - 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, 0x06, - 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, - 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, - 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x9C, - 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, - 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD3, 0x06, 0x06, - 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x06, 0x88, 0x01, 0x13, 0x03, 0xC0, - 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, - 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, - 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, - 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, - 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, - 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xCC, - 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, - 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x00, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, - 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, - 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, - 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, - 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, - 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, - 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, - 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, - 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, - 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, - 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, - 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, - 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableH4gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbX03[0x67D] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, - 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, - 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, - 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, - 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, - 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, - 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, - 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, - 0x00, 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, - 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, - 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, - 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, - 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, - 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, - 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, - 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, - 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, - 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, - 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, - 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, - 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, - 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, - 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, - 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, - 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, - 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, - 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, - 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, - 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, - 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, - 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, - 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, - 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, - 0x06, 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, - 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, - 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, - 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, - 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, - 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, - 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, - 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, - 0x02, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, - 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, - 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, - 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, - 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, - 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, - 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, - 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, - 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, - 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, - 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, - 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, - 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, - 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, - 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, - 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbX03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableM1y4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, - 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, - 0x30, 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, - 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, - 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, - 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, - 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, - 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, - 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, - 0x09, 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, - 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, - 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, - 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, - 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, - 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, - 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, - 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, - 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, - 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, - 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, - 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, - 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, - 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, - 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, - 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, - 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, - 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, - 0x1D, 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, - 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, - 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, - 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, - 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, - 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, - 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, - 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, - 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, - 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, - 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, - 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, - 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, - 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, - 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, - 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, - 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, - 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, - 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, - 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, - 0x74, 0x05, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableM1y4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gb01[0x685] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xFF, 0x12, 0x0B, 0x88, 0x10, 0x00, - 0x14, 0x00, 0x0B, 0x00, 0x13, 0x00, 0x47, 0x00, 0x45, 0x00, 0x4F, 0x00, 0x4D, 0x00, 0x46, 0x00, - 0x46, 0x00, 0x48, 0x00, 0x48, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0B, 0x18, 0x00, 0x06, - 0x20, 0x10, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x4F, 0x13, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x8F, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, - 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, - 0x02, 0x03, 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, - 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, - 0x80, 0x0A, 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, - 0x23, 0x10, 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x1F, 0x34, 0x1A, 0x01, - 0x07, 0x03, 0x79, 0x03, 0x08, 0x21, 0x00, 0xAF, 0x10, 0x08, 0x01, 0x03, 0x00, 0x50, 0x00, 0x40, - 0x01, 0x20, 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, - 0x1B, 0x00, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, - 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, - 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, - 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, - 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, - 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, - 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, - 0x04, 0x00, 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, - 0x00, 0x05, 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, - 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, - 0x0E, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, - 0x30, 0x02, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, - 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, - 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, - 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, - 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, - 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, - 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, - 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x04, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, - 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x07, 0x70, 0x03, - 0x04, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, - 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, - 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, - 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, - 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, - 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, - 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, - 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, - 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x0C, 0x98, 0x00, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, - 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0x82, 0x05, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, - 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x00, 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, - 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, - 0xC0, 0x8C, 0x09, 0x0D, 0xB3, 0x06, 0x06, 0x0B, 0x88, 0x0A, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x0B, - 0xDE, 0x03, 0x13, 0x07, 0x8E, 0x01, 0x51, 0x09, 0x00, 0x05, 0x00, 0x07, 0x02, 0x00, 0x0F, 0x18, - 0x00, 0x05, 0x31, 0x0A, 0x00, 0x0A, 0x96, 0x09, 0x11, 0x06, 0x3E, 0x00, 0x3F, 0x0B, 0x00, 0x0A, - 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, - 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, - 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, - 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, - 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xA4, 0x0C, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, - 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, - 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, - 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, - 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, - 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, - 0x01, 0x23, 0x00, 0x29, 0x00, 0x27, 0x00, 0x2D, 0x00, 0x22, 0x00, 0x27, 0x00, 0x23, 0x00, 0x2C, - 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, - 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x62, - 0x05, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x80, 0x17, 0x13, 0x02, 0x10, 0x06, 0x17, 0x0D, 0xCC, 0x10, - 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, - 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, - 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, - 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, - 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, - 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x11, 0x00, 0xF2, 0x02, 0x00, 0x0A, 0x00, 0x13, - 0x14, 0xAC, 0x00, 0x04, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, - 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, - 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, - 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableH1y4gb01[0x679] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x17, 0x01, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, 0x08, 0xFC, 0x05, 0x12, 0x07, - 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, - 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, - 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, - 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, - 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, - 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, - 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, - 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, - 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, - 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, - 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, - 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, - 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, - 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, - 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, 0x2D, 0x4C, 0x09, 0x00, - 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, - 0x04, 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, - 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x08, 0x74, 0x0A, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xC4, - 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, - 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, - 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, - 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, - 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, - 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, - 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, - 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, - 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, - 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, - 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, - 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, - 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, - 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, - 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, - 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, - 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x12, - 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, - 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, - 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, - 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, 0x23, - 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, - 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, - 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, - 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, - 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, - 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, - 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, - 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, - 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, - 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, - 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, - 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, - 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, - 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableH1y4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gb03[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x33, 0x2E, 0x31, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x01, 0x88, 0x02, 0x32, 0x16, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x16, 0x16, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, - 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, - 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, - 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, - 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, - 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, - 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, - 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, 0x0F, - 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, 0x01, - 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, - 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, - 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, - 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, - 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, - 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, - 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, - 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, - 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, - 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, - 0xB4, 0x0B, 0x08, 0x28, 0x00, 0x42, 0xD8, 0x51, 0x1A, 0xA0, 0x0A, 0x00, 0x11, 0x88, 0x04, 0x00, - 0x26, 0x20, 0x12, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, - 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, - 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, - 0x2C, 0x00, 0x07, 0x20, 0x80, 0x18, 0x3F, 0x01, 0x3F, 0x00, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, - 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, - 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, - 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD3, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x00, 0x06, 0x88, 0x01, 0x13, 0x03, - 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, - 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, - 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, - 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, 0x0D, - 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, - 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, - 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, - 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, - 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x00, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, - 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, - 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, - 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, - 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, - 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, - 0x20, 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, - 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, - 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, - 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, - 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, - 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, - 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, - 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, - 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, - 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, - 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, - 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, - 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x04, - 0x50, 0x10, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS4gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[0x688] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x78, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x13, 0x29, 0x01, 0x00, 0x13, 0x32, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, - 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, - 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, - 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, - 0x00, 0x6E, 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, - 0x28, 0x10, 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x13, 0x05, - 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, 0x14, 0x00, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, - 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, - 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, - 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, - 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, - 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, - 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, - 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, - 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, - 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, - 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, - 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, - 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, - 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, - 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, - 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, - 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, - 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, - 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, - 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, - 0x09, 0x13, 0x37, 0x0C, 0x00, 0x13, 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x70, 0x00, 0x13, 0x10, - 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, - 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, - 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, - 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x88, 0x0E, 0x00, 0x09, 0x00, 0x07, - 0x00, 0x0E, 0x00, 0x03, 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, - 0x00, 0x05, 0x20, 0x0E, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, - 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, - 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, - 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, - 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, - 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, - 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, - 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, - 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, - 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, - 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, - 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, - 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xB6, 0x04, - 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, 0x00, - 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, - 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, - 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, - 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, - 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, - 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, - 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, - 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, - 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, - 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, - 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, - 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, - 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, - 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS4gbY01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[0x687] = { - 0xFF, 0x0E, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x56, 0x34, 0x5F, 0x56, 0x30, 0x2E, 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, - 0x00, 0x10, 0x71, 0xE0, 0x1C, 0x03, 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, - 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x39, 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, - 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, - 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, - 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, - 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, - 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, - 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, 0x08, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, - 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, - 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, - 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, - 0x00, 0x53, 0x31, 0x31, 0x03, 0x48, 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, - 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, - 0xFF, 0x12, 0x0B, 0x08, 0x10, 0x00, 0x14, 0x00, 0x0B, 0x00, 0x13, 0x00, 0x47, 0x00, 0x45, 0x00, - 0x4F, 0x00, 0x4D, 0x00, 0x46, 0x00, 0x46, 0x00, 0x48, 0x00, 0x48, 0x00, 0x08, 0x00, 0x0C, 0x00, - 0x0C, 0x00, 0x0B, 0x18, 0x00, 0x06, 0x20, 0x10, 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, - 0x00, 0x4F, 0x13, 0x00, 0x10, 0x00, 0x01, 0x00, 0x8F, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, - 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, - 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, - 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, - 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, - 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, - 0x92, 0x02, 0x1F, 0x34, 0x1A, 0x01, 0x07, 0x03, 0x79, 0x03, 0x08, 0x21, 0x00, 0xAF, 0x10, 0x00, - 0x01, 0x01, 0x00, 0x10, 0x00, 0x40, 0x00, 0x20, 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, - 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, - 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x08, - 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, - 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, - 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, - 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, - 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, - 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, - 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, - 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, - 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, 0x03, - 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, 0x03, - 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x48, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x1B, 0x35, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, - 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, - 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, 0x01, 0x00, 0x00, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0x48, 0x04, 0x02, - 0xA4, 0x00, 0x17, 0x02, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x04, 0x84, 0x06, 0x00, 0x14, 0x00, - 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, - 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, - 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, - 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, - 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, - 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, - 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, - 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x07, 0x70, 0x03, 0x04, 0x98, 0x07, 0x90, - 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, 0xC0, 0x5D, 0x5D, 0x0E, - 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, 0x00, - 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x95, 0x01, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, 0x00, 0x7F, - 0x07, 0x10, 0x10, 0x82, 0x05, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1D, 0x8C, 0x09, 0x93, 0x0B, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x9C, 0x00, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0x48, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB3, 0x06, - 0x06, 0x0B, 0x08, 0x0A, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x0B, 0xDE, 0x03, 0x13, 0x07, 0x8E, 0x01, - 0x51, 0x09, 0x00, 0x05, 0x00, 0x07, 0x02, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x31, 0x0A, 0x00, 0x0A, - 0x96, 0x09, 0x11, 0x06, 0x3E, 0x00, 0x3F, 0x0B, 0x00, 0x0A, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, - 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, - 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x08, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, - 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, - 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, - 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, - 0x33, 0xA4, 0x0C, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, - 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, - 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, - 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, - 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, - 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, - 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0x7C, 0x0F, 0xAE, 0x1B, 0x29, 0x01, - 0x00, 0xF4, 0x01, 0x23, 0x00, 0x29, 0x00, 0x27, 0x00, 0x2D, 0x00, 0x22, 0x00, 0x27, 0x00, 0x23, - 0x00, 0x2C, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, - 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, - 0x06, 0x62, 0x05, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x17, 0x0D, - 0x82, 0x05, 0x13, 0x0C, 0x84, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, - 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, - 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, - 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, - 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, - 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x11, 0x00, 0xF2, 0x02, 0x00, 0x0A, - 0x00, 0x13, 0x14, 0xAC, 0x00, 0x04, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, - 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, - 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, - 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y8gb04[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableH1a4gb01[0x67B] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x35, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x88, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, 0xC9, - 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, - 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, - 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, - 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, - 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, - 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, - 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, - 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, - 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x9F, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x06, - 0x00, 0xB0, 0x03, 0x7C, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, - 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, - 0x90, 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, - 0x90, 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, - 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, - 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, - 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, - 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, - 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, - 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x13, 0x05, 0x0C, 0x00, 0x17, 0x01, 0x84, 0x06, 0x00, - 0x14, 0x00, 0x12, 0x07, 0xFE, 0x0E, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, - 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, - 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, - 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, - 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, - 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, - 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, - 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, 0x07, - 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, 0x0B, - 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, 0x00, - 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, - 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, - 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, - 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, - 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, - 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x1C, 0x09, 0x17, - 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, - 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, - 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, - 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, - 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, - 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, - 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, - 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0xC8, 0x60, - 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, - 0x06, 0x0B, 0x88, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, - 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, - 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, - 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x5B, 0xB0, - 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, 0x2B, 0x1C, 0x0D, 0x05, 0x21, - 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, - 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, - 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, - 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, - 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5F, 0x12, 0x80, 0xB0, 0x03, 0x1F, 0x00, 0xB0, 0x03, 0x7C, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, - 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, - 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, - 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, - 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, - 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, - 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, - 0x04, 0x00, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x78, 0x06, 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, - 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, - 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, - 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, - 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, - 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, - 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, - 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, - 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, - 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, - 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableH1a4gb01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableH1a4gb01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[0x681] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0xB0, 0x00, 0x18, 0x06, 0x44, 0x01, 0x74, 0x00, 0x00, 0x00, 0x31, 0x31, 0x03, - 0x88, 0xF0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0xC8, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x88, 0x18, 0x00, - 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, 0x62, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x18, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xDC, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x57, 0x13, 0x07, 0x00, 0x80, 0x0A, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x11, 0x00, 0xB8, 0x01, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, - 0x02, 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, - 0x03, 0x79, 0x03, 0x09, 0x21, 0x00, 0x9F, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x00, 0x20, - 0xC9, 0x00, 0x09, 0x34, 0xEF, 0x00, 0xEF, 0x0B, 0x00, 0x48, 0x1C, 0x1C, 0x1C, 0x1C, 0x1B, 0x00, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x33, 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, - 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, 0x88, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, - 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, - 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, - 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, - 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, - 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, 0x14, 0x16, 0xC8, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, - 0x12, 0xC8, 0x04, 0x00, 0x23, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5E, 0x72, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, - 0x13, 0x02, 0x0F, 0xB0, 0x03, 0x78, 0x00, 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, - 0x13, 0x1E, 0xB0, 0x03, 0x1F, 0x10, 0xB0, 0x03, 0x40, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, - 0x00, 0x0F, 0x90, 0x03, 0x21, 0x13, 0x13, 0x04, 0x00, 0x0F, 0x90, 0x03, 0x14, 0x22, 0x30, 0x02, - 0x04, 0x00, 0x0F, 0x90, 0x03, 0x00, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, - 0x07, 0x0A, 0x4F, 0x04, 0x00, 0x80, 0xB0, 0x90, 0x03, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, - 0x0F, 0x01, 0x00, 0xAD, 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x1B, 0x18, 0x10, 0x09, 0x05, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF5, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0x48, 0x04, 0x02, 0xA4, 0x00, 0x04, 0x04, 0x00, 0x13, 0x02, 0xE8, 0x05, 0x04, 0x10, 0x00, - 0x08, 0xFC, 0x05, 0x12, 0x07, 0x0A, 0x0A, 0xD3, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, - 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, - 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, - 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, - 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, - 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, - 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, - 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x06, 0xE8, 0x04, 0x05, 0x98, - 0x07, 0xA0, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x2C, 0x00, 0x00, 0xB4, - 0x0B, 0x08, 0x28, 0x00, 0xA0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x1F, - 0x00, 0x31, 0x88, 0x00, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, - 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, - 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, - 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, - 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, - 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x57, 0x0C, 0x00, - 0x00, 0x00, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, - 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x0C, 0x98, 0x00, 0x13, 0x16, 0xEC, 0x03, - 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x13, 0x0E, 0x44, 0x00, 0x12, 0x09, 0xD0, 0x09, - 0x00, 0x7F, 0x07, 0x10, 0x10, 0xBC, 0x09, 0x57, 0xF1, 0xF1, 0x03, 0x88, 0x1D, 0x8C, 0x09, 0x93, - 0x0B, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x13, - 0x20, 0xB5, 0x08, 0x22, 0x08, 0x06, 0x50, 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, - 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, - 0x13, 0x0D, 0x9C, 0x00, 0x00, 0x90, 0x00, 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0xC8, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xD7, 0x06, 0x06, 0x0B, 0x88, 0x0E, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x03, - 0x1C, 0x0E, 0x11, 0x0B, 0xEC, 0x03, 0x11, 0x03, 0xF2, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x20, 0x0E, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x11, 0x07, 0x0C, 0x00, 0x1F, 0x0E, 0x8C, 0x09, 0xA0, 0xD0, - 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, - 0x61, 0x8C, 0x09, 0x5B, 0xB0, 0x04, 0x00, 0x00, 0x0D, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x80, - 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, - 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x26, 0x02, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, - 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, - 0x09, 0x11, 0x33, 0xCC, 0x01, 0x15, 0x06, 0x1C, 0x0D, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, - 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, - 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, - 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, - 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1F, 0x41, 0xB0, 0x03, 0x48, 0x0F, 0x90, 0x03, 0x0D, - 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x90, 0x03, - 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, - 0x00, 0x28, 0x00, 0x21, 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, - 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x16, 0x07, 0x33, 0x14, 0x0F, 0xCC, - 0x10, 0xA2, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, - 0x13, 0x0F, 0x68, 0x05, 0x13, 0x02, 0x74, 0x05, 0x17, 0x0D, 0xCC, 0x10, 0x13, 0x0C, 0x84, 0x06, - 0x13, 0x0A, 0x50, 0x06, 0xBF, 0x00, 0x00, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, - 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, - 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, - 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, - 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, - 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, - 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, - 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, - 0x57, 0x54, 0x00, 0x01, 0x88, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, - 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y4gbY01[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[0x696] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x08, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xE8, 0x00, 0x08, 0x0C, 0x00, 0x53, 0x31, 0x31, 0x03, 0x48, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, 0x00, - 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, 0x33, - 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, - 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, - 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, - 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, - 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, - 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, - 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, - 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x68, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, - 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, - 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x10, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x13, 0x29, 0x01, 0x00, 0x13, 0x35, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, - 0x00, 0xFF, 0x16, 0x39, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, - 0x40, 0x04, 0x01, 0x00, 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, - 0x0F, 0x00, 0x60, 0x09, 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, - 0x01, 0x00, 0x00, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, - 0x01, 0xD8, 0x09, 0x13, 0x01, 0xFC, 0x05, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x04, 0x84, - 0x06, 0x00, 0x14, 0x00, 0x11, 0x07, 0x14, 0x00, 0xE3, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, - 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, - 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, - 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, - 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, - 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, - 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, - 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, - 0x03, 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, - 0xC0, 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, - 0x00, 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, - 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, - 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, - 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, - 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, - 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, - 0x00, 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, - 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, 0x00, 0x13, 0x10, 0xA8, 0x09, 0x13, 0x16, - 0xEC, 0x03, 0x13, 0x0E, 0x44, 0x00, 0x17, 0x0A, 0xDC, 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, - 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1C, 0x8C, - 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, - 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x70, 0x00, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, - 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, - 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x13, 0x0C, 0xC4, 0x07, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, - 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, - 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, 0x08, 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, - 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, - 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, - 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, - 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, 0x35, 0x50, 0x50, 0xA0, 0x8C, 0x09, 0x5F, 0x8C, 0x30, - 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, - 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, 0x09, 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, - 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, - 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, 0xCC, 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, - 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, - 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, - 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, - 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, - 0x03, 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, - 0x07, 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, - 0xB6, 0x04, 0x01, 0x00, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, 0x00, 0x26, 0x00, - 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, 0x00, 0xFF, 0x36, - 0x08, 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0x50, 0x1F, 0x0B, 0x04, 0x00, 0x11, - 0x0F, 0xCC, 0x00, 0x20, 0x12, 0x0C, 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, - 0xC3, 0x05, 0x13, 0x0F, 0x04, 0x00, 0x13, 0x03, 0x04, 0x00, 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, - 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, 0x00, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, - 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, - 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, - 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, - 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, - 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, - 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, - 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, - 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, - 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS8gb03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin" }; -constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbX03[0x680] = { - 0xFF, 0x18, 0x03, 0x00, 0x00, 0x00, 0x30, 0x31, 0x5F, 0x32, 0x30, 0x34, 0x30, 0x30, 0x30, 0x5F, - 0x4E, 0x6F, 0x43, 0x66, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x5F, 0x56, 0x30, 0x2E, - 0x34, 0x2E, 0x32, 0x5F, 0x56, 0x32, 0x2E, 0x30, 0x00, 0x01, 0x00, 0x06, 0x71, 0xE0, 0x1C, 0x03, - 0x00, 0x4C, 0x04, 0x00, 0x04, 0x00, 0x8F, 0x70, 0x6C, 0x6C, 0x70, 0x5F, 0x6F, 0x75, 0x74, 0x2F, - 0x00, 0x05, 0x5F, 0x02, 0x80, 0x18, 0x40, 0x00, 0x01, 0x00, 0x40, 0xFF, 0x1E, 0x3F, 0x3A, 0x00, - 0x00, 0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x8A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x10, 0x17, 0x0A, 0x04, - 0x00, 0x22, 0x01, 0x00, 0x5C, 0x00, 0x57, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x24, 0x00, 0x13, 0x09, - 0x54, 0x00, 0x13, 0x0B, 0x20, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x13, 0x00, 0x18, 0x00, 0x53, 0x17, - 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x18, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, - 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x06, 0x34, 0x00, 0x17, 0x02, 0x40, 0x00, 0x00, 0x50, - 0x00, 0x13, 0x0E, 0x1C, 0x00, 0x08, 0xB4, 0x00, 0x00, 0x34, 0x00, 0x53, 0x31, 0x31, 0x03, 0x08, - 0x0C, 0x9C, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x0A, 0x00, 0x13, 0x12, 0xE8, 0x00, 0x54, 0x1A, - 0x00, 0x00, 0x00, 0x16, 0xF4, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x04, 0x10, 0x01, 0x13, 0x02, 0xC4, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x12, 0x09, 0x7C, 0x00, 0x23, 0x48, - 0x1C, 0x58, 0x00, 0x40, 0x0D, 0xA0, 0x60, 0x91, 0x7C, 0x01, 0x31, 0xA0, 0x00, 0x2C, 0x86, 0x00, - 0x11, 0x78, 0x16, 0x00, 0x2F, 0xFF, 0x0F, 0x56, 0x01, 0x03, 0xF1, 0x0C, 0x0B, 0x08, 0x16, 0x00, - 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0x8E, 0x00, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x20, 0x16, - 0x00, 0x3A, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x3E, 0x00, 0x11, 0x17, 0xE0, 0x00, 0x0F, 0x01, 0x00, - 0x8D, 0x80, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x98, 0x01, 0xF0, 0x0E, 0x00, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x00, 0x02, 0x03, - 0xE0, 0xC1, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x99, 0x5C, 0x01, 0x60, 0x08, 0x00, - 0x00, 0x50, 0x50, 0x50, 0x22, 0x02, 0x10, 0xF3, 0x40, 0x01, 0x22, 0x13, 0x07, 0xA4, 0x01, 0x04, - 0x4C, 0x00, 0x13, 0x12, 0x04, 0x00, 0x02, 0x00, 0x02, 0x11, 0x05, 0x9F, 0x01, 0x23, 0x10, 0x02, - 0x51, 0x02, 0x00, 0xE4, 0x02, 0x13, 0x04, 0x92, 0x02, 0x2F, 0x34, 0x10, 0x90, 0x00, 0x06, 0x03, - 0x79, 0x03, 0x0E, 0x21, 0x00, 0x15, 0x10, 0x47, 0x00, 0x0F, 0xC9, 0x00, 0x03, 0x34, 0xEF, 0x00, - 0xEF, 0x0B, 0x00, 0x49, 0x1C, 0x1C, 0x1C, 0x1C, 0x3B, 0x00, 0x12, 0x10, 0x04, 0x00, 0x44, 0x33, - 0x60, 0x18, 0x01, 0x14, 0x00, 0x13, 0x18, 0x60, 0x02, 0x00, 0x88, 0x02, 0x42, 0x14, 0x14, 0x16, - 0x08, 0xB8, 0x00, 0xF0, 0x07, 0x01, 0x00, 0x80, 0x90, 0x00, 0x00, 0x04, 0x04, 0x07, 0x07, 0x65, - 0x00, 0x04, 0x00, 0x1F, 0x80, 0x13, 0x05, 0x00, 0x11, 0x10, 0x1F, 0x80, 0x02, 0xF0, 0x0F, 0x40, - 0x72, 0x10, 0x00, 0x00, 0x40, 0x12, 0x01, 0x6A, 0x5B, 0x12, 0x01, 0x00, 0x10, 0x08, 0x0F, 0x00, - 0x58, 0x10, 0x00, 0x00, 0xFC, 0x10, 0x11, 0x00, 0x13, 0x08, 0x0F, 0x50, 0x7C, 0x0C, 0x00, 0xF3, - 0x07, 0x14, 0x11, 0x00, 0x03, 0x00, 0x07, 0x4C, 0x72, 0x10, 0x00, 0x5A, 0x3C, 0x55, 0x55, 0x14, - 0x14, 0x16, 0x48, 0x5D, 0x5D, 0x0C, 0x88, 0x04, 0x00, 0x12, 0x48, 0x04, 0x00, 0x23, 0x0E, 0x8C, - 0x04, 0x00, 0x10, 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, - 0x5E, 0x70, 0x00, 0x80, 0x06, 0x06, 0x00, 0x00, 0x05, 0x17, 0x02, 0x0F, 0xB0, 0x03, 0x7A, 0x00, - 0x8C, 0x02, 0x10, 0x1F, 0x24, 0x00, 0x03, 0x34, 0x02, 0x13, 0x1E, 0xB0, 0x03, 0x15, 0x10, 0xB0, - 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x09, 0x13, 0x0E, 0x04, 0x00, 0x0F, 0x90, - 0x03, 0x21, 0x00, 0x64, 0x01, 0x1F, 0x13, 0x90, 0x03, 0x17, 0x00, 0x33, 0x05, 0x1F, 0x30, 0x90, - 0x03, 0x03, 0x1F, 0x04, 0x40, 0x07, 0xFF, 0xFF, 0x70, 0x1F, 0x01, 0x40, 0x07, 0x0A, 0x4F, 0x04, - 0x00, 0x80, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x28, 0x00, 0x02, 0x00, 0x0B, 0x0F, 0x01, 0x00, 0xAD, - 0x1B, 0x29, 0x01, 0x00, 0x0C, 0x20, 0x00, 0x04, 0x48, 0x03, 0x0F, 0x01, 0x00, 0xFF, 0x16, 0x39, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x0D, 0x00, 0xB4, 0x02, 0x40, 0x04, 0x01, 0x00, - 0x00, 0x16, 0x0A, 0x13, 0x18, 0x84, 0x05, 0x0D, 0x50, 0x03, 0x5A, 0x42, 0x0F, 0x00, 0x60, 0x09, - 0x14, 0x00, 0x1E, 0x01, 0x0C, 0x00, 0x0F, 0xFC, 0x00, 0x6E, 0xF7, 0x02, 0x01, 0x00, 0x00, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x00, 0x80, 0x01, 0xD8, 0x09, 0x17, - 0x01, 0x04, 0x00, 0x17, 0x02, 0x0C, 0x06, 0x1B, 0x01, 0xFC, 0x05, 0x11, 0x07, 0x14, 0x00, 0xE3, - 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0xE6, 0x04, - 0x4F, 0x00, 0x1A, 0x00, 0x80, 0x04, 0x00, 0x0E, 0x11, 0x1B, 0x10, 0x04, 0xF1, 0x02, 0x80, 0x00, - 0x4C, 0x02, 0x00, 0x00, 0xB2, 0x00, 0xFF, 0x00, 0xDA, 0x00, 0xFF, 0x00, 0x9D, 0x00, 0xFF, 0x02, - 0x00, 0x17, 0x0C, 0x08, 0x00, 0xF1, 0x02, 0x49, 0x00, 0x7F, 0x00, 0x80, 0x00, 0xFF, 0x00, 0x04, - 0x00, 0xFF, 0x00, 0xAD, 0x00, 0x08, 0x00, 0xFF, 0x88, 0x00, 0x33, 0xFF, 0x00, 0xC6, 0x04, 0x00, - 0x13, 0x6D, 0x2C, 0x00, 0x11, 0xE2, 0x06, 0x00, 0x01, 0x73, 0x06, 0x01, 0x0A, 0x00, 0x13, 0x14, - 0xC0, 0x06, 0x2E, 0xF4, 0x01, 0x78, 0x01, 0x13, 0x08, 0x44, 0x0F, 0x0F, 0x23, 0x01, 0x08, 0x1F, - 0xC0, 0x0C, 0x00, 0x04, 0x08, 0x23, 0x05, 0x03, 0xC6, 0x04, 0x90, 0x01, 0x08, 0x00, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x58, 0xC0, 0x5D, 0x5D, 0x0E, 0x0C, 0x28, 0x00, 0xC0, 0xD8, - 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, 0x00, 0x04, 0x00, 0x11, 0x20, 0xFD, - 0x04, 0x15, 0x88, 0x04, 0x00, 0x50, 0x25, 0x08, 0x11, 0x00, 0x0C, 0x46, 0x00, 0x07, 0x50, 0x10, - 0x00, 0x0C, 0x00, 0x26, 0x5C, 0x0D, 0x94, 0x01, 0x7F, 0x30, 0x31, 0x5F, 0x31, 0x36, 0x30, 0x30, - 0xCD, 0x10, 0x23, 0x28, 0x6A, 0x18, 0xCC, 0x10, 0x4F, 0x6D, 0x5F, 0x75, 0x64, 0x2C, 0x00, 0x07, - 0x21, 0x80, 0x18, 0x0C, 0x02, 0x2F, 0xF0, 0x02, 0xB4, 0x02, 0x3B, 0x22, 0xFF, 0x3B, 0x6C, 0x06, - 0x0F, 0xCC, 0x10, 0x45, 0x10, 0x60, 0x79, 0x01, 0x47, 0x01, 0x00, 0x00, 0xE0, 0x24, 0x00, 0x13, - 0x44, 0x9C, 0x09, 0x13, 0x29, 0x64, 0x00, 0x00, 0x95, 0x01, 0x17, 0x2D, 0x4C, 0x09, 0x00, 0xBC, - 0x09, 0x97, 0x23, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x09, 0x13, 0x1D, 0x04, - 0x00, 0x13, 0x0C, 0xA8, 0x09, 0x13, 0x16, 0xEC, 0x03, 0x13, 0x0E, 0x14, 0x00, 0x17, 0x0A, 0xDC, - 0x09, 0x00, 0x08, 0x00, 0x13, 0x24, 0x0C, 0x00, 0x12, 0x1C, 0x8C, 0x09, 0x10, 0x10, 0xC4, 0x00, - 0x57, 0xF1, 0xF1, 0x03, 0x08, 0x1C, 0x8C, 0x09, 0x93, 0x0C, 0x00, 0x06, 0x00, 0x33, 0x00, 0x00, - 0x00, 0x39, 0x4C, 0x09, 0x13, 0x37, 0x0C, 0x00, 0x23, 0x20, 0x18, 0x90, 0x02, 0x12, 0x06, 0x50, - 0x02, 0x13, 0x10, 0xF0, 0x01, 0x13, 0x17, 0x08, 0x00, 0x13, 0x38, 0x64, 0x00, 0x00, 0x8F, 0x01, - 0x62, 0x2E, 0x00, 0x00, 0x00, 0xCC, 0x01, 0x04, 0x00, 0x13, 0x0D, 0x34, 0x01, 0x00, 0x90, 0x00, - 0x00, 0xFA, 0x01, 0x17, 0x22, 0x40, 0x01, 0x66, 0xF1, 0xF1, 0x03, 0x48, 0x60, 0x18, 0x8C, 0x09, - 0x00, 0x7C, 0x01, 0x4F, 0xBB, 0x01, 0x00, 0xC0, 0x8C, 0x09, 0x0D, 0xB5, 0x06, 0x06, 0x0B, 0x08, - 0x0D, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0E, 0x60, 0x0A, 0x13, 0x03, 0xC0, 0x0A, 0x11, 0x07, 0x82, - 0x00, 0x1F, 0x08, 0x18, 0x00, 0x06, 0x00, 0x88, 0x09, 0x11, 0x08, 0x20, 0x00, 0x00, 0x3E, 0x00, - 0x3F, 0x0E, 0x00, 0x0D, 0x8C, 0x09, 0xA0, 0xD0, 0x40, 0x06, 0x31, 0x00, 0x2F, 0x00, 0x40, 0x06, - 0x17, 0x00, 0x90, 0x01, 0x09, 0x8C, 0x09, 0x12, 0x61, 0x8C, 0x09, 0x22, 0xB0, 0x04, 0xDA, 0x03, - 0x08, 0x8C, 0x09, 0x5F, 0x8C, 0x30, 0x00, 0x00, 0x2B, 0x1C, 0x0D, 0x05, 0x21, 0x00, 0x06, 0xCB, - 0x0B, 0x13, 0x11, 0x8C, 0x09, 0x81, 0x84, 0x10, 0x02, 0x40, 0x85, 0x14, 0x02, 0x40, 0x8C, 0x09, - 0x1F, 0x20, 0x8C, 0x09, 0x40, 0x1F, 0x00, 0x8C, 0x09, 0x0F, 0x26, 0x90, 0x61, 0xCC, 0x10, 0x00, - 0x78, 0x02, 0x13, 0x2B, 0x88, 0x02, 0x00, 0x8C, 0x09, 0x11, 0x33, 0x48, 0x02, 0x15, 0x06, 0xCC, - 0x10, 0x2F, 0x20, 0x03, 0x8C, 0x09, 0x14, 0x53, 0x53, 0x08, 0x0F, 0x10, 0x42, 0x8C, 0x09, 0x5F, - 0x43, 0x00, 0x07, 0x06, 0x23, 0xCC, 0x10, 0x07, 0x43, 0x48, 0x48, 0x0E, 0x8C, 0x04, 0x00, 0x10, - 0x4C, 0x04, 0x00, 0x0F, 0xB0, 0x03, 0xFF, 0x09, 0x1F, 0x99, 0xB0, 0x03, 0xFF, 0x5F, 0x01, 0xCC, - 0x10, 0x03, 0xCF, 0x09, 0x0F, 0xB0, 0x03, 0x78, 0x04, 0xCC, 0x10, 0x13, 0x3F, 0xB0, 0x03, 0x1D, - 0x41, 0xB0, 0x03, 0x1F, 0x01, 0xB0, 0x03, 0x36, 0x0F, 0x90, 0x03, 0x0D, 0x1F, 0x22, 0x40, 0x07, - 0xFF, 0xFF, 0xF2, 0x1F, 0x01, 0x40, 0x07, 0x0D, 0x1F, 0xB0, 0x40, 0x07, 0x37, 0x2F, 0x20, 0x00, - 0x02, 0x00, 0x0A, 0x0F, 0xCC, 0x10, 0xBE, 0xF4, 0x01, 0x27, 0x00, 0x21, 0x00, 0x27, 0x00, 0x20, - 0x00, 0x26, 0x00, 0x23, 0x00, 0x2A, 0x00, 0x22, 0x00, 0x48, 0x03, 0x0C, 0x18, 0x00, 0x0F, 0x01, - 0x00, 0xFF, 0x36, 0x08, 0xCC, 0x10, 0x00, 0xC8, 0x0F, 0x1F, 0x20, 0xCC, 0x10, 0xA8, 0x12, 0x0C, - 0xF4, 0x0F, 0x05, 0xCC, 0x10, 0x13, 0x06, 0x9C, 0x10, 0x00, 0xC3, 0x05, 0x13, 0x0F, 0x68, 0x05, - 0x13, 0x02, 0x74, 0x05, 0x13, 0x0D, 0x1C, 0x00, 0x13, 0x07, 0x38, 0x00, 0x13, 0x08, 0x90, 0x06, - 0x00, 0x50, 0x06, 0xBF, 0x03, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x0D, 0x00, 0x19, 0x24, 0x6C, 0xCC, - 0x10, 0x1E, 0x13, 0xD0, 0xCC, 0x10, 0xF7, 0x06, 0x03, 0x12, 0x00, 0x00, 0x3D, 0x00, 0x80, 0x00, - 0x38, 0x00, 0x80, 0x00, 0x41, 0x00, 0x80, 0x00, 0x90, 0x00, 0x80, 0x00, 0x05, 0x08, 0x00, 0x70, - 0x49, 0x00, 0x34, 0x00, 0x80, 0x00, 0x80, 0xFA, 0x14, 0x62, 0x00, 0x16, 0x00, 0x08, 0x00, 0x80, - 0x06, 0x15, 0x23, 0x00, 0x19, 0x04, 0x00, 0x91, 0x18, 0x00, 0x80, 0x00, 0x95, 0x00, 0x80, 0x00, - 0x1D, 0x26, 0x00, 0x31, 0x00, 0x00, 0x2C, 0xDC, 0x00, 0x11, 0x80, 0x98, 0x06, 0x17, 0x08, 0xCC, - 0x10, 0x17, 0x09, 0xBC, 0x17, 0x1F, 0x00, 0xCC, 0x10, 0x10, 0x79, 0x56, 0x01, 0x55, 0x05, 0x55, - 0x05, 0x02, 0x0C, 0x00, 0x13, 0x01, 0xDC, 0x07, 0x00, 0x01, 0x00, 0x13, 0x2F, 0x08, 0x00, 0x57, - 0x54, 0x00, 0x01, 0x08, 0x2D, 0xCC, 0x10, 0x2F, 0x48, 0x48, 0xCC, 0x10, 0x1B, 0x1B, 0x35, 0xCC, - 0x10, 0x00, 0x50, 0x10, 0x00, 0x07, 0x00, 0x80, 0x9C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr const u8 T210b01SdevEmcDvfsTableS1y8gbX03[] = { + #embed "../../mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin" }; diff --git a/fusee/program/source/sdram/fusee_sdram_params.inc b/fusee/program/source/sdram/fusee_sdram_params.inc index 133e42b9f..a89dcd2ca 100644 --- a/fusee/program/source/sdram/fusee_sdram_params.inc +++ b/fusee/program/source/sdram/fusee_sdram_params.inc @@ -14,68 +14,8 @@ * along with this program. If not, see . */ -constexpr inline const u8 SdramParamsErista0_1[0x3CA] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0, - 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, - 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, - 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, - 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, - 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, - 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, - 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, - 0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, - 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, - 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, - 0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, - 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, - 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, 0x38, - 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, - 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, - 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, - 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, - 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, 0x00, - 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, 0x94, - 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, - 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, - 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, - 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x58, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, - 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, - 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, - 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, - 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, - 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, - 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, - 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2F, - 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xF9, 0x1F, 0x0D, 0x68, 0x07, 0x4C, 0x03, 0x5F, - 0x01, 0x1F, 0x80, 0x68, 0x07, 0xFF, 0xFF, 0xFF, 0x71, 0x1F, 0x02, 0x68, 0x07, 0xB7, 0x1F, 0x05, - 0x68, 0x07, 0xFF, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista0_1[0x3CB] = { + #embed "../../sdram_params/lz/sdram_params_erista_0_1.lz4" }; constexpr inline const u8 * const SdramParamsErista0 = SdramParamsErista0_1; @@ -84,68 +24,8 @@ constexpr inline const size_t SdramParamsSizeErista0 = sizeof(SdramParamsErista0 constexpr inline const u8 * const SdramParamsErista1 = SdramParamsErista0_1; constexpr inline const size_t SdramParamsSizeErista1 = sizeof(SdramParamsErista0_1); -constexpr inline const u8 SdramParamsErista2_3[0x3C6] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0, - 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, - 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, - 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, - 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, - 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, - 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, - 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, - 0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, - 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, - 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, - 0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, - 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, - 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, 0x38, - 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, - 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, - 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, - 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, - 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, 0x00, - 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, 0x94, - 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, - 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, - 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, - 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0x58, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, - 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, - 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, - 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, - 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, - 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, - 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, - 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2F, - 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xFF, 0x9E, 0x1F, 0x12, 0x68, 0x07, 0x18, 0x1F, - 0x03, 0x68, 0x07, 0xFF, 0xFF, 0xAE, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x68, 0x07, 0xFF, 0xFF, 0xAE, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista2_3[0x3C7] = { + #embed "../../sdram_params/lz/sdram_params_erista_2_3.lz4" }; constexpr inline const u8 * const SdramParamsErista2 = SdramParamsErista2_3; @@ -154,73 +34,8 @@ constexpr inline const size_t SdramParamsSizeErista2 = sizeof(SdramParamsErista2 constexpr inline const u8 * const SdramParamsErista3 = SdramParamsErista2_3; constexpr inline const size_t SdramParamsSizeErista3 = sizeof(SdramParamsErista2_3); -constexpr inline const u8 SdramParamsErista4_5[0x417] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x13, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x28, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x27, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x08, 0x0C, 0x00, 0xA0, - 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x3B, 0x5A, 0x00, 0xF1, 0x28, 0xF3, 0x0C, - 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, - 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, - 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, - 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, 0xB0, 0x04, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, 0x71, 0x71, 0x03, 0x08, - 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, 0x08, 0x0D, 0x0C, 0x00, - 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0x67, 0x02, 0x70, 0x15, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, 0x11, 0x00, 0xFF, 0x0F, - 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0xA2, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, 0x08, 0x00, 0x04, 0x00, - 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, 0x11, 0x01, 0x00, 0x10, - 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, 0x7F, 0x14, 0x00, 0x12, - 0x00, 0x10, 0x00, 0x14, 0x18, 0x00, 0x06, 0xF3, 0x02, 0x30, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x30, - 0x00, 0x33, 0x00, 0x35, 0x00, 0x30, 0x00, 0x32, 0x00, 0x05, 0x20, 0x00, 0x0F, 0x18, 0x00, 0x05, - 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x14, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x11, 0x10, 0x0C, 0x00, - 0x0C, 0x7A, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, - 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x3C, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, - 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, 0x03, - 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, 0x38, - 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, - 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, - 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, - 0x0C, 0x01, 0x00, 0x13, 0x1B, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, 0x14, - 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, 0x00, - 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, 0x94, - 0x04, 0x13, 0x37, 0x72, 0x01, 0x12, 0x10, 0x8D, 0x01, 0x31, 0x00, 0x11, 0x01, 0xB9, 0x02, 0x00, - 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, 0x12, 0x00, 0x00, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x2C, 0x01, 0x05, - 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, 0xDC, 0xDC, 0x0A, 0x01, 0x00, - 0x01, 0x24, 0x01, 0x21, 0x03, 0x0C, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x18, 0x58, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, 0x02, 0x0C, 0x74, 0x01, 0x04, - 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x17, 0x04, 0xEC, 0x03, 0xE4, 0x01, 0x00, 0x02, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xC3, 0x71, 0x0F, 0x0F, 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, - 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, - 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, - 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, - 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, - 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, - 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2F, - 0xEC, 0x00, 0x3C, 0x01, 0x07, 0x0F, 0x68, 0x07, 0xF9, 0x1F, 0x0D, 0x68, 0x07, 0x4C, 0x03, 0x5F, - 0x01, 0x1F, 0x80, 0x68, 0x07, 0x29, 0x1F, 0x12, 0x68, 0x07, 0x18, 0x1F, 0x03, 0x68, 0x07, 0xFF, - 0x45, 0x11, 0x15, 0xF6, 0x06, 0x1F, 0x16, 0x18, 0x00, 0x06, 0xF5, 0x00, 0x32, 0x00, 0x2F, 0x00, - 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x0C, 0x02, 0x0E, 0x18, 0x00, - 0x0F, 0x68, 0x07, 0x13, 0x13, 0x15, 0x5A, 0x00, 0x02, 0x5E, 0x00, 0x3F, 0x16, 0x00, 0x15, 0x68, - 0x07, 0xD4, 0x13, 0x12, 0x04, 0x00, 0x0F, 0x68, 0x07, 0x3E, 0x1F, 0x02, 0x68, 0x07, 0x65, 0x11, - 0x07, 0x04, 0x00, 0x0D, 0x68, 0x07, 0x1F, 0x10, 0x68, 0x07, 0x27, 0x1F, 0x05, 0x68, 0x07, 0xFF, - 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista4_5[0x418] = { + #embed "../../sdram_params/lz/sdram_params_erista_4_5.lz4" }; constexpr inline const u8 * const SdramParamsErista4 = SdramParamsErista4_5; @@ -229,67 +44,8 @@ constexpr inline const size_t SdramParamsSizeErista4 = sizeof(SdramParamsErista4 constexpr inline const u8 * const SdramParamsErista5 = SdramParamsErista4_5; constexpr inline const size_t SdramParamsSizeErista5 = sizeof(SdramParamsErista4_5); -constexpr inline const u8 SdramParamsErista6_7[0x3BC] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x0E, 0xFC, 0x05, 0x68, 0xBC, 0x01, 0x70, 0x0A, 0x00, 0x00, 0x00, 0x04, 0xB4, - 0x01, 0x70, 0x01, 0x32, 0x54, 0x76, 0xC8, 0xE6, 0x00, 0x70, 0x24, 0x00, 0xC8, 0x34, 0x00, 0x00, - 0x00, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x18, 0x00, 0xFF, 0x01, 0xFF, 0xFF, 0x1F, - 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x77, 0x00, 0x04, 0x00, 0x01, - 0xD3, 0xA6, 0xA6, 0xAF, 0xB3, 0x3C, 0x9E, 0x00, 0x00, 0x03, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, - 0x00, 0x3C, 0x00, 0x19, 0x1F, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x08, 0x46, 0x00, 0x57, 0xA1, - 0x01, 0x00, 0x00, 0x32, 0x64, 0x00, 0x00, 0xC3, 0x00, 0x13, 0x02, 0x0C, 0x00, 0x13, 0x03, 0x04, - 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x2C, - 0x00, 0x10, 0x09, 0xC8, 0x00, 0x07, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x13, - 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x13, 0x08, 0x40, 0x00, 0x13, 0x05, 0x1C, 0x00, 0x04, - 0x58, 0x00, 0x13, 0x02, 0x18, 0x00, 0x04, 0x64, 0x00, 0x00, 0xA6, 0x00, 0xB5, 0x12, 0x00, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x58, 0x01, 0x03, 0x61, 0x00, - 0x13, 0xC1, 0x50, 0x00, 0x17, 0x08, 0xC8, 0x00, 0x13, 0x03, 0x2C, 0x00, 0x17, 0x05, 0x54, 0x00, - 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xD8, 0x00, 0x13, 0x05, 0x30, 0x00, - 0x00, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0xBF, 0x29, 0x00, 0xF1, - 0x29, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, - 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, - 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, - 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0x12, 0xC1, 0x01, 0x2C, 0x00, 0xFF, 0xEC, 0x01, - 0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xD0, 0xC0, - 0x71, 0x71, 0x03, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x72, 0x72, 0x0E, 0x0C, 0x20, 0x00, 0xC2, 0x08, - 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, - 0x67, 0x02, 0x70, 0x15, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x94, 0xF3, 0x05, 0x08, - 0x11, 0x00, 0xFF, 0x0F, 0xFF, 0x0F, 0xCC, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, - 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, - 0x10, 0x00, 0xA2, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0xD3, - 0x08, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x28, 0x01, 0x00, 0x13, - 0x11, 0x01, 0x00, 0x10, 0xBE, 0xBF, 0x00, 0x12, 0x0F, 0x02, 0x00, 0x1F, 0x00, 0x01, 0x00, 0x2C, - 0x7F, 0x15, 0x00, 0x12, 0x00, 0x12, 0x00, 0x16, 0x18, 0x00, 0x06, 0xF5, 0x00, 0x32, 0x00, 0x2F, - 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x2F, 0x00, 0x33, 0x0C, 0x02, 0x0F, 0x18, - 0x00, 0x05, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x13, 0x15, 0x5A, 0x00, 0x02, 0x5E, 0x00, 0x3B, 0x16, - 0x00, 0x15, 0x78, 0x00, 0x05, 0x50, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, - 0x00, 0x51, 0x18, 0x00, 0x00, 0x28, 0x01, 0x23, 0x40, 0x01, 0x0C, 0x02, 0x54, 0xAB, 0x00, 0x0A, - 0x04, 0x11, 0x58, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xEC, 0x00, 0x0D, 0x17, 0x02, 0x0C, 0x00, 0x17, - 0x03, 0x60, 0x03, 0x02, 0xA1, 0x01, 0x68, 0x22, 0x04, 0xFF, 0xFF, 0xAF, 0x4F, 0x74, 0x03, 0x04, - 0x38, 0x00, 0x32, 0x8B, 0xFF, 0x07, 0x84, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, - 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, - 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, - 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x94, 0x00, 0x80, 0x2F, 0x41, 0x13, 0x1F, - 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x7F, 0x0B, 0xD7, 0x06, 0x40, 0x82, - 0x00, 0xB2, 0x08, 0x08, 0x03, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x10, 0x10, 0x10, 0x59, 0x03, 0x0B, - 0x94, 0x04, 0x11, 0x37, 0x16, 0x03, 0x30, 0x00, 0x00, 0x10, 0x05, 0x00, 0x51, 0x30, 0x00, 0x00, - 0x11, 0x01, 0xB9, 0x02, 0x00, 0x1F, 0x00, 0x13, 0x0A, 0xA9, 0x04, 0x17, 0x10, 0x77, 0x03, 0x05, - 0x12, 0x00, 0x00, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, - 0x67, 0x76, 0x2C, 0x01, 0x05, 0x53, 0xFF, 0xEF, 0xFF, 0xEF, 0xC0, 0x01, 0x00, 0x57, 0xDC, 0xDC, - 0xDC, 0xDC, 0x0A, 0x01, 0x00, 0x01, 0x24, 0x01, 0x21, 0x03, 0x07, 0x04, 0x00, 0xF1, 0x03, 0x00, - 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, - 0x10, 0x58, 0x01, 0xB2, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0xE0, - 0x02, 0x0C, 0x74, 0x01, 0x04, 0x08, 0x00, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x11, - 0x07, 0x10, 0x00, 0xC4, 0x02, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, - 0x98, 0x05, 0x15, 0x1F, 0xF3, 0x00, 0x00, 0xC0, 0x03, 0x14, 0x01, 0xDD, 0x00, 0x14, 0x80, 0xB6, - 0x00, 0x15, 0xF0, 0xD4, 0x03, 0x68, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0xD2, 0x00, 0x2F, 0xF0, - 0xFF, 0xEC, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x14, 0x30, 0xAB, 0x00, 0x0F, 0x2C, 0x00, 0x02, - 0x4F, 0x76, 0x0C, 0x00, 0x04, 0x50, 0x02, 0x01, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, - 0x7E, 0x16, 0x40, 0x9F, 0x05, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, - 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, - 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x2E, 0xEC, 0x00, 0x3C, 0x01, 0x0F, 0x01, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsErista6_7[0x3BD] = { + #embed "../../sdram_params/lz/sdram_params_erista_6_7.lz4" }; constexpr inline const u8 * const SdramParamsErista6 = SdramParamsErista6_7; @@ -298,70 +54,8 @@ constexpr inline const size_t SdramParamsSizeErista6 = sizeof(SdramParamsErista6 constexpr inline const u8 * const SdramParamsErista7 = SdramParamsErista6_7; constexpr inline const size_t SdramParamsSizeErista7 = sizeof(SdramParamsErista6_7); -constexpr inline const u8 SdramParamsMariko0_1[0x3EC] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x82, - 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x0E, 0x00, 0x11, 0x88, 0x04, 0x00, 0x26, 0x20, - 0x12, 0x0C, 0x00, 0x02, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, 0xBC, 0xBC, 0xC5, 0xB3, 0x3C, 0x9E, - 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, - 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, - 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, - 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, - 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, - 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, - 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, - 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, - 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, - 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, - 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, - 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, - 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, - 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, - 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, - 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, - 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, - 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, - 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, - 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, 0x16, 0x16, 0x16, 0x88, 0x2C, 0x00, 0x2C, - 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, - 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, - 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xA2, 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, - 0x1C, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, - 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, - 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, 0x31, 0x7F, 0x22, 0x00, 0x0E, 0x00, 0x10, 0x00, 0x1B, - 0x18, 0x00, 0x06, 0xF3, 0x02, 0x43, 0x00, 0x49, 0x00, 0x45, 0x00, 0x42, 0x00, 0x47, 0x00, 0x49, - 0x00, 0x47, 0x00, 0x46, 0x00, 0x16, 0xE6, 0x00, 0x0F, 0x18, 0x00, 0x05, 0x1F, 0x28, 0x02, 0x00, - 0x0C, 0x11, 0x22, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x1B, 0x00, 0x22, 0x94, - 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, - 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, - 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, - 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, - 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, - 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, - 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, - 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, - 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, - 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, - 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, - 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, - 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, - 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, - 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, - 0x00, 0x10, 0xA4, 0x01, 0xEF, 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, - 0x00, 0x80, 0x01, 0xC0, 0x01, 0x00, 0x04, 0x08, 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, - 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, - 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, - 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, 0x68, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, - 0x0B, 0x05, 0x2F, 0xF0, 0xFF, 0xF4, 0x00, 0x05, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, - 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, - 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, - 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, - 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, - 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0x9C, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, - 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, - 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x0F, 0x38, - 0x08, 0x0D, 0x11, 0x16, 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, - 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xF6, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko0_1[0x3EE] = { + #embed "../../sdram_params/lz/sdram_params_mariko_0_1.lz4" }; constexpr inline const u8 * const SdramParamsMariko0 = SdramParamsMariko0_1; @@ -370,76 +64,8 @@ constexpr inline const size_t SdramParamsSizeMariko0 = sizeof(SdramParamsMariko0 constexpr inline const u8 * const SdramParamsMariko1 = SdramParamsMariko0_1; constexpr inline const size_t SdramParamsSizeMariko1 = sizeof(SdramParamsMariko0_1); -constexpr inline const u8 SdramParamsMariko2_3[0x447] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x61, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x30, 0x01, 0x13, - 0x02, 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, - 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, - 0x0B, 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, - 0x08, 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, - 0x18, 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, - 0x00, 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, - 0x80, 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, - 0x0C, 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, - 0x00, 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, - 0x00, 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, - 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, - 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, - 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, - 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, - 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x08, 0x00, 0x00, - 0x02, 0x08, 0x00, 0x00, 0x0D, 0xAB, 0x00, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x08, 0x00, 0x00, - 0x0B, 0x08, 0x5D, 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, - 0x0D, 0x0C, 0x14, 0x14, 0x16, 0x08, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, - 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, - 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xA2, 0x08, - 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x1C, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, - 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x00, 0x64, 0x01, 0xB3, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x35, 0x01, 0x00, 0x13, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, - 0x0F, 0xF4, 0x02, 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, - 0x02, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, - 0x00, 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x10, 0x02, 0x00, 0x0C, 0x11, 0x16, - 0x5A, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, - 0x54, 0x01, 0xA4, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x18, 0x00, 0x63, - 0x80, 0x01, 0x00, 0x00, 0x40, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, - 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x05, 0x78, 0x03, 0x78, 0x01, 0x22, - 0x04, 0xFF, 0x9F, 0xAF, 0x4F, 0x88, 0x03, 0x04, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x80, 0x00, - 0xF0, 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, - 0x25, 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, - 0x67, 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, - 0x0C, 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, - 0xFF, 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, - 0x00, 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, - 0x04, 0x14, 0x40, 0x8B, 0x02, 0x1D, 0x00, 0x9D, 0x02, 0x01, 0x04, 0x04, 0xCF, 0x81, 0x10, 0x09, - 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, 0x10, 0x04, - 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4C, 0x1C, 0x1C, 0x1C, 0x1C, 0xF0, 0x01, 0x31, - 0x02, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, 0x00, - 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x20, 0x20, 0x00, 0xB1, 0x08, 0x4C, 0x00, 0x00, - 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x04, 0x02, 0x0D, 0xC0, 0x01, 0x04, 0x08, 0x00, 0x17, - 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x11, 0x07, 0x10, 0x00, 0xE2, 0x02, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, - 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x04, 0x84, 0x03, 0x35, 0x00, 0x00, 0xF0, 0x24, 0x04, - 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, - 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, - 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, - 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, - 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, - 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xC3, - 0x2F, 0x00, 0x00, 0x38, 0x08, 0x0B, 0x2F, 0xC5, 0xB3, 0x38, 0x08, 0x29, 0x1F, 0x00, 0x38, 0x08, - 0x84, 0x13, 0x05, 0x1C, 0x00, 0x08, 0x78, 0x05, 0x1F, 0x0D, 0x38, 0x08, 0xC7, 0x93, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0x88, 0x38, 0x08, 0xF2, 0x0A, 0x88, 0x00, 0x00, 0x0B, 0x88, - 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, - 0x16, 0x16, 0x16, 0x88, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x43, 0x1B, 0x02, 0x38, 0x08, 0x04, 0x30, - 0x08, 0x0F, 0x38, 0x08, 0x91, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x0F, 0x38, 0x08, 0x24, 0x14, 0x80, - 0x38, 0x08, 0x04, 0x20, 0x00, 0x0F, 0x38, 0x08, 0xFF, 0x1E, 0x7F, 0x80, 0x00, 0x40, 0x00, 0x04, - 0x10, 0x80, 0x38, 0x08, 0x82, 0x1F, 0x00, 0x38, 0x08, 0x09, 0x1F, 0x10, 0x38, 0x08, 0x1F, 0x1F, - 0x01, 0x38, 0x08, 0x00, 0x1F, 0x00, 0x38, 0x08, 0x36, 0x0E, 0xFC, 0x06, 0x0F, 0x38, 0x08, 0xFF, - 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko2_3[0x449] = { + #embed "../../sdram_params/lz/sdram_params_mariko_2_3.lz4" }; constexpr inline const u8 * const SdramParamsMariko2 = SdramParamsMariko2_3; @@ -448,71 +74,8 @@ constexpr inline const size_t SdramParamsSizeMariko2 = sizeof(SdramParamsMariko2 constexpr inline const u8 * const SdramParamsMariko3 = SdramParamsMariko2_3; constexpr inline const size_t SdramParamsSizeMariko3 = sizeof(SdramParamsMariko2_3); -constexpr inline const u8 SdramParamsMariko4_5[0x3F5] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, - 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, - 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, - 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, - 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, - 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, 0x0D, 0xA0, - 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, 0x02, 0x03, - 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, 0x0C, 0x26, - 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, 0x0A, 0x0B, - 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, 0xBF, 0x01, - 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, 0x88, 0x00, - 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, 0x88, 0x5D, - 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, 0x8C, 0x14, - 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, 0x00, 0x0A, - 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, 0x30, 0x01, - 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, 0x00, 0x10, - 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, 0x00, 0x01, - 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, 0x20, 0x80, - 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, 0x31, - 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, 0x45, - 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, 0x01, - 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, 0x5C, - 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, 0x40, - 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, 0x01, - 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, 0x03, - 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, - 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, - 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, - 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, - 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, - 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, - 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, - 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, - 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, - 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, - 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, - 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, - 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, - 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04, 0x08, - 0x00, 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, - 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, - 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, - 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0B, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, - 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, - 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, - 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, - 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, - 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, - 0xFF, 0xFF, 0xFF, 0x40, 0x13, 0x32, 0x01, 0x00, 0x0F, 0x38, 0x08, 0x41, 0x3E, 0x18, 0x00, 0x0F, - 0x38, 0x08, 0x07, 0x18, 0x00, 0x93, 0x48, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x20, - 0x08, 0x11, 0x0D, 0x8E, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x78, 0x02, 0x00, 0x0C, 0x11, - 0x18, 0x5A, 0x00, 0x15, 0x0F, 0x38, 0x08, 0x1F, 0x18, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xF6, 0x50, - 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko4_5[0x3F7] = { + #embed "../../sdram_params/lz/sdram_params_mariko_4_5.lz4" }; constexpr inline const u8 * const SdramParamsMariko4 = SdramParamsMariko4_5; @@ -521,74 +84,8 @@ constexpr inline const size_t SdramParamsSizeMariko4 = sizeof(SdramParamsMariko4 constexpr inline const u8 * const SdramParamsMariko5 = SdramParamsMariko4_5; constexpr inline const size_t SdramParamsSizeMariko5 = sizeof(SdramParamsMariko4_5); -constexpr inline const u8 SdramParamsMariko6_7[0x425] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00, - 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, - 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, - 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, - 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, - 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, - 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, - 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, - 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, - 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, - 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, - 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, - 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, 0x22, 0x20, - 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, - 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, - 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, - 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, - 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, - 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, - 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, - 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, - 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, - 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, - 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, - 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, - 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, - 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, - 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, 0x81, - 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, - 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, - 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, - 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, 0x00, - 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04, 0x08, 0x00, - 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, - 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, - 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, - 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, - 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, - 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, - 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, - 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, - 0x22, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x05, 0x1F, 0x08, 0x38, 0x08, 0x5B, 0x93, 0x08, 0x00, 0x00, - 0x02, 0x08, 0x00, 0x00, 0x0D, 0x08, 0x38, 0x08, 0xF2, 0x0A, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x5D, - 0x5D, 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, - 0x14, 0x16, 0x08, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x32, 0x1C, 0x00, 0x38, 0x08, 0x1F, 0x00, 0x38, - 0x08, 0xFF, 0x00, 0x04, 0x18, 0x00, 0x00, 0x34, 0x06, 0x1F, 0x40, 0x38, 0x08, 0xFF, 0x22, 0x04, - 0x12, 0x00, 0x0F, 0x38, 0x08, 0x81, 0x1F, 0x01, 0x38, 0x08, 0x09, 0x1F, 0x20, 0x38, 0x08, 0x0F, - 0x1B, 0x01, 0x38, 0x08, 0x1F, 0x02, 0x38, 0x08, 0x00, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x8C, 0x50, - 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko6_7[0x427] = { + #embed "../../sdram_params/lz/sdram_params_mariko_6_7.lz4" }; constexpr inline const u8 * const SdramParamsMariko6 = SdramParamsMariko6_7; @@ -597,74 +94,8 @@ constexpr inline const size_t SdramParamsSizeMariko6 = sizeof(SdramParamsMariko6 constexpr inline const u8 * const SdramParamsMariko7 = SdramParamsMariko6_7; constexpr inline const size_t SdramParamsSizeMariko7 = sizeof(SdramParamsMariko6_7); -constexpr inline const u8 SdramParamsMariko8_9[0x426] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x53, 0x0E, 0x00, 0x00, - 0x00, 0x05, 0x1C, 0x00, 0x05, 0x24, 0x01, 0x03, 0x6C, 0x00, 0x03, 0xD7, 0x01, 0x10, 0x80, 0x0A, - 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, 0x00, - 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x74, 0x00, 0x13, - 0x0A, 0x08, 0x00, 0x13, 0x14, 0x60, 0x00, 0x04, 0x54, 0x00, 0x13, 0x3B, 0x04, 0x00, 0x13, 0x05, - 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, - 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, - 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, - 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, - 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, - 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, - 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, - 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, - 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, - 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x00, 0x10, 0x01, 0xDB, 0x0C, 0x00, 0x04, 0x00, 0x1F, 0x22, - 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, - 0x02, 0x31, 0x7F, 0x18, 0x00, 0x0F, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x48, - 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x47, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0D, - 0x8E, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x18, 0x5A, 0x00, - 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x18, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, - 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, - 0x00, 0x01, 0x40, 0x02, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, - 0xE4, 0x03, 0x0E, 0x07, 0x0C, 0x00, 0x04, 0xA8, 0x04, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, - 0xFF, 0x9F, 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, - 0x10, 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, - 0x01, 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, - 0x24, 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, - 0x90, 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, - 0xFF, 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, - 0x01, 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, - 0x14, 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, - 0x04, 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, - 0x4D, 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, - 0x1C, 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, - 0x44, 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, - 0x08, 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x08, 0xC0, 0x01, - 0x17, 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, - 0xD2, 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, - 0x16, 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, - 0x15, 0xF0, 0x24, 0x04, 0x60, 0x43, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x0B, 0x05, 0x3B, 0x80, 0x2A, - 0x02, 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, - 0x00, 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, - 0x04, 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, - 0x00, 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, - 0x01, 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, - 0x0F, 0x38, 0x08, 0xFF, 0x22, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x74, 0x93, 0x08, 0x00, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x0D, 0x08, 0x38, 0x08, 0xF2, 0x0A, 0x08, 0x00, 0x00, 0x0B, 0x08, 0x5D, 0x5D, - 0x0E, 0x0C, 0x5D, 0x5D, 0x0C, 0x08, 0x08, 0x08, 0x0D, 0x0C, 0x00, 0x00, 0x0D, 0x0C, 0x14, 0x14, - 0x16, 0x08, 0x2C, 0x00, 0x0F, 0x38, 0x08, 0x32, 0x1C, 0x00, 0x38, 0x08, 0x1B, 0x00, 0x38, 0x08, - 0x13, 0x32, 0x01, 0x00, 0x0F, 0x38, 0x08, 0xE8, 0x04, 0x18, 0x00, 0x00, 0x34, 0x06, 0x1F, 0x40, - 0x38, 0x08, 0xFF, 0x22, 0x04, 0x12, 0x00, 0x0F, 0x38, 0x08, 0x81, 0x1F, 0x01, 0x38, 0x08, 0x09, - 0x1F, 0x20, 0x38, 0x08, 0x1F, 0x1F, 0x02, 0x38, 0x08, 0x00, 0x1F, 0x01, 0x38, 0x08, 0xFF, 0x8C, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko8_9[0x428] = { + #embed "../../sdram_params/lz/sdram_params_mariko_8_9.lz4" }; constexpr inline const u8 * const SdramParamsMariko8 = SdramParamsMariko8_9; @@ -673,68 +104,8 @@ constexpr inline const size_t SdramParamsSizeMariko8 = sizeof(SdramParamsMariko8 constexpr inline const u8 * const SdramParamsMariko9 = SdramParamsMariko8_9; constexpr inline const size_t SdramParamsSizeMariko9 = sizeof(SdramParamsMariko8_9); -constexpr inline const u8 SdramParamsMariko10_11[0x3D0] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00, - 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, - 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, - 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x13, 0x04, 0xEC, 0x00, 0x08, 0x0C, 0x00, 0x90, 0x1C, 0x03, 0x00, 0x00, - 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, 0x1B, 0x06, - 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, 0x1E, 0x0D, - 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, 0x25, 0x02, - 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, 0x07, 0x9A, - 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, 0x00, 0x02, - 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, 0x00, 0x0B, - 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, 0x00, 0x0D, - 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, 0x00, 0xCC, - 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, 0x0F, 0x00, - 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, 0x08, 0x44, - 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, 0x00, 0x2C, - 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, 0x22, 0x20, - 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, 0xF4, 0x02, - 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, 0x43, 0x00, - 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, 0x0C, 0xBA, - 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, 0x00, 0x00, - 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, 0x01, 0xB3, - 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, 0x08, 0x00, - 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, 0x0F, 0xE4, - 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, 0x9F, 0xAF, - 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, 0x32, 0x54, - 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, 0x75, 0x64, - 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, 0x00, 0x31, - 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, 0x00, 0x80, - 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, - 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, 0x31, 0x03, - 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, 0x40, 0x8B, - 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, 0xCF, 0x81, - 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, 0x22, 0x10, - 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, 0x1C, 0x98, - 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, 0x57, 0x6E, - 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, 0x4C, 0x00, - 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x0C, 0xC0, 0x01, 0x04, 0x08, 0x00, - 0x17, 0x05, 0x0C, 0x02, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, 0x02, 0x01, 0x02, - 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, 0x1F, 0x28, 0x01, - 0x43, 0xFF, 0x00, 0xFF, 0x01, 0xA4, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, 0xF0, 0x24, 0x04, - 0x60, 0x43, 0xCB, 0xFA, 0xE4, 0xD3, 0xFE, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, 0x1C, 0x00, 0x0C, - 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, 0x05, 0x10, 0x76, - 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, 0x38, 0x7E, 0x16, - 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, 0x08, 0x2F, 0x00, - 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, 0x00, 0x05, 0x22, - 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0F, 0x3C, 0x01, 0x03, 0x0F, 0x38, 0x08, 0xFF, - 0xFF, 0x3B, 0x1F, 0x08, 0x38, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x14, 0x1F, 0x01, 0x38, 0x08, 0x51, - 0x5F, 0xC3, 0xBA, 0xE4, 0xD3, 0x1E, 0x38, 0x08, 0xFF, 0x47, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko10_11[0x3D2] = { + #embed "../../sdram_params/lz/sdram_params_mariko_10_11.lz4" }; constexpr inline const u8 * const SdramParamsMariko10 = SdramParamsMariko10_11; @@ -743,67 +114,8 @@ constexpr inline const size_t SdramParamsSizeMariko10 = sizeof(SdramParamsMariko constexpr inline const u8 * const SdramParamsMariko11 = SdramParamsMariko10_11; constexpr inline const size_t SdramParamsSizeMariko11 = sizeof(SdramParamsMariko10_11); -constexpr inline const u8 SdramParamsMariko12_13[0x3C0] = { - 0xFF, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2C, 0x01, - 0x00, 0x01, 0x00, 0x96, 0x88, 0x02, 0x80, 0x18, 0x40, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0xF0, - 0x01, 0xFF, 0xFF, 0x1F, 0x00, 0xD8, 0x51, 0x1A, 0xA0, 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x88, - 0x00, 0x04, 0x00, 0x20, 0x20, 0x12, 0x1A, 0x00, 0x17, 0x88, 0x04, 0x00, 0xF7, 0x00, 0x00, 0x00, - 0xBC, 0xBC, 0xAF, 0xC9, 0x3C, 0x9E, 0x00, 0x00, 0x02, 0x03, 0xE0, 0xC1, 0x04, 0x01, 0x00, 0x17, - 0x3F, 0x01, 0x00, 0x00, 0x38, 0x00, 0xD0, 0x04, 0x08, 0x00, 0x00, 0x50, 0x50, 0x50, 0x00, 0xA1, - 0x01, 0x00, 0x00, 0x30, 0x39, 0x00, 0x62, 0x10, 0x00, 0x16, 0x00, 0x10, 0x90, 0x80, 0x00, 0x03, - 0x74, 0x00, 0x13, 0x03, 0x04, 0x00, 0xD7, 0x1E, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x3A, - 0x00, 0x00, 0x00, 0x1D, 0x94, 0x00, 0x57, 0x09, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x13, 0x0B, - 0x28, 0x00, 0x13, 0x08, 0x0C, 0x00, 0x00, 0x1C, 0x00, 0x53, 0x17, 0x00, 0x00, 0x00, 0x15, 0x08, - 0x00, 0x13, 0x1B, 0x28, 0x00, 0x57, 0x20, 0x00, 0x00, 0x00, 0x06, 0x04, 0x00, 0x13, 0x03, 0x18, - 0x00, 0x13, 0x04, 0x10, 0x00, 0x17, 0x02, 0x10, 0x00, 0x00, 0x4C, 0x00, 0x13, 0x0E, 0x18, 0x00, - 0x17, 0x05, 0x6C, 0x00, 0x00, 0x34, 0x00, 0x13, 0x0C, 0xE0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x80, - 0x0A, 0x00, 0x00, 0x0F, 0x01, 0x93, 0x18, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x0C, - 0x00, 0x10, 0x0A, 0x48, 0x00, 0x03, 0x61, 0x00, 0x13, 0xC1, 0x50, 0x00, 0x13, 0x08, 0x40, 0x00, - 0x13, 0x0A, 0x08, 0x00, 0x13, 0x14, 0x5C, 0x00, 0x13, 0x02, 0xC0, 0x00, 0x13, 0x3B, 0x04, 0x00, - 0x13, 0x05, 0x04, 0x00, 0x04, 0x88, 0x00, 0x04, 0x0C, 0x00, 0x00, 0xF8, 0x00, 0x90, 0x1C, 0x03, - 0x00, 0x00, 0x0D, 0xA0, 0x60, 0x91, 0x3F, 0x15, 0x01, 0xF1, 0x28, 0x00, 0xF3, 0x0C, 0x04, 0x05, - 0x1B, 0x06, 0x02, 0x03, 0x07, 0x1C, 0x23, 0x25, 0x25, 0x05, 0x08, 0x1D, 0x09, 0x0A, 0x24, 0x0B, - 0x1E, 0x0D, 0x0C, 0x26, 0x26, 0x03, 0x02, 0x1B, 0x1C, 0x23, 0x03, 0x04, 0x07, 0x05, 0x06, 0x25, - 0x25, 0x02, 0x0A, 0x0B, 0x1D, 0x0D, 0x08, 0x0C, 0x09, 0x1E, 0x24, 0x26, 0x26, 0x08, 0x24, 0x06, - 0x07, 0x9A, 0xBF, 0x01, 0x3C, 0xFF, 0x00, 0xFF, 0x00, 0x02, 0xB0, 0x04, 0x00, 0x01, 0x88, 0x00, - 0x00, 0x02, 0x88, 0x00, 0x00, 0x0D, 0xD5, 0x01, 0xF2, 0x0E, 0xC0, 0x31, 0x31, 0x03, 0x88, 0x00, - 0x00, 0x0B, 0x88, 0x5D, 0x5D, 0x0E, 0x8C, 0x5D, 0x5D, 0x0C, 0x88, 0x08, 0x08, 0x0D, 0x8C, 0x00, - 0x00, 0x0D, 0x8C, 0x14, 0x14, 0x16, 0x88, 0x2C, 0x00, 0x2C, 0x11, 0x08, 0xDF, 0x02, 0x70, 0x10, - 0x00, 0xCC, 0x00, 0x0A, 0x00, 0x33, 0x6E, 0x01, 0x40, 0xF3, 0x25, 0x08, 0x11, 0x69, 0x00, 0x23, - 0x0F, 0x00, 0x30, 0x01, 0x80, 0x01, 0x03, 0x00, 0x70, 0x00, 0x0C, 0x00, 0x01, 0x0C, 0x00, 0xC0, - 0x08, 0x44, 0x00, 0x10, 0x04, 0x04, 0x00, 0x06, 0x13, 0x07, 0x00, 0x80, 0x10, 0x00, 0x71, 0xA0, - 0x00, 0x2C, 0x00, 0x01, 0x37, 0x0F, 0x52, 0x01, 0x11, 0x02, 0x64, 0x01, 0xBB, 0x04, 0x00, 0x1F, - 0x22, 0x20, 0x80, 0x0F, 0xF4, 0x20, 0x02, 0x29, 0x01, 0x00, 0x12, 0x78, 0x9A, 0x02, 0x1F, 0x0F, - 0xF4, 0x02, 0x31, 0x7F, 0x16, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x17, 0x18, 0x00, 0x06, 0xF1, 0x02, - 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x43, 0x00, 0x46, 0x00, 0x47, 0x00, 0x41, 0x00, 0x46, 0x00, - 0x0C, 0xBA, 0x01, 0x1F, 0x0D, 0x18, 0x00, 0x06, 0x1F, 0x28, 0x02, 0x00, 0x0C, 0x11, 0x16, 0x5A, - 0x00, 0x00, 0x5C, 0x00, 0x00, 0x5E, 0x00, 0x3F, 0x17, 0x00, 0x16, 0x94, 0x00, 0x00, 0x05, 0x54, - 0x01, 0xB3, 0x40, 0x06, 0x00, 0xCC, 0x00, 0x09, 0x00, 0x4F, 0x00, 0x51, 0x80, 0x18, 0x00, 0x04, - 0x08, 0x00, 0x01, 0x6E, 0x00, 0x54, 0xAB, 0x00, 0x0A, 0x04, 0x11, 0x5C, 0x01, 0x03, 0x04, 0x00, - 0x0F, 0xE4, 0x03, 0x0E, 0x0B, 0xCC, 0x02, 0x14, 0x01, 0x14, 0x00, 0x75, 0x01, 0x22, 0x04, 0xFF, - 0x9F, 0xAF, 0x4F, 0x10, 0x00, 0x07, 0x34, 0x00, 0x32, 0x9F, 0xFF, 0x37, 0x98, 0x00, 0xF0, 0x10, - 0x32, 0x54, 0x76, 0x10, 0x47, 0x32, 0x65, 0x10, 0x34, 0x76, 0x25, 0x01, 0x34, 0x67, 0x25, 0x01, - 0x75, 0x64, 0x32, 0x01, 0x72, 0x56, 0x34, 0x10, 0x23, 0x74, 0x56, 0x01, 0x45, 0x32, 0x67, 0x24, - 0x00, 0x31, 0x49, 0x92, 0x24, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x13, 0x12, 0x04, 0x00, 0x0C, 0x90, - 0x00, 0x80, 0x20, 0x41, 0x13, 0x1F, 0x14, 0x00, 0x01, 0x00, 0x7C, 0x00, 0x85, 0xFF, 0xFF, 0xFF, - 0x7F, 0x1F, 0xD7, 0x36, 0x40, 0xE6, 0x03, 0x25, 0x34, 0x10, 0xF0, 0x03, 0x0F, 0xCC, 0x00, 0x01, - 0x31, 0x03, 0x00, 0x05, 0x2B, 0x03, 0x22, 0x10, 0x02, 0xDD, 0x03, 0x13, 0x21, 0x15, 0x04, 0x14, - 0x40, 0x8B, 0x02, 0x07, 0x01, 0x00, 0x71, 0x80, 0x00, 0x40, 0x00, 0x04, 0x10, 0x80, 0x04, 0x04, - 0xCF, 0x81, 0x10, 0x09, 0x28, 0x93, 0x32, 0xA5, 0x44, 0x5B, 0x8A, 0x67, 0x76, 0x54, 0x05, 0x4D, - 0x22, 0x10, 0x10, 0x04, 0x00, 0x44, 0x00, 0xEF, 0x00, 0xEF, 0x14, 0x00, 0x4D, 0x1C, 0x1C, 0x1C, - 0x1C, 0x98, 0x01, 0x21, 0x03, 0x08, 0x04, 0x00, 0xF1, 0x03, 0x00, 0x24, 0xFF, 0xFF, 0x00, 0x44, - 0x57, 0x6E, 0x00, 0x28, 0x72, 0x39, 0x00, 0x10, 0x9C, 0x4B, 0x00, 0x10, 0xA4, 0x01, 0xB2, 0x08, - 0x4C, 0x00, 0x00, 0x80, 0x20, 0x10, 0x0A, 0x00, 0x28, 0x10, 0x30, 0x03, 0x08, 0xC0, 0x01, 0x17, - 0x01, 0xC8, 0x01, 0x17, 0x05, 0x10, 0x00, 0x13, 0x04, 0x10, 0x00, 0x12, 0x07, 0x62, 0x00, 0xD2, - 0x02, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, 0xA3, 0x72, 0x0F, 0x0F, 0x00, 0x70, 0x42, 0x00, 0x16, - 0x1F, 0x28, 0x01, 0x43, 0xFF, 0x00, 0xFF, 0x01, 0x70, 0x04, 0x24, 0x00, 0x80, 0x96, 0x00, 0x15, - 0xF0, 0x24, 0x04, 0x60, 0x43, 0xCB, 0xFA, 0xE4, 0xD3, 0xFE, 0x0F, 0x05, 0x3B, 0x80, 0x2A, 0x02, - 0x1C, 0x00, 0x0C, 0xF4, 0x00, 0x19, 0x08, 0x0E, 0x00, 0x01, 0xE6, 0x05, 0x1F, 0x03, 0x2C, 0x00, - 0x05, 0x10, 0x76, 0xE9, 0x03, 0x0F, 0x9C, 0x02, 0x00, 0x05, 0x34, 0x00, 0x0F, 0x3A, 0x00, 0x04, - 0x38, 0x7E, 0x16, 0x40, 0x03, 0x06, 0x0F, 0x38, 0x00, 0x17, 0x3F, 0x1E, 0x40, 0x04, 0xA8, 0x00, - 0x08, 0x2F, 0x00, 0xC0, 0x55, 0x00, 0x04, 0x3F, 0x46, 0x24, 0x00, 0x38, 0x00, 0x0A, 0x0F, 0x01, - 0x00, 0x05, 0x22, 0x46, 0x2C, 0x38, 0x00, 0x19, 0xEC, 0x16, 0x00, 0x0E, 0x3C, 0x01, 0x0F, 0x01, - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2C, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, +constexpr inline const u8 SdramParamsMariko12_13[0x3C2] = { + #embed "../../sdram_params/lz/sdram_params_mariko_12_13.lz4" }; constexpr inline const u8 * const SdramParamsMariko12 = SdramParamsMariko12_13; diff --git a/fusee/program/update_mtc_tables.py b/fusee/program/update_mtc_tables.py index 7a7e0edd1..a6f73b07c 100644 --- a/fusee/program/update_mtc_tables.py +++ b/fusee/program/update_mtc_tables.py @@ -57,6 +57,22 @@ def main(argc, argv): except: pass write_file(os.path.join('mtc_tables/lz/%s' % board, '%d.lz4' % i), compressed) + try: + os.makedirs('mtc_tables/combined/%s' % board) + except: + pass + data_1600 = params[soc][board][-1] + data_800 = params[soc][board][-4] if soc == 'erista' else '' + data_204 = params[soc][board][0] if soc == 'mariko' else params[soc][board][3] + assert up(' Date: Sun, 4 May 2025 13:23:19 -0700 Subject: [PATCH 209/238] exo: use #embed for loader stub --- exosphere/loader_stub/loader_stub.mk | 21 +++------------- .../loader_stub/source/secmon_loader_main.cpp | 24 +++++++++++++------ exosphere/loader_stub/source/start.s | 5 +--- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/exosphere/loader_stub/loader_stub.mk b/exosphere/loader_stub/loader_stub.mk index df737a370..7bffe7dc0 100644 --- a/exosphere/loader_stub/loader_stub.mk +++ b/exosphere/loader_stub/loader_stub.mk @@ -15,13 +15,12 @@ ifneq ($(__RECURSIVE__),1) export ATMOSPHERE_TOPDIR := $(CURRENT_DIRECTORY) export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) $(CURDIR)/include \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ - $(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR) + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) -BINFILES := program.lz4 boot_code.lz4 +BINFILES := #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -102,13 +101,7 @@ $(OUTPUT).elf : $(OFILES) $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libexosphere/$(ATMOSPHERE_LIBRARY_DIR)/libexosphere.a -program.lz4.o: program.lz4 - @echo $(notdir $<) - @$(bin2o) - -boot_code.lz4.o: boot_code.lz4 - @echo $(notdir $<) - @$(bin2o) +secmon_loader_main.o: CXXFLAGS += --embed-dir="$(CURRENT_DIRECTORY)/../program/$(ATMOSPHERE_OUT_DIR)/" %.elf: @echo linking $(notdir $@) @@ -117,14 +110,6 @@ boot_code.lz4.o: boot_code.lz4 $(OFILES_SRC) : $(OFILES_BIN) -#--------------------------------------------------------------------------------- -# you need a rule like this for each extension you use as binary data -#--------------------------------------------------------------------------------- -%.bin.o %_bin.h: %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -include $(DEPENDS) #--------------------------------------------------------------------------------------- diff --git a/exosphere/loader_stub/source/secmon_loader_main.cpp b/exosphere/loader_stub/source/secmon_loader_main.cpp index 368941eb1..782d7ac11 100644 --- a/exosphere/loader_stub/source/secmon_loader_main.cpp +++ b/exosphere/loader_stub/source/secmon_loader_main.cpp @@ -15,21 +15,31 @@ */ #include #include "secmon_loader_uncompress.hpp" -#include "program_lz4.h" -#include "boot_code_lz4.h" namespace ams::secmon::loader { - NORETURN void UncompressAndExecute(const void *program, const void *boot_code) { + namespace { + + constexpr const u8 SecmonProgramLz4[] = { + #embed + }; + + constexpr const u8 SecmonBootCodeLz4[] = { + #embed + }; + + } + + NORETURN void UncompressAndExecute() { /* Uncompress the program image. */ - Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program, program_lz4_size); + Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), SecmonProgramLz4, sizeof(SecmonProgramLz4)); /* Copy the boot image to the end of IRAM */ - u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer() - boot_code_lz4_size; - std::memcpy(relocated_boot_code, boot_code, boot_code_lz4_size); + u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer() - sizeof(SecmonBootCodeLz4); + std::memcpy(relocated_boot_code, SecmonBootCodeLz4, sizeof(SecmonBootCodeLz4)); /* Uncompress the boot image. */ - Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size); + Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, sizeof(SecmonBootCodeLz4)); /* Jump to the boot image. */ reinterpret_cast(secmon::MemoryRegionPhysicalIramBootCodeImage.GetAddress())(); diff --git a/exosphere/loader_stub/source/start.s b/exosphere/loader_stub/source/start.s index 47838e5fa..6640ac2d9 100644 --- a/exosphere/loader_stub/source/start.s +++ b/exosphere/loader_stub/source/start.s @@ -98,8 +98,5 @@ _start: ldr x20, =0x7C020000 mov sp, x20 - adr x0, program_lz4 - adr x1, boot_code_lz4 - /* Uncompress the program and iram boot code images. */ - b _ZN3ams6secmon6loader20UncompressAndExecuteEPKvS3_ + b _ZN3ams6secmon6loader20UncompressAndExecuteEv From b2dd3b7dcee0f7db93dd4aca84f63e0043cabb91 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 4 May 2025 13:23:38 -0700 Subject: [PATCH 210/238] boot: use #embed for fusee --- stratosphere/boot/source/boot_power_utils.cpp | 15 +++++++++------ stratosphere/boot/system_module.mk | 19 +++++++------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/stratosphere/boot/source/boot_power_utils.cpp b/stratosphere/boot/source/boot_power_utils.cpp index 3f057e87c..a4d8104be 100644 --- a/stratosphere/boot/source/boot_power_utils.cpp +++ b/stratosphere/boot/source/boot_power_utils.cpp @@ -16,7 +16,6 @@ #include #include "boot_power_utils.hpp" #include "boot_pmic_driver.hpp" -#include "fusee_bin.h" namespace ams::boot { @@ -32,6 +31,10 @@ namespace ams::boot { /* Globals. */ alignas(os::MemoryPageSize) u8 g_work_page[os::MemoryPageSize]; + constexpr const u8 FuseeBin[] = { + #embed ATMOSPHERE_BOOT_FUSEE_PATH + }; + /* Helpers. */ void ClearIram() { /* Make page FFs. */ @@ -48,8 +51,8 @@ namespace ams::boot { ClearIram(); /* Copy in payload. */ - for (size_t ofs = 0; ofs < fusee_bin_size; ofs += sizeof(g_work_page)) { - std::memcpy(g_work_page, fusee_bin + ofs, std::min(static_cast(fusee_bin_size - ofs), sizeof(g_work_page))); + for (size_t ofs = 0; ofs < sizeof(FuseeBin); ofs += sizeof(g_work_page)) { + std::memcpy(g_work_page, FuseeBin + ofs, std::min(static_cast(sizeof(FuseeBin) - ofs), sizeof(g_work_page))); exosphere::CopyToIram(IramPayloadBase + ofs, g_work_page, sizeof(g_work_page)); } @@ -61,8 +64,8 @@ namespace ams::boot { ClearIram(); /* Copy in payload. */ - for (size_t ofs = 0; ofs < fusee_bin_size; ofs += sizeof(g_work_page)) { - std::memcpy(g_work_page, fusee_bin + ofs, std::min(static_cast(fusee_bin_size - ofs), sizeof(g_work_page))); + for (size_t ofs = 0; ofs < sizeof(FuseeBin); ofs += sizeof(g_work_page)) { + std::memcpy(g_work_page, FuseeBin + ofs, std::min(static_cast(sizeof(FuseeBin) - ofs), sizeof(g_work_page))); exosphere::CopyToIram(IramPayloadBase + ofs, g_work_page, sizeof(g_work_page)); } @@ -93,7 +96,7 @@ namespace ams::boot { } void SetInitialRebootPayload() { - ::ams::SetInitialRebootPayload(fusee_bin, fusee_bin_size); + ::ams::SetInitialRebootPayload(FuseeBin, sizeof(FuseeBin)); } void RebootForFatalError(ams::FatalErrorContext *ctx) { diff --git a/stratosphere/boot/system_module.mk b/stratosphere/boot/system_module.mk index be26006df..f460aae73 100644 --- a/stratosphere/boot/system_module.mk +++ b/stratosphere/boot/system_module.mk @@ -23,7 +23,7 @@ CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c) CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp) SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee.bin +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -67,15 +67,18 @@ endif .PHONY: clean all check_lib check_fusee #--------------------------------------------------------------------------------- -all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a +all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a $(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin @$(MAKE) __RECURSIVE__=1 OUTPUT=$(CURDIR)/$(ATMOSPHERE_OUT_DIR)/$(TARGET) \ DEPSDIR=$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) \ --no-print-directory -C $(ATMOSPHERE_BUILD_DIR) \ -f $(THIS_MAKEFILE) -$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib check_fusee +$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib @$(SILENTCMD)echo "Checked library." +$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin: check_fusee + @$(SILENTCMD)echo "Checked fusee." + ifeq ($(ATMOSPHERE_CHECKED_LIBSTRATOSPHERE),1) check_lib: else @@ -124,15 +127,7 @@ $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR @npdmtool $< $@ @echo built ... $(notdir $@) -boot_power_utils.o: fusee.bin.o - -#--------------------------------------------------------------------------------- -# you need a rule like this for each extension you use as binary data -#--------------------------------------------------------------------------------- -fusee.bin.o: fusee.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) +boot_power_utils.o: CXXFLAGS += -DATMOSPHERE_BOOT_FUSEE_PATH=\"$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin\" -include $(DEPENDS) From f9165c472e103a2f998654d13887200d63f4c6c9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 4 May 2025 13:31:08 -0700 Subject: [PATCH 211/238] docs: add gcc15 to changelog --- docs/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.md b/docs/changelog.md index 664570043..d498e3242 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,6 +19,7 @@ + `pm` was updated to reflect the latest official behavior. + `ncm` was partially updated to reflect the latest official behavior. + `erpt` was updated to reflect the latest official behavior. ++ Atmosphère was updated to use GCC 15/newlib (latest devkitA64/devkitARM releases). + A number of improvements were made to the dmnt cheat engine. + New instructions were added, and instructions were updated for improved/new functionality. + Please see the documents for details -- thanks @tomvita! From d5567b53638aeb0dd31506c9daf02a76ebb27598 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 7 May 2025 12:46:54 -0700 Subject: [PATCH 212/238] pm: update for fsp-pr RegisterProgram api change --- stratosphere/pm/source/impl/pm_process_manager.cpp | 2 +- stratosphere/pm/source/pm_main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 50600f0d4..8a4d7ba16 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -195,7 +195,7 @@ namespace ams::pm::impl { const u8 *aci_fah = acid_fac + program_info.acid_fac_size; /* Register with FS and SM. */ - R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(fixed_location.program_id), static_cast(fixed_location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size)); + R_TRY(fsprRegisterProgram(static_cast(process_id), static_cast(fixed_location.program_id), static_cast(fixed_location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size, 0)); R_TRY(sm::manager::RegisterProcess(process_id, fixed_location.program_id, override_status, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size)); /* Set flags. */ diff --git a/stratosphere/pm/source/pm_main.cpp b/stratosphere/pm/source/pm_main.cpp index b7d775be9..5bef871c7 100644 --- a/stratosphere/pm/source/pm_main.cpp +++ b/stratosphere/pm/source/pm_main.cpp @@ -53,7 +53,7 @@ namespace ams { /* It also registers privileged processes with SM, so that their program ids can be known. */ void RegisterPrivilegedProcess(os::ProcessId process_id, ncm::ProgramId program_id) { fsprUnregisterProgram(process_id.value); - fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl)); + fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl), 0); sm::manager::UnregisterProcess(process_id); sm::manager::RegisterProcess(process_id, program_id, cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl)); } From f1ca7db5628dbfea357d4a12476f1b5b1bae93cc Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 9 May 2025 11:58:56 -0700 Subject: [PATCH 213/238] boot: use --embed-dir for fusee embed --- stratosphere/boot/source/boot_power_utils.cpp | 2 +- stratosphere/boot/system_module.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stratosphere/boot/source/boot_power_utils.cpp b/stratosphere/boot/source/boot_power_utils.cpp index a4d8104be..0dc71b842 100644 --- a/stratosphere/boot/source/boot_power_utils.cpp +++ b/stratosphere/boot/source/boot_power_utils.cpp @@ -32,7 +32,7 @@ namespace ams::boot { alignas(os::MemoryPageSize) u8 g_work_page[os::MemoryPageSize]; constexpr const u8 FuseeBin[] = { - #embed ATMOSPHERE_BOOT_FUSEE_PATH + #embed }; /* Helpers. */ diff --git a/stratosphere/boot/system_module.mk b/stratosphere/boot/system_module.mk index f460aae73..2f28eeee1 100644 --- a/stratosphere/boot/system_module.mk +++ b/stratosphere/boot/system_module.mk @@ -127,7 +127,7 @@ $(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR @npdmtool $< $@ @echo built ... $(notdir $@) -boot_power_utils.o: CXXFLAGS += -DATMOSPHERE_BOOT_FUSEE_PATH=\"$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/fusee.bin\" +boot_power_utils.o: CXXFLAGS += --embed-dir="$(ATMOSPHERE_LIBRARIES_DIR)/../fusee/$(ATMOSPHERE_BOOT_OUT_DIR)/" -include $(DEPENDS) From 0e2ef545f947d24c6add254874ab493ba84bbdc9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 9 May 2025 12:00:44 -0700 Subject: [PATCH 214/238] fusee: commit mtc table combined bins, to remove need for running py script outside of makefile --- .../T210SdevEmcDvfsTableH4gb01/table.bin | Bin 0 -> 14784 bytes .../T210SdevEmcDvfsTableS4gb01/table.bin | Bin 0 -> 14784 bytes .../T210SdevEmcDvfsTableS6gb01/table.bin | Bin 0 -> 14784 bytes .../T210b01SdevEmcDvfsTableH1a4gb01/table.bin | Bin 0 -> 1667 bytes .../T210b01SdevEmcDvfsTableH1y4gb01/table.bin | Bin 0 -> 1665 bytes .../T210b01SdevEmcDvfsTableH4gb03/table.bin | Bin 0 -> 1669 bytes .../T210b01SdevEmcDvfsTableM1a4gb01/table.bin | Bin 0 -> 1665 bytes .../T210b01SdevEmcDvfsTableM1y4gb01/table.bin | Bin 0 -> 1668 bytes .../T210b01SdevEmcDvfsTableM4gb03/table.bin | Bin 0 -> 1673 bytes .../T210b01SdevEmcDvfsTableS1y4gb01/table.bin | Bin 0 -> 1677 bytes .../T210b01SdevEmcDvfsTableS1y4gbX03/table.bin | Bin 0 -> 1670 bytes .../T210b01SdevEmcDvfsTableS1y4gbY01/table.bin | Bin 0 -> 1673 bytes .../T210b01SdevEmcDvfsTableS1y8gb04/table.bin | Bin 0 -> 1678 bytes .../T210b01SdevEmcDvfsTableS1y8gbX03/table.bin | Bin 0 -> 1672 bytes .../T210b01SdevEmcDvfsTableS1y8gbY01/table.bin | Bin 0 -> 1683 bytes .../T210b01SdevEmcDvfsTableS1z4gb01/table.bin | Bin 0 -> 1667 bytes .../T210b01SdevEmcDvfsTableS4gb01/table.bin | Bin 0 -> 1666 bytes .../T210b01SdevEmcDvfsTableS4gb03/table.bin | Bin 0 -> 1666 bytes .../T210b01SdevEmcDvfsTableS4gbY01/table.bin | Bin 0 -> 1680 bytes .../T210b01SdevEmcDvfsTableS8gb03/table.bin | Bin 0 -> 1694 bytes 20 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS6gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1a4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM4gb03/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbX03/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gb04/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gbY01/table.bin create mode 100644 fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin diff --git a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin b/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableH4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..f0de1ed563b4989a87433e288a84c59127c07b8d GIT binary patch literal 14784 zcmZQ)U|=vbh&M7YF)%QQ_se%qOAkveD$dN$ix0EZv(Ph-4>Qy=W55X>$S^Y~Ff%at zurM$bE(o)36cY0ke%F6d5~QS3=9lxNSGNa z2NDCxGeP+vHb^hX43OJE@=z%Tkeb3mW)6@X$Q=v}3=JS(3PJrM#=yV;W3xalI0*GW z$V`wB48!~mG81H;Is*d(2!redVURmOenMs!7BYLtfDB+@VBlSlFmb;%1H%Fa9k46* zF)%Rv=Z8R;dl57@hX{iZg8+jFg8_pcgE4~vgE50Cg8_pPJp6Hqi!gw6g7kuPgLnv2 z2P;cnNuh!NivklUE*Kox7|t+oGKeyqVc=pgW?*K1a8Tb-SYCvIk%5JSfgu1CzzhnX zK_Ms1&d>l#XE1+BGcYiKFarYCT}@fPuk5h%qZ#h><~ngP$Qn zfPvwUfFOe~j4dL_z|6o7QWs?t8Y&_p=229{(*eaGwntGBUk?=f6czFLfYR`2o=ljD zoF_v^^CUb`(;`nAH?XoYFtDRJ?)sp!x^oevloYDhDbK_6CR#ss};lg8U1q2U*~C zAE+Dxl|i7ghUWF4!)QGSiZ5)K26@iFya8NcG7P4A5R?W%c}@`oUC?A39cu@X=VNkmjgh70eJTz~C+r%KfATvOr43cMH zU@%~UUJD_=PwCxFsTCA7`d2Ud)J)vn3+=s(#d$KSzY@lA-Q-c9N#2OJp zNKg<8G@t<8>7X7MsP}~~KFY@)0-lpp7?3e`RR~c~TZM&@fnf`@-3Bdp5ef!?#mK?>?Fd%sl21OJo z?qF>g5FeChK5{WV<4chFHHsp z22k4y#Qp$nK>cB2U;ya@VNlwKVPytL9D~w5$eq&|7#KhpWFII2f!qUfGsq1fcY)jk z8b31tNrL)D&^F9&CiVlMQ9Mvz9pqQ+n45!*ft7)kfsFxVKMMmBIK_e3P=DYQXJdfq zgy;tGu-h=0MA6$Y3e1uW@(c>hJPaoo*x=)53=Hf@<7XiEpO9c^5C<`!7*u|MFlhV? zl%7Gtf}jWkB|ruSE=EQMCUAO!j-M$gfXB~3&3KSfFs5YuOyCjj@v{?1<7c4s268tj z{ek)opmYODm$31(35+Z>A3p;H$!MO0jGv9>NpR9fA!w2(8=zJUqC5#IPeFZoT?PgQ zP@dEW_31^#I1qUfGJZylJc%#Qf##?{bqA;}1Jy5}kOI{sAa{VuED#3CfhsmoeZ~f@ zGeI;+9Y_v@LG=zuEhvb&q4glBzXYlWLFR+}3#td18CV%W{sxsrpmKNrKpH;-wZA~+B&hojaw7WvpooAb8c@7InPgL-H8&u0XtDk*0W`A;TIs^4#K=QCQ3`ib?LHPqz=7Z+RLFtT-fq?;}9@H-Yu|eq%)NfE> zfQ)^~Fo3691wixZA3rj4fXo2-4b*SoVPFHVF|uJ`V6bCgV6b9fU;wcdKphxRpM(w4 z=>XXYO8+oy!N9-(vI`XKdLVZ*GBD^cGBAMb1!)Dj2NZ^&aY2y#p>}&DfFvQ~XEXm> zGcfFCWFRHm9}LFntxCL|)(pMlaF$lajy2WrEB#_T}p z64q}}U}ixXKVvY$vHmO=Y5kcq13O3^Z2g&s2TunSdw6*8czAg5^+2(YhXIF~%-~=ku85kHq^%82Hgp8k2BTwSX zbK20c1W-MKuO0-ou?W?Jpt&AUJtYUN2SMsV^&qHh1o;fq6~CoJ_r=+U<4@N9cR%YATP z2bAtXc@323;B8On_!%|oIsBt%pbJc^a1RXB`$88V zs{S2p?nWO!8;BGI>f4rHAD4GtinU(E2lGA<+0)1A_%a1A`+&1H%M{1_o9n8Zv&?z`(-L zz#zuJ0b0%jW=k?OFo3WGLj%K9h6V;%h6b=4sJsBNKy%9>42&GQ44`dXpx!vc0S^z- W)}MjK&p^8w!Q~Nj{A>;j0|NjU3vQVJ literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin b/fusee/program/mtc_tables/combined/T210SdevEmcDvfsTableS4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..99cc3a02ed3a7276198848b9de40022b2acf4e03 GIT binary patch literal 14784 zcmZQ)U|=vbh&M7YF)%QQ_se%qOAkveD$dN$ix0EZv(Ph-4>Qy=W55X>$S^Y~Ff%at zurM$bE(o)$<4sP0FnpU31Wkkfb3FWU|?WF z!ptBEC?6!x1m%O+AiW?nKyCx+fl4ue)D#vnbAaSPVi5Bg8HAvI5o2J0vss`P9EAEG zWF|-mhGBjOnF%saoq>S?gh6(KFvuMsKOwUV3zYn?r;_h(Ulsgu#G8kHMJ1fWer-l)-?(2p;~p#6=iDIzf6txC|(#G*ci?*a59K8oMGT%FlJz8esECVQCMDtfsuiQgMlFc6u=A$ zpFtrf%+AmNN@p-XNi#4ofG`6C6N5Q4qy#{ckc`A7$jHD1idPN}W(I~BMg{=^0R{$8 zA^@p@ViN`i259C2X$32XN-;19Fff49C7h4O`2YU@`vXvL=gyrwTu8t;K?0N&z&b!_ z3FK~&)gmHd9AJMlFfueuU|?WjVP{WeU}2DN5N2f%6p#n0btn>GU~mv(%!(FbWDwxs zXNVABVE7{-$RG@3iwH6>Gq8iyMcIUgiin7L6czDwKrx8zQB=g&1I0c?MSMP>G(4Io z6J{dk$+<$Xt+r8Nf9V3%u?Fl|!I12vpY4ydHEItp`Ezg$>gn&l#9EfGbQ;)ivnyoE#{x zF+l26P(3IE4ipxu)`Ot@fUBP41GUSb?LAQ509g;pN9cJD)NTb~Q2qnSL-Q86O$^I( zpil>=PeNreF!V^@U`1*KUQ zMh1p0&~_WN+(jrD02U(y1BVX-LxX|<7lVcXLjx?of!bamHmE*;(V)5l#s}3WpgII3 z24XWZFflPQF*C5R9xmkPXDEPpMV>*5p@AR<^?gC=e3%#*HZlBXxW(|FVJ^deFysM~ z{~18ECqq3$1H*p?7KZ-}YZ*8g{)5M2{xck7fZ$xH+DBj-+*ky&M8WD9IT*m*XkL)B z4-^&g!J4FCr``yZS^(*#moqRhU}9DdK?V*67VuaTXdDX^CNaDW4AAj23j+`!WBiQ4 zl!w6*F@BaCUz!4T4_2ZMBiOU|{e-a-I?c0|P$;1A{mN1A`#6 z4I>Ga2c;uW8wMl~!k~x(#T~2-1LA}73`iY_4Z@&y3dkH#JaBffYOk0vh|$WME(bwXHzx50C~9!yhIF29Q1w2Bm!%R%U?2F(}=G+&PVbfdPa; z_JPa=xd-HCkQ+em0=Wk?er5oY1hvzkZJ6Cm><2*OXP~}1)Vo+HZVomERt8oEHU^OW zEDTKG6bE91(i=zvh>cC0jRB$)q8r2msUF-Iy$z$lEXg3xpuo(-aDssiK7Pi)z>YM2 z2J+Df35Etx`T?;)7*u|MFlhV?l%7Fip!k6G)fpKXn84`?I)0|003JUBHRC}_!I+Zq zGl56A$Inh6jh}(i8_3pUBbrCCNQ$leEe)QPcks@E`W@mjpj*k(nld^ zk|!IGtN6f}OO3$2UvL4A4=F%CqYgp8k2BTs_7jH@05^=Ck36{s!) z)i0os0@WiRcYw+)5C+MC2E;)185^|D1koUMAUO~Q)jJ@ypn8fMS`UKyOQ3oXWIo8h zpz$+i237`;zd>aYs2rkOJqR5?8_jc|7)Hf3$a4n9&^!l<`@vEVg3=%;?HNMnXF+u} zs2&8RLr}V;W<7{6&w=V-P`H5d4Zb`#+V*4ww?jek21>D`ZBGV&Z zUIXPhQ2hdKdqT(0s8P=;FyM!vG&GbkbodNTDKp43s4ysju`+`KvVJdUL<8+UP&=#vY5WY-{sNVgpzc4&jUWulgCKEGeFNfy^nhp(AH)XLMa<01 z%xo;|47@^ZB#)nEFff3}*qAsO7;G8-GgvVEXK-Zr&oF`EKLaZg?a5#QA3xJU8b32) z_|E{sN(}!QwlMr>umX>oF@RS5fLWkATZMs-H> z3^aa5&H}V735IeK#?L;0A_AIdK=A@)l1+iu+SNp0|Th<0CS)V0|SFB z0|SE=v<(GHXP`a|NFLN50F~SKV?8ED=Rq#o2S0I@;o57ci^VStQ% z$uKYoFflL)facRbeq`nVnE{G>kXjxFHU`ibi46k-gB=3{gB1e<1Bk5vT4V?6ldwTL z9UwbF=^utI7#J8p`a!|2$H2g#!wA73dqG-3?g51%Xj~BFeyH6Z2_Q+x_}R?=)(i~0 z85szUpQWX7bMP>5GjK8RfX8Jy8CV%O7?{9pkb6L31j={V#CaG%Izf6txcNfC z`wb3kh79@)4s7BK6BxNb<7bJW^=AwWpb>A_`ZJJ^dJGsEbU+L!292G8FplvvCQx4; z6mGEfXQ1)3|MLGqNdsyE12}Df;*kN83_wW>gdy?-)}IL|{eKTp$iRTU{%k@bV*ME? zy@A{fN`Ig>3@AN<(j~0lpuo(6GJeKjgk$|#Fw*)nX9jkVI@tO%4-cLWDE9F1;PLSA z;Ol{69}f>cpV2%C89y7%ldu$vO4B4yf@@2tJ)n*)1H*vlNl={!Dgc~7WjX@`1E^j? z&6AMvGiu~Xe0dJkp8>7)2Gt|@>OoK&i%>lXn(G18Q*zLH5TqVd4}!`@kbgnrXM6)y z4>}}_)`QS2fKJgM&tV%s8#H;&je&syv?T*HuL{a@p!yJ$E~!}$;>&ZRZBO(R$iOh# z_8gvVPiVOh?(1M}dqT(0s8P@1A3X#0>@d^aP!fR;oIx3C3~~&b3@Tu(#-IT1fq{Bo z=;A}kkAvB*=;LPtk)l9-d}Iu2w;_+8u|e0{fV%&n`AiT7_1!@jG-d$mhk`IjAE<)~ z8p{B++nAZzSa~>j86;JDNFF}}t*HX7KVudGjh{6zSTHm&I5IRaOkikWU`3)K<7W*F zEDQ|{VhkLhQy=W55X>$S^Y~Ff%at zurM$bE(o)$<4sP0FnpU31Wkkfb3FWU|?WF z!ptBEC?6!x1m%O+AiW?nKyCx+fl4ue)D#vnbAaSPVi5Bg8HAvI5o2J0vss`P9EAEG zWF|-mhGBjOnF%saoq>S?gh6(KFvuMsKOwUV3zYn?r;_h(Ulsgu#G8kHMJ1fWer-l)-?(2p;~p#6=iDIzf6txC|(#G*ci?*a59K8oMGT%FlJz8esECVQCMDtfsuiQgMlFc6u=A$ zpFtrf%+AmNN@p-XNi#4ofG`6C6N5Q4qy#{ckc`A7$jHD1idPN}W(I~BMg{=^0R{$8 zA^@p@ViN`i259C2X$32XN-;19Fff49C7h4O`2YU@`vXvL=gyrwTu8t;K?0N&z&b!_ z3FK~&)gmHd9AJMlFfueuU|?WjVP{WeU}2DN5N2f%6p#n0btn>GU~mv(%!(FbWDwxs zXNVABVE7{-$RG@3iwH6>Gq8iyMcIUgiin7L6czDwKrx8zQB=g&1I0c?MSMP>G(4Io z6J{dk$+<$Xt+r8Nf9V3%u?Fl|!I12vpY4ydHEItp`Ezg$>gn&l#9EfGbQ;)ivnyoE#{x zF+l26P(3IE4ipxu)`Ot@fUBP41GUSb?LAQ509g;pN9cJD)NTb~Q2qnSL-Q86O$^I( zpil>=PeNreF!V^@U`1*KUQ zMh1p0&~_WN+(jrD02U(y1BVX-LxX|<7lVcXLjx?of!bamHmE*;(V)5l#s}3WpgII3 z24XWZFflPQF*C5R9xmkPXDEPpMV>*5p@AR<^?gC=e3%#*HZlBXxW(|FVJ^deFysM~ z{~18ECqq3$1H*p?7KZ-}YZ*8g{)5M2{xck7fZ$xH+DBj-+*ky&M8WD9IT*m*XkL)B z4-^&g!J4FCr``yZS^(*#moqRhU}9DdK?V*67VuaTXdDX^CNaDW4AAj23j+`!WBiQ4 zl!w6*F@BaCUz!4T4_2ZMBiOU|{e-a-I?c0|P$;1A{mN1A`#6 z4I>Ga2c;uW8wMl~!k~x(#T~2-1LA}73`iY_4Z@&y3dkH#JaBffYOk0vh|$WME(bwXHzx50C~9!yhIF29Q1w2Bm!%R%U?2F(}=G+&PVbfdPa; z_JPa=xd-HCkQ+em0=Wk?er5oY1hvzkZJ6Cm><2*OXP~}1)Vo+HZVomERt8oEHU^OW zEDTKG6bE91(i=zvh>cC0jRB$)q8r2msUF-Iy$z$lEXg3xpuo(-aDssiK7Pi)z>YM2 z2J+Df35Etx`T?;)7*u|MFlhV?l%7Fip!k6G)fpKXn84`?I)0|003JUBHRC}_!I+Zq zGl56A$Inh6jh}(i8_3pUBbrCCNQ$leEe)QPcks@E`W@mjpj*k(nld^ zk|!IGtN6f}OO3$2UvL4A4=F%CqYgp8k2BTs_7jH@05^=Ck36{s!) z)i0os0@WiRcYw+)5C+MC2E;)185^|D1koUMAUO~Q)jJ@ypn8fMS`UKyOQ3oXWIo8h zpz$+i237`;zd>aYs2rkOJqR5?8_jc|7)Hf3$a4n9&^!l<`@vEVg3=%;?HNMnXF+u} zs2&8RLr}V;W<7{6&w=V-P`H5d4Zb`#+V*4ww?jek21>D`ZBGV&Z zUIXPhQ2hdKdqT(0s8P=;FyM!vG&GbkbodNTDKp43s4ysju`+`KvVJdUL<8+UP&=#vY5WY-{sNVgpzc4&jUWulgCKEGeFNfy^nhp(AH)XLMa<01 z%xo;|47@^ZB#)nEFff3}*qAsO7;G8-GgvVEXK-Zr&oF`EKLaZg?a5#QA3xJU8b32) z_|E{sN(}!QwlMr>umX>oF@RS5fLWkATZMs-H> z3^aa5&H}V735IeK#?L;0A_AIdK=A@)l1+iu+SNp0|Th<0CS)V0|SFB z0|SE=v<(GHXP`a|NFLN50F~SKV?8ED=Rq#o2S0I@;o57ci^VStQ% z$uKYoFflL)facRbeq`nVnE{G>kXjxFHU`ibi46k-gB=3{gB1e<1Bk5vT4V?6ldwTL z9UwbF=^utI7#J8p`a!|2$H2g#!wA73dqG-3?g51%Xj~BFeyH6Z2_Q+x_}R?=)(i~0 z85szUpQWX7bMP>5GjK8RfX8Jy8CV%O7?{9pkb6L31j={V#CaG%Izf6txcNfC z`wb3kh79@)4s7BK6BxNb<7bJW^=AwWpb>A_`ZJJ^dJGsEbU+L!292G8FplvvCQx4; z6mGEfXQ1)3|MLGqNdsyE12}Df;*kN83_wW>gdy?-)}IL|{eKTp$iRTU{%k@bV*ME? zy@A{fN`Ig>3@AN<(j~0lpuo(6GJeKjgk$|#Fw*)nX9jkVI@tO%4-cLWDE9F1;PLSA z;Ol{69}f>cpV2%C89y7%ldu$vO4B4yf@@2tJ)n*)1H*vlNl={!Dgc~7WjX@`1E^j? z&6AMvGiu~Xe0dJkp8>7)2Gt|@>OoK&i%>lXn(G18Q*zLH5TqVd4}!`@kbgnrXM6)y z4>}}_)`QS2fKJgM&tV%s8#H;&je&syv?T*HuL{a@p!yJ$E~!}$;>&ZRZBO(R$iOh# z_8gvVPiVOh?(1M}dqT(0s8P@1A3X#0>@d^aP!fR;oIx3C3~~&b3@Tu(#-IT1fq{Bo z=;A}kkAvB*=;LPtk)l9-d}Iu2w;_+8u|e0{fV%&n`AiT7_1!@jG-d$mhk`IjAE<)~ z8p{B++nAZzSa~>j86;JDNFF}}t*HX7KVudGjh{6zSTHm&I5IRaOkikWU`3)K<7W*F zEDQ|{VhkLhE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2M<{P37H562i^q<6Kfa^7cl6wF$h+OG3fv24`XEh$iv+s#=y(K%^=R; z%;3u4%HYi4#^BE2$l%7n)5jpsE5X2~AjV+Dz+l6`V8k)gLiUP+;W|BC|C z48{+93=V7zXBapc1Q^aRa4{G&Ffl(ksNg6pFT%jcFf)cRfrEh|ARs`AN#L^sW4JIo zLj#u&gRl?_0}}(2AnSZaWdWu@CWa?W!Yq@R^i2dNFt9OKGIJ_2%x_?DU|hrL;@2-2a}VCh*-xCh7atF3=I<)7+6@? z*;5%<7~~s-Ss4TcF=j;zF)|2n@H0dRFfjZP5M&VM;18(bVff50 zBFMnZ!0uBdzz}5<8Y&_pb|N;Gr-Ow-=mZOcGG7l1gMbeU1OEo*|D5tOH!%N?o6pd| z#>T+F%EqvPxrU*KNkCqOfjNUoSZ)Keyub!#2mT4noWgu84Ez(A6&X?(<%K6Oi!&Ir z${S2zW|n7hVE_NWK%UWooy(tvp<%-WW^;WF1||k>eny71(wdA6JPHgf9?blV4FAO} zJtwKKfC8SEVGEN33nK%A7?-d_3oCB`bCeT5LjtD=gB&9d1OFd}yzfkm3=AAT3=9nl z0$dCl0t^j|H#mhE|FE)fFbK2qFo-j@urY`*2(lY7JYr&EWMXDuVO?Cr&(Bcc#t<*h zAjQzY!oVjeEx_`Tse!?ViGg7g!+(Zb4F4JCGW=&^5a;1w_{ikRP|wi7@SlN&;XlJ# z1`dY*9Sp|*8IG|q2S@iu<@S}a1}_XWOQd_V0fUyAnY=SQ&=;FfkB2-T-S$_VGrkYWd=~nW?*pa;S`o- zVGtHr!6_{EhFO@;g+ZL_4krT#gRlw@gOE%Qr+~l_hVYLcnLA{9I4AQkurU}jFfds9 za0;9AFeocXOkfgXD_{^7_`oPE&cPsTk;1^x&zPjgz`$^Zk%d8+*Mw1+=LoyFk^^Jf z$B)b>5+r&!8EP2)cQY~^=;7qu%Erds!OOtGz{bFrz$MIlfJ>0Qi9w!2f`N^pgHw=0 z0pvr~0 znp;?~hqJLofXSg%gvp_YQ(mEm(?Oo0hm&7zLgE<#h6*NO?G7e}9!^1H4<=DI8D4z_ z<{nOw;9w4Z0jD0$cxMK7Hsvz{?9Lt@m>D2ms9^)MJSg$AoDmSV-@q*IxPjS&e*!bF zyb>sNe*&d$UU_iRRsbjMGXi_RFsd^sGN>~sFsLyoGiWg=F?cZZNPrUee>09V0%GjO zBK&6r776iu;b%P~Aj~#LfZ;H!Fh8h>WML5JJtH8@Q^6+86~MNifq{*chl7_vQYGh% zfSmA!GXme)n1vV^Y#ACDEEpOX92puICNMNGuyQaIcrutUG%z&$5=mkZW8h$DU=vkl zkYr()D8bOcFqNT!K~{~ykbyzx4ufFB3^s9&GXmnAd&K1#&IkxphB1b+hO#p8FbFf= uVP{}u5Z32l2oGUk?9e?Upzq;vMnGEH^o#&QfWQF;1_p*XpsIj@fdK%c|25M9 literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH1y4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..72fb85c13fab78496b518393fe65281bb5063ac0 GIT binary patch literal 1665 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXBr=7q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC%s+Oay}i?}CJhHH?M}7SU|>@aW3Xaiuwh`ZV-OU7z`)PQ(Ayxdq|m_s zMS*Ds;|D$l2R4Q?44e!C3}+a)7>pU1m>(Qea1@poVPIsK8N-;s!N3p@5TL{)@Y#Ve zT$r7qfy;+MScrvziGfLwbv~oA08=0n!xJW9mPt(dCIS-}*qAGsITab^H!wIbun06T zD4b;AG+tYZhm2X;n=h6xM| zEG+EosSGR(@(seQ41xmk4NM>S9f|}P7#xHcv!aC<83Z`^86pH282$(dG6-|<2h{K| zd}bFBWMF1s_bC!!h_VR{6%i3T5gW_X!NMSPf`vhuuZM*}z=wr_e*^P>PWhP|nE%Jk zXJ}w!V_;xqW7xo4!_dPdAg{u}Y{Dcgw}Dw+U<0!Q{{&`EVLlcH{t3*A3@MEA!V{Rq z8H`!w4JI%%%dO01pETDT zje$KtfPsfWErxdrW4(c4yrG$a!C3)ijVy^X0{*%2r71cL?1~K%JWQG&m~@!<3z+nj z{#)m;@t+ZJ6-cOLbZ2B>c%Z@{>@tT_STluzL55RY*N2l~59f4c22iSIU~uf=6qaRS z5awCIDJ=GeS(s0RL7eLjr!b!jgAhjv7ehU}fWQ%k@Q)vvJ7jt|C-X3{F&Hy2Fj)F< z3Y+sVC@V-zU=m^rU=kMiz$h%v!60mr!obkan54(Rz;Ff>_Pi#H3=eybK%+Yz%w}T*Ax;xCGgo800x57}yv(I0ZQr zK<*UeTfo5I!#VeY1Dhd(K7#|BIKu=+&K^#o#2(J*4J-@{ygi)pJq8R7+A_SXiVSS0 zxrGILI2&68m>gO~m>haIFLx42}#93=8k v@31p4G6?H)FocINFm~vk5zzPWI3pk}ZF)w4Awb{&0|NuY98g8Tz`y_i%@{We literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableH4gb03/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..ca8213bf418bd7fa793917b3a267bc6cefc87162 GIT binary patch literal 1669 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)RXBZ!5q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2MO*rV`Tow!`&gqz{|kR zAkN^-;L702;LPC0;LhO4;Ksny#~{xu!N8^<#$d(3V8g&*#~>*FfPtTpp|?R^Nuh!N zivrUO#t(c94r~l(7&sXO7|t+oF&Hy2F+Vt{;3zCF!obKdGlnsNgMlF+AV7&p;Ijjx zk}&%cMiw6iVIdXrktO3kXPW%iBoFWWzj64kde;D$tHUYWAlSjepr# z3~DjFQyA+F4C4*W3=GZ+C~IU%oDuNPjW12nVPIEmklQz$VTxfswO^Qz)^AGkOCH0|RdlXMB$V1B12{&h8|9SwF!x51Q;rqgta@E7F!RbQfl~J; zQ0nHD2PbU>aMC^_u=fk2I)fsEI)eg(8iO)}7K0Ll2Q!ZZC~^Nc<2WNA#%?Uae@0-D z5YHEW)-wXaY;yz{4zmjLg9=F&265gq0>V5kY{FatZ2K7)*jRZuco`&Ba?S|I312uP z@STlWh=IYDp@G4Ip@G4Xp@CrnLjwaV2Sb4;g9$?eL&GnTBnB}C4u%FcQDp{67KVuu z3=IrZ85$U5)ffyJ7AVD-#ccFykF|21W*9 oeGZ235C+B$-7^CE9v)`|q@_*I2rvW)9AIEzV3-4{3>X*~04wM;Q~&?~ literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1a4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..fb9189d5694be4abb8788c64ae8ed74a800ff690 GIT binary patch literal 1665 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXBr=7q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC%s+Oay}i?}CJhHH?M}7SU|>@aW3Xaiuwh`ZV-OU7z`)PQ(Ayxdq|m_s zMS*Ds;|D$l2R4Q?44e!C3}+a)7>pU1m>(Qea1@poVPIsK8N-;s!N3p@5TL{)@Y#Ve zT$r7qfy;+MScrvziGfLwbv~oA08=0n!xJW9mPt(dCIS-}*qAGsITab^H!wIbun06T zD4b;AG+tYZhm2X;n=h6xM| zEG+EosSGR(@(seQ41xmk4NM>S9f|}P7#xHcv!aC<83Z`^86pH282$(dG6-|<2h{K| zd}bFBWMF1s_bC!!h_VR{6%i3T5gW_X!NMSPf`vhuuZM*}z=wr_e*^P>PWhP|nE%Jk zXJ}w!V_;xqW7xo4!_dPdAg{u}Y{Dcgw}Dw+U<0!Q{{&`EVLlcH{t3*A3@MEA!V{Rq z8H`!w4JI%%%dO01pETDT zje$KtfPsfWErxdrW4(c4yrG$a!C3)ijVy^X0{*%2r71cL?1~K%JWQG&m~@!<3z+nj z{#)m;@t+ZJ6-cOLbZ2B>c%Z@{>@tT_STluzL55RY*N2l~59f4c22iSIU~uf=6qaRS z5awCIDJ=GeS(s0RL7eLjCj$qAunG@@kW3G!fWQ%k@Q)vvJ7jt|C-X3{F&Hy2Fj)F< z3Y+sVC@V-zU=m^rU=kMiz$h%v!60mr!obkan54(Rz;Ff>_Pi#H3=eybK%+Yz%w}T*Ax;xCGgo800x57}yv(I0ZQr zK<*UeTfo5I!#VeY1Dhd(K7#|BIKu=+&K^#o#2(J*4J-@{ygi)pJq8R7+A_SXiVSS0 zxrGILI2&68m>gO~m>haIFLx42}#93=8k v@31p4G6?H)FocINFm~vk5zzPWI3pk}ZF)w4Awb{&0|NuY98g8Tz`y_i$_zG^ literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableM1y4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..4a53db3c31f70812c06eaf58a832cb54a957f888 GIT binary patch literal 1668 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXA~c1q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC%s+Oay}i?}CJhHH?M}7SU|>@aW3Xaiuwh`ZV-OU7z`)PQ(Ayxdq|m_s zMS*Ds;|D$l2R4Q?44e!C3}+a)7>pU1m>(Qea1@poVPIsK8N-;s!N3p@5TL{)@Y#Ve zT$r7qfy;+MScrvziGfLwbv~oA08=0n!xJW9mPt(dCIS-}*qAGsITab^H!wIbun06T zD4b;AG+tYZhm2X;n=h6xM| zEG+EosSGR(@(seQ41xmk4NM>S9f|}P7#xHcv!aC<83Z`^86pH282$(dG6-|<2h{K| zd}bFBWMF1s_bC!!h_VR{6%i3T5gW_X!NMSPf`vhuuZM*}z=wr_e*^P>PWhP|nE%JM zGBmKUF)*;Q1v2q(U@l?kVG@v6VPH045|-P*EHAKu*@1roGp8^g3j_ZIW<`b+MtR{0 z%;F5jtnvmEn3?5S9N7Q=FOX++VCV8@VQAPef!SPNgMo>Go1c+kt+Xa11CIg&iw845 zBg20&OV3FvETEw0W!S>xz{1GDAjTyu(Zb3bz#Qeo&yc_=!XU@U!@&QCA@4gABLf46 z4+BGkf&dqTh5$nY;|)%6MivHPrWdR%0t_5~SOwXQ7#=Y(F)}eTu&^#J;^${5aASy< zXOLoOU}4}Blonw5$kf2#!^FU_iQzxPEr$OLa~b|KF^KbUFnnb4WT)~oiyUCn`@&ekD9qu)&#%nLA%B2}frXWk zK~!J{`vS%e1_q`M1_s^^9R`Li+#DJV3vL8TEnr{>U}a#CXE5wwQ25It+QGsQpvoc0 zz~jci9w5NL!=M(!JB6{{z%bs>%)sERfU-uG#2Eqq-1yQI9R_yA1_>S}%@0gEO#B5* zdP@JTbJ+OL2)GI)R5H3VGB7+)VGwqi!zrwp!oVQIDX#0o$*_lWx-tVOT{AE^_HYWz zvM>nqtl$(Dd&4ZuC&D1kb%&FIgF#q@he1fDhf_e{2t)YCkIWr1J)Dzy7}yw$85kHW zeK>{9c^H%xBqlHku>~**3w&S{7Uy6Pwn$-M=x0pQV_;x70}6Xy6Gny!3=F>*#g!Zw z(>{J=K9L~N!^u#?=)aqh;Xn^3?^ZT8?halC4hA*`z635|<^x=U>`e^v91;v{3>}<; z910+J3i2&r;P2s_d%=OtkU^ipflZuY0wZS+r%+-KXY>XZ1_s_9&iEb!h6ZgJURFg0 zw$t3gf<2s#Edopqts+bgJ)H6iJ)92m3_YCuY7-LA2ryJI32S#SG4yZ>8hbE_vdQr3 zD=_zPiUbF9@C!KgaK<|`u(K(j5ny-r@W9Lf@r-8#n9pOWKd^NU{GUFX3%0#V(?(*kpQLb|7IL# z1jN{lMflGMEE3}R!q0j}K$vZg0K;KcVg3wOVWtvRao#fm!aNmh!dwAt`xzM6Sa~>j z86;J5&Irf}UpOQ1osC(Dfx(ucfx&{Ifx(fXfnfqe0|P4uLxCrQ2}1)z!!MB}1~CQ> zh6XlKWd=zWhKUjk4GdEm8W?2N7z`O0bnY++Hq2lX=QtxE&bdcip5csuKxG(XC~GJy z6Ayzh;~jPeMh0Ph4uE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2MO*rV`Tow!`&gqz{|kR zAkN^-;L702;LPC0;LhO4;Ksny#~{xu!N8^<#$d(3V8g&*#~>*FfPtTpp|?R^Nuh!N zivrUO#t(c94r~l(7&sXO7|t+oF&Hy2F+Vt{;3zCF!obKdGlnsNgMlF+AV7&p;Iji` zxG+0I1D6kjun-G_Aj1wuLDu<<$^uM*Obkz$gjpsr>6-{lU|?geWad<4nBTzQz`!EV zz@TuFfz#wY!+UN94;dL58EFP30Ra{U7vls8MiB;Ki3BEw4kjlN5wVUP3?JAT85$-q zFtD(&v!^n!FvvFuvoZ(@$Tu*3;CCnzU|?_%V$6ybVq_5D;Ae;sU|{$oAjlxh!5>h= z!|<71M38}*f!(J_fFa5zG*m=H>_luVPX`Nw&WxgI31_2)y2L27q|2gGnZeac& zSH#f3#>T+FD$K;cfw_XAhe<$Qg@HMPNmygZF^Dh-vKuixVq#)sVrF1rU0lS^&rsmT5HHUl z#n8aQz$Yjz!19r)fx(A~fngKFe}-EO{~6{o{AXei=iy-Z$mGdT&(Of|pMizpKf_uE z4u=07495Q%jO01pETDT zje$KtfPsfWErxdrW4(c4yrG$a!C3)ijVy^X0{*%2r71cL?1~K%JWQG&m~@!<3z+nj z{#)m;@t+ZJ6-cOLbZ2B>c%Z@{>@tT_SSy7goQHvdLDz?qVGrkYWd=~{W?*pa;S`o- zVGtIW!5}R5hFO@;g+ZL_4kw5f;=I7gP|q$Pu!l4J<45KW*&fcx+zf0C#taM$mOh-q z<~$6_3KA2TgxCrggatk@3X5|v2wS8uF!VDf=`k=coMB{P5ayl3Ak1@wU0lh5G410= z<`W4LJ)8_RjQ+bB84mPt@?K_R!sMXFB(KoJ=^)S0!^y8UA@Pg=Lj{wtb_Wwf52v8<8Aeey8D4z_ z<{nOw;9w4Z0jD0$cxMK7Hsvz{?9Lt@n7JUH@r(fTc}`FcU^ycoY`=k7-f;u72mb_S zUU?-@3jYL3;k@$T&U;2cn5TtJm@9y7KLZ0BD-Q=RgQQB% z838%r3ugqrvoQ-XFxWCQFjz1&FgP+aFic=*U|{87DDY%3VQ64z_$89WAjZJK(7-0D z%pl3aFj0b`fnh2`1B0v@gCPTh&K(B9h8b+)9A^Z?IroUmGn^3+s0?EaWesIz;$dL$ uU|?|-5!UBm2oGUk?9e?Upzq;vMnGEH^o#&QfWQF;1_p*XpbCM3fdK&0)i(P8 literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..e5a1baa380202a250b364ff9eb7e10e47ffa625f GIT binary patch literal 1677 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXBr=7q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC%s+Oay}i?}CJhHH?M}7^aAojk@MUmgaAWXb@L=Fz;9=ll;Fe%uQxIUVVqmagV6bEG7iJJ(U}WfTkXKS@ z;Qyk)G=uR2AA$=6DDDnNlfx4QjF}(mCPK94C@6r7?~LY z7#tWCPBL(syk~gN&EO#;BO@ctpd=u`!r)?@Ai*fYAS{u<#L&UyBqAc#v4i0QJ0nBG z1O^5c7IyYj1{MbS24PkPK>_&&rVsoMMFI>A4nmAs(L#(20v!Ad5dsVhe*^>>ggN*F zYIqnvvx^8aFf*|G6bUdy*@T9Qh=`qtjpgZJVGugO!l2C8!@?lo!@|J7f%!kD{LBr^ z|Ko}n8rawv7+8gw_%|?DF!V49$g40gn=lE>ZD5uc*ud<-KY^K3n2&{le*&|jurQbw zQ8HixGZ^Gq9N7Q=FOX++VCV8@VQAPef!SPNgMo>Go1c+kt+Xa11CIg&iw845Bg20& zOV3FvEDZdN47?0mm>gIb85qR4q$LD6Sp%4(ocI|MI7Jxb73u~G5lw^#qghDF2jE&25}w^hL2314D}2R4F4He82&S? zW#C}=-@#z~pWzq_gK(}6gWw}J2F7AGMlJ?nkppacUl=PGg*jaK`IQ+tR zhziVLU%=SGz`)eOz`)y~!@#hGn?r+P!Hqzv1q=)UtPBkD42B&H3V&HdJ6IS3R5=70 zc-$D+0|Xd&7}R2Tr!dwV7{(i#85o=uP}azjI3wVn8(*5D!@#cCAi=|=`GHA?iNAnJ zPwBsP4jca&0at;9N=A1^28IVJ48ksRIE6J+7{YlN7#MVYI2rbEPFH3CrELZV#~w~$ zSr!Iio*4|nVsDs*`9v7Rx$bZZ^SLkxabDnLsAm@tXkrcj_>s9owuf^vHv=1kF#`jG zr4OgDIS+%fg2V(SA+`V}VSx{f!r~kZ!WJnE4E>BrdJGHfP+M$R5ip~N1}=nX6k47@#@@jV6% z4caoitcnb5r@4g%dpH|g1ehFJMVK7anB*0DI345}dN}#jCM2E_V5ndc*6v_p=;0JJ zUcw{FCc~?*z}&+r5**CIFW}U}8Sl)%&Zc}ufZf@{12Y@MGoBG(KFHCbp-Y<;G44Mq;47v4CFhKQobZJ+0^iw~g%}uY85$TY7#bKH85$TSFf=f*axfHlGMF$lFf{xU zNn#LV;9zKA6IEuAWMP;n!O*}km7#$_R*gZB;S&=BDDkdgU^yco&bdcip5csuKxG(X zC~GJy6Ayzh;~jPeMh0Ph4uE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2M<{P37H562i^q<6Kfa^7cl6wF$h+OG3fv24`XEh$iv+s#=y(K%^=R; z%;3u4%HYi4#^BE2$l%7n)5jpsE5X2~AjV+Dz+l6`V8k)gLiUP+;W|BC|C z48{+93=V7zXBapc1Q^aRa4{G&Ffl(ksNg6pFT%jcFf)cRfrEh|ARs`AN#L^sW4JIo zLj#u&gRl?_0}}(2AnSZaWdWu@CWa?W!Yq@R^i2dNFt9OKGIJ_2%x_?DU|hrL;@2-2a}VCh*-xCh7atF3=I<)7+6@? z*;5%<7~~s-Ss4TcF=j;zF)|2n@H0dRFfjZP5M&VM;18(bVff50 zBFMnZ!0uBdzz}5<8Y&_pb|N;Gr-Ow-=mZOcGG7l1gMbeU1OEo*|D5tOH!%N?Yh`F) zV`E@oWea5D-@shL(8DAkufo8b!6YoVfmvQ)1G5AF1ZGZQJ{AW43CxNNDU9;M6PU#r zj9KLkCNMM0vpBH-|6d@_=)lh9&%)5KVFI(cz6Jvm12;b-!&+%gMg|@Q1{M!yeny7> zVwRqhR9HYk&&#ld$$^EDfkBK*SfYiMH-I_HiJu{XQ-nc|k%xi*4@2H}CPoGZ4j%@F z1_c2w1`Pp*2F4ql!i;}dSvVMkS$P=58C%#GL>L6wjTjy=F)=bRGqA8OF5>5BC~#wl zmuHY-XkcOB6Ovi@?@xIXkhryz{2pK zVJ!m(!~YHji5TME- z$iU;qz#bsLz{8*x!#jns-oP;4(9FQ#tbnpcmc$tW|J?Y}6deY3#Rdr;Ce05_I!ycp zOnOTHt#jD;&j`2*BvdlGGcqtdP+<^unZqfpnZm#z!zr%o!^yCRbGkAEC~Y$^IQDP~ z%d#*C3#{N27JI`i%;&-&&UJ^AfrCLowp9N5GeCNOgLa0(^%a7J%nVPN3x;f(JwU}(^m;bm21 zU^~q%EZD=@*doB>&?>^@(8DRO(8K8<&(OokuQnm^i~vIgldyIN6GIQDps@#&D4Ptg zz5;U(r$}%x2fu(*4`;kH13R1Y83A@@4-d>N5YKoceMVsK7e;jkMFw>S1qL++Wd>9tlwD{%^){ zMnH_+ScLzKz#<`@FZ`@$1cce<2rwLG73K$(k}M43yk`W2c`De1xdPbsGcd5R@^J7n zNUG$V5s(wUa7N%e8?z7tgDpb?g9SqagCj!&!vux~238J+0#61Lh6aX)Um{5iVhkJ% z4Q!&y43aDi6D1fL7^X5bFvzMg7&0*E++h%Gn87B_aYjI#bC0+@!x;gA$}q-I)=*X^ z9tL5?JM0XM48r;x4B;URj2*gX1oS;T&Im|Lo1PJ12oN~Hz`(#T2UHs{FfafB%tkhE literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y4gbY01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..1333e260e4f0b155fde9ee891ceeccaa922d84a4 GIT binary patch literal 1673 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXA~c1q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC%s+Oay}i?}CJhHH?M}7^_V6b9fuwh`ZV-OU-!@$qT(Ayxdq|m_s zMS*Ds;|D$l2R4Q?44e!C3}+a)7>pU1m>(Qea1@poVPIsK8N-;s!N3p@5TL{)@Y#Ve zT$r7qfy;+MScru|kYNX-AnSZaWdWu@CWa?W!Yq@R^i2dNFt9OKGIJ_2%x_?DU|hrL;@2-2a}VCh*-xCh7atF3=I<) z7+6@?*;5%<7~~s-Ss4TcF=j;zF)|2n@H0dRFfjZP5M&VM;18(b zVff50BFMnZ!0uBdzz}5<8Y&_pb|N;Gr-Ow-=mZOcGG7l1gMbeU1OEo*|D5tOH!%N? zD`IG1V`E@o6=ve!z+A!5!z3WD!oY08BrLaqSzcfRvjhJGW=>%~76$$a%!0ZD|HUjl zC#kT2!k(953zGv2BLjmNm$ZZcCu;z6loLNg0;dRr93u|{{~w0DuS|>#3>-cT3=Ikb zTnril3=NDPEKExnSXdZ@nO?B62rzK`VHIRIVtB;F#K^?Vz{0w?h@YRKz>OhZomAWEOLNN?+arEqcDdHKff{~hx`E^1{PLE22p_- z>7#Ns37#MgvbQl=6aC2xdEVvOUwSa*kfR%wkp24t#LE$fpXa@^JfGUR|1CJX6 zdw>7~4})3^?-a&*1H*VjGXsOO0?Ha$5@!VbbK^@>bQstb8zgv`G(RxuF!2{K=_&oU z&SB#}Bj75KP|4`d$iVPGg+bV54yUkY3PU�|SGu4=2MO&gsewptQ}v;Ml_{EX%?m z%rk>QSnLh6FrNs6IM*FcVLlfIA*Qx zef-FLB0-{ulc9#ue>Wq;fgVoY>uhY?9efO&4D1Yi49qfog4}PI1(`oF@JleTD)2#a zp&&aCgFYWa59j;~4s3=D`V0qKH?S};@b+-V_ZToVXv^@jDl)L0 z<`x$0;cRRXU~*^`VRBGol2_>AbdYE0;pA7Fka$Lbp@KQ(@!?lS^=zc8vZC^Bd;C^D!qC^Kj=C^2|2^GJZw_kS~vGXi4l z#v=S@1QrSLeBoz3BOuH+M}Xllt1y2Ct1wdut2pl&0b!mNHes#+w*3qYY^*#SybO{m zIcEgqgfE;C_|C>G#K2(7(7<59(7@ox(7-T(p@D&wgQ38a!GxiKq2ZTE5`!262SWp! zs4{~j3&TVSh6aYI3=IsjY7B-93_5oh1RG|siF2G05a-+@F3)gAK%g>=F_blwm5GNz wnDGuf10#d5J_kd12m@n>?im4n505hf($c191Q-GY4lpn5+7!uXQF2sA7-Ryz`)2LQ20QGnZbvJfrX*JASb6F zKEJfYl7TgzsX@Ylfsw)Cznr}l0|PGu0|O%i1H%&r1_llW28J#M1_mw$1_nh21_lWR z1_l-e1_luZ1_ssu1_5y{76v6oh8Tu$D+UGzSrrCh&JYG+ZUqKm4ju+!1__2>aRvqk zQ4R)SX$gjK1qKENHWmh9W(fviHWLPMCI<$F00v>c4Ga=&E{r7%3=D>b%p4yW92giF z8n_sQg@aV6b9fuwh`ZWAGPd5MW?r=x>l$QfT1+qQEqR@dF=& z0~^B`22KV6hBFLY48{yh%nuGKI10;)FfcOAjA2aRU|wB@CVfJFnneg5oBOy zVD~8!V2H8_4HXd)^N5Y*>0n_H@?c?5=Idc$5b$AP;NQUfpHqJ32Il{9MGOsWYzz#n z!c6=dm@621m;~fi7??Adgyl9ciwbODmS^0+Y{ox^1d=LGB9xXFfcSI2yiiI z2rx7-day7pVGw8HU=U{&U|?xsV-R5wWEWw0#KgqN#LU3Ly10m+pP|5wAzq$AilKpp zflp9cfaN1o1A`9}1H&eU{|vVn{xi&F_|L>3&cng*k;#*xo}q!^KLZQHe}=UT91Qxfj9AjY+&edTMe8k4USj@)A#ULzlfKBfUV+EryhYLTyG9!ol0UibxRz?O`3=!0zJDea|i1Pv`Lp{5IKoe{D$B)b$vOS!Wxf$3Pj2RdhEPXhI&3PD< z6(lAw39%J02n&2*6c*=T5VlBRVCZK|(qmv?IK#-oAj~_5L73+VySS1AW7@}$%pM66 zJ)8_RjQ+bB84mPt@@{5hdpMOgu-szi=;4g-F<@ZOmf>YpWMDhZ zEiBl>+1Mh$|p$}53V z`6o~+=amO1aRqo1*JNb)!l=xk$)L`l%b>)d&Y;Yo!{EWpBLPb2|IIkg2#B#8i}0Tj zSR};rg`f3|fG}GUE5l({VSZ4#$-*Gc+r%o&)50dq6~MNinVF51hl7_vQYGh%fSmA! zGXme)n1vV^Y#ACDEEpOX92puICNMNGuyQaIcrutUG%z&$5=mkZW8h$DU=vklkYr() zD8bOcFqNT!K~{}Hkl_;(11JfvVPH8UAkMi*T%O^KfIwv!V<>AVD-#ccFykF|21W*9 oeGZ235C%pL-7^CE9v)`|q@_*I2rvW)9AIEzV3-4{9~c-I0O0^C`~Uy| literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbX03/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..f9f325f511b266ebfd0a2a631b63e20fb887acac GIT binary patch literal 1672 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXA~c1q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhs1a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC$gwCW66%cR|9$8b-qf3_5KLf)!#6`v3XE7@0rvaC3+;@G@{S zh%-1dxH7mhI5W60xHC91xH0hbG05{uFt90zF<3D$*f22IF$ju3VBlwD=xvZ!QfT1+ zqQEqR@dF=&0~^B`22KV6hBFLY48{yh%nuGKI10;)FfcOAjA2aRU|70T z76$nSVO9n~0r>`|5Bv^A0t^feLX26_LW~Ro9Q+Is0t^g)1Oyp`Irsx=co;sjiwH6> zGqC#<2{1(2gocWUhCQQO|8<<4}HZaRGZeTX!pTNv1%*VpOKY>}1A%#(1cmlIH zgE6bT!31Vzc@_uu|Njf*86DWU{8<uWGDF>v!UGOU%>WMtq`U|{iJ=4WL1 zFJ|dENreRz@VpFLm>gIb85qR4ge6*7c>|cEocI|MI7Jxb7n51}TOH z76v{+X#tjxObrY^ObiU082&TdV))N6m*GDXgE$Wd!$&4hhI)nuhW`vK4F4I{GH@{b z?_e;VD{JPc|vyi*wK4GiNA%?u3A3Mgx2Nt_Yz&y6ol(P3a$Y>?n#()_@r!^B^}q^I=X zI){z_jDV{^LM5X+BLl+&6$W9KIh?|pDGUr#8O3#dI2rbEPFH3CC29r+#~w~$Sr!Ii zo)w(JVsDs*`9v7Rx$bZ>a4-m~@GuC;^l%CY9AOCm_>q}IriXJf4+9&6F#`jGr4OgD zIS+%fg2V(SA+`V}VSx{f!r~kZ!WJnE4E>BrdJGHtKoL86C~p@z|aHzUJ=9!}n^Y;4>dybK%+Yz%w}T*Ax;xCGgo800x57}yv(I0ZQr zK<*UeTfo5I!#VeY1Dhd(K7#|BIKu=+&K^#o#2!wi4J@~qIeIwbdkh#Dv}Jf%6&cu0 za|;Xha5lCGFgdh}Fgf&a$}9A6I>I{ku>I@1DY7EK@S`11I9?U!vpyd7EjN^;|!wG(Q zg);&xgm}L2vz`$UW}73xaF|t?KZ8}6sf1OSSB62D-GV`wV*(pP0NZ|MW;RwH4qgUH zm7FsIa>5tR2z+N_7GhwqWoTfqU}#`)WN2WRz|g?J%E3_J$za0Jz|inZB#A+cfrFue zO;njdl7(TS1VaPERE7oySv3Yj1_qrw41x_a*u*)`2#9m;5tnB;BOp*2#u&;P%F4vU xAk27&oq>@-Sf7I-JcNOfL-&k;zK6#d0cmN|GXe|&0tXlv7#QY&>H`J_1^`k5F^K>G literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1y8gbY01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..bf1c6310ee3160d1db9799a983827b9394a73ce7 GIT binary patch literal 1683 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXA~c1q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@>9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aWrrGtTmhe3$5hC$gwCW66%cR|9$8b-qf3_5KLf)!#6`v3XE7@0rvaC1m7@H22T zh%`ihzhtf@SkL0 zHhItRo}0l_Mn*=)nn6f_g~7!*L4r|)L0BSziJ^nZNkl}9V+X?rc1DJV2@DJ@EbQ#5 z3@i-t4Z^Gpf&%glOdt3iiUb%K9E2FNqJS6X zrRO9S7EtK(GHhXTU}0on5aW`T5a47DV2*O)XGq`_VUT0wVc`G6koT2|k%583hk>C% zL4b=vLx7=y(SwC)2?GlYgE$ipn>6DeRzY?VhDS_Hj7-c7EUb%*`1u(M+!*5J8Kf8* zSQz*Or3F|%GBq&xFflM}V))N+i{U@RT!#Nl4B|W-3?G?18R{7t82&S`F#Km&%fP|# zzk|W}Kf^H=2H{*C2Ej*c42;EWj9d)DA_v&?zA#oW3Uj#d^D8rQ$RFTgU}0rs5EYog zK7o;gfq{vGfq^%iA>u%6EFX^s!+{%tQVSRu0$3RsIv7|O1Qq_Wh<30r1gLTdGVr)D zum=b*@Gz*w@J?Z@H!zGhG&3+bE1;~AC2>Z;KR3QKMTdc1u|a}|N%I4f4ikR?lb+Il z>l`-zGXkyx36+fQj0_A9R2YO^=5PvYrZ6x}Wfa%-;bhpuIbE3nl(rcd9D6v0Wmy=6 zd1f#Oi@jkM<`ZEM=eolw%;&-&#Cd^}p`KkpU=L^b$B)b$vOS!Wxf$3Pj2RdhEPXhI z&3PDv6}ECHaj*q22@8B+6c*=T5VlBRVCZK|(qmv?IK#-oAj~_5fnfpz!!Jg0B?rc| zj~|&m5+r&!8EP2)cQY~^=;7qO&c?>g!NzXSuT0v{w7 z3bOMs=<_l3aL&Krz-Gvx&)~o&&M<+IvxieCv4>M>1IsODjvmhV9s>pjZ5duxMFzIh z+`@uAoQ*94Ob)FgOb%*H@(Mki4)P2=ocwAN63+-QR4@r^cQ7&Za0(iqVH9OMBcQLq z+`}mn9L&Kl;MBtz@65o?rhG<#-PywfGb_Y1o)KU^&k4!~EN29S?Kd#XIwI0Pue=f{ znSTN$b6$CH8dm_P@iPKjSr{3^qGiWg=F?cZZNPrUge>09V0t_ek zg@7?l1^8%wQAeI3pm=xkp@{;f#PlWf)^9YbYxd y4}&n{9d-sr24Q^;hVT#uMh@LG0{R{vX9T3BP0t801PB~pU|?XF1F9Mr7#INWG%~3G literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS1z4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..aeb4ebf67823017c77b512a455c9ce29de4594c3 GIT binary patch literal 1667 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXBr=7q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhv2a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2M<{P37H562i^q<6Kfa^7cl6wF$h+OG3fv24`XEh$iv+s#=y(K%^=R; z%;3u4%HYi4#^BE2$l%7n)5jpsE5X2~AjV+Dz+l6`V8k)gLiUP+;W|BC|C z48{+93=V7zXBapc1Q^aRa4{G&Ffl(ksNg6pFT%jcFf)cRfrEh|ARs`AN#L^sW4JIo zLj#u&gRl?_0}}(2AnSZaWdWu@CWa?W!Yq@R^i2dNFt9OKGIJ_2%x_?DU|hrL;@2-2a}VCh*-xCh7atF3=I<)7+6@? z*;5%<7~~s-Ss4TcF=j;zF)|2n@H0dRFfjZP5M&VM;18(bVff50 zBFMnZ!0uBdzz}5<8Y&_pb|N;Gr-Ow-=mZOcGG7l1gMbeU1OEo*|D5tOH!%N?o6pd| z#>T+F%EqvPxrU*KNkCqOfjNUoSZ)Keyub!#2mT4noWgu84Ez(A6&X?(<%K6Oi!&Ir z${S2zW|n7hVE_NWK%UWooy(tvp<%-WW^;WF1||k>eny71(wdA6JPHgf9?blV4FAO} zJtwKKfC8SEVGEN33nK%A7?-d_3oCB`bCeT5LjtD=gB&9d1OFd}yzfkm3=AAT3=9nl z0$dCl0t^j|H#mhE|FE)fFbK2qFo-j@urY`*2(lY7JYr&EWMXDuVO?Cr&(Bcc#t<*h zAjQzY!oVjeEx_`Tse!?ViGg7g!+(Zb4F4JCGW=&^5a;1w_{ikRP|wi7@SlN&;XlJ# z1`dY*9Sp|*8IG|q2S@iu<@S}a1}_XWOQd_V0fUyAnY=SQ&=;FfkB2-T-S$_VGrkYWd=~nW?*pa;S`o- zVGtHr!6_{EhFO@;g+ZL_4krT#gRlw@gOE%Qr+~l_hVYLcnLA{9I4AQkurU}jFfds9 za0;9AFeocXOkfgXD_{^7_`oPE&cPsTk;1^x&zPjgz`$^Zk%d8+*Mw1+=LoyFk^^Jf z$B)b>5+r&!8EP2)cQY~^=;7qu%Erds!OOtGz{bFrz$MIlfJ>0Qi9w!2f`N^pgHw=0 z0pvr~0 znp;?~hqJLofXSg%gvp_YQ(mEm(?Oo0hm&7zLgE<#h6*NO?G7e}9!^1H4<=DI8D4z_ z<{nOw;9w4Z0jD0$cxMK7Hsvz{?9Lt@m>D2ms9^)MJSg$AoDmSV-@q*IxPjS&e*!bF zyb>sNe*&d$UU_iRRsbjMGXi_RFsd^sGN>~sFsLyoGiWg=F?cZZNPrUee>09V0%GjO zBK&6r776iu;b%P~Aj~#LfZ;H!Fh8h>WML5JJtH8@Q^6+86~MNifq{*chl7_vQYGh% zfSmA!GXme)n1vV^Y#ACDEEpOX92puICNMNGuyQaIcrutUG%z&$5=mkZW8h$DU=vkl zkYr()D8bOcFqNT!K~{~ykbyzx4ufFB3^s9&GXmnAd&K1#&IkxphB1b+hO#p8FbFf= uVP{}u5Z32l2oGUk?9e?Upzq;vMnGEH^o#&QfWQF;1_p*XpsIj@fdK%c|25M9 literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb01/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..a89f97ab08b232a1ba18ac5888951c52e82627a3 GIT binary patch literal 1666 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)RXBZ!5q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2MO*rV`Tow#oeLAz{eoK zAkE;+;K|_1;Kbn0;K|_5;I@Imo`FF?f`LsziNT72!G?jsj=^7=L5YEpp}#?1Nuh!N zivrUO#t(c94r~l(7&sXO7|t+oF&Hy2F+Vt{;3zCF!obKdGlp>k2LnSuKmY>+!-CHa zj7q}nOBh*v7=(pb7z7!1FbcBHXH*to3S?q zfq{jEojsL-g+abSn3X|LK)!+L1HVI&00V=A5Mx%f5F>*C2R}oE00YAx0YL^~4*q}| z9){2CB7zLe4D3Ed0t`_$p`l`8Vkcr_c{*4agif$9DD(BOFbMdtFz|0+{?92ta|84L zxFUuIHZ}$ZR$(Uo4a^k`Jxl`fDh$jSOu}*-nB@gFFgx&1VCEF&V`1Q*z^o`N45met z44A+S26+|-_W%D29xS z6a=^!Gz1tL7(G~+mN1AjaWDw8@-T=qwy-gXFbJ|6F+5^oVq{`wU}0Tc#Lv%A;KmRy z&mhInz{0>MC@sM9k*R^fhlzn<6T^RoTMYjh<}&7QJBMppI@1gL;e5{0}Cr7 zgQ&m^_63X`3=B*i3=F&-It&b3xH&W!oNfe4E#P7h>|kL~QxM_-Wvl>I4nYPUHwN|q z0R|ohwHV$hjP(YF@rGsw24@A7HL@hm2>9p5m!{}2uq!l3*fUx(d|=XH;xAy*Q~Gb6 z!^VF`z*QijlF^-!f#HD)gRsjSPGPMShHxGR1_oUpPKG_4)0G)ONt=Pev4>MwmW4rB zUaYXX-s69c;kGs70G z28Ico`l1XyobxX@uo*JwGdQq`GfZIQ?BNtj?BR^wz{0@5+rt^(W5B?mEyK&I$iSw| zC@k2++1Mh$J&^;rd@8NMqKw8@Li~vi3K*JnRO~Amw001yyGo}Cl literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS4gb03/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..350eb99deeb88f66bb30549ac0c5ef47beb1a809 GIT binary patch literal 1666 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)RXBZ!5q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2MO*rV`Tow!`&gqz{|kR zAkN^-;L702;LPC0;LhO4;Ksny#~{xu!N8^<#$d(3V8g&*#~>*FfPtTpp|?R^Nuh!N zivrUO#t(c94r~l(7&sXO7|t+oF&Hy2F+Vt{;3zCF!obKdGlnsNgMlF+AV7&p;Ijjx zk}&%cMiw6iVIdXrktO3kXPW%iBoFWWzj64kde;D$tHUYWAlSjepr# z3~DjFQyA+F4C4*W3=GZ+C~IU%oDuNPjW12nVPIEikg#X8Wca|O!^B^}q^I=XI){z_ zjDV{^LM5X+BLl+&6$W9KIh?|pDGcE}3=9mqKAa4DIHxN!fKoOCgJTb;uq+FMu)quk zVX-&N!h9|a;#_w)L9`I(1x|)~b^(DsoZ%loGIz-Ka8BlCU}G?5U|_KH;S@IKVNh0( zn7|~&R=^-E@PScSoP$BwB87pWpD{^~fq~%+BMXBt?;HkUo+IqyN)C)^A3rjmNRa5^ zWT;{E-_6Kypof$9G8-Fr2QLE$0~-S$16v29F!KQ}LG~sFc@7B%HiiyPK@J6wI|ca` zF!1+q&b{EkX2_t=;J_x%FoBV?hf^rAhckKu3j+gh4`+Oj0Rw}!3@@u91KVkCVZk2G z#ufo4hgK0L2Q?;ng&s}^d4?WNezggSX9O53n1r=Em>7CE1&z-zin7V@>MJn!aEb&6 zbMOl|^>D^JGq5u#pAlep_VB>W0`ZJz1enirf|5VW83AGY4b1Y68<;)#CouEMD}j>t zCs6X{l?SJ71#sFvBe3@iqdJ2kgF1r(gBpV}gBF7lg9kH@1Soa?H{&=XAjWPi!hc3! zkr2-pe%3Pr!fbN{7!I=v^MguB76x(NGXlaqEo{PE0c`sj7}!{OICvQ(RdUV<$O&IK zBk-M#S%`tbmZ5>cf}w%Ik)eTM0z(4>D+fb?CxZz?14F|vkt7B&1`dV>Hc@2;Nfw5Q z5)2ItQyCfE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVZIFv5^OGvB@7G< zhK9@?9~c}M7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk0z1Ak4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2MO*rV`Tow!`&glz|X+V zAkN^y;KJa_;KJa};LhO4;Ksn4#30Wr!N8^(vhk>7wp|?R^Nuh!N zivrUO#t(c94r~l(7&sXO7|t+oF&Hy2F+Vt{;3zCF!obKdGlnsNgMlF+AV7&p;Iji` zxG+0I1D6kjun-G_Aj1wuLDu<<$^uM*Obkz$gjpsr>6-{lU|?geWad<4nBTzQz`!EV zz@TuFfz#wY!+UN94;dL58EFP30Ra{U7vls8MiB;Ki3BEw4kjlN5wVUP3?JAT85$-q zFtD(&v!^n!FvvFuvoZ(@$Tu*3;CCnzU|?_%V$6ybVq_5D;Ae;sU|{$oAjlxh!5>h= z!|<71M38}*f!(J_fFa5zG*m=H>_luVPX`Nw&WxgI31_2)y2L27q|2gGnZeac& zSH#f3#>T+FD$K;cfw_XAhe<$Qg@HMPNmygZF^Dh-vKuixVq#)sVrF1rU0lS^&rsmT z5HHUl#n8aQz$Yjz!19r)fx(A~fngKFe}-EO{~6{o{AXei=iy-Z$mGdT&(Of|pMizp zKf_uE4u=07495Q%jO01pET zDTje$KtfPsfWErxdrW4(c4yrG$a!C3)ijVy^X0{*%2r71cL?1~K%JWQG&m~@!< z3z+nj{#)m;@t+ZJ6-cOLbZ2B>c%Z@{>@tT_STltooQHvdLDz?qVGrkYWd=|RXJByb z;S`o-VGtIW!5}R5hFO@;g+ZL_4kw5f;=I7gP|q$Pu!l4J<45KW*&fcx+zf0C#taM$ zmOh-q<~$6-3R^jpIM@mpgatk@3X5|v2wS8uF!VDf=`k=coMB{P5ayl3Ak1@wU0lh5 zG410=<`W4LJ)8_RjQ+bB84mPt@?K|S>DgrR|<;g?7fgBSw` zLj#+rGJ_-w!$b*&28O8&4Ggks42BF0I(HZZ8)mSHbDR+n=iDPM&u~USpfZdxlr@x< ziHAX$@eVr!BZII$2Sa!W17nBo83BC{k23<&(xztw7y<+iFfcGM%mLL43=9kav_3Z` literal 0 HcmV?d00001 diff --git a/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin b/fusee/program/mtc_tables/combined/T210b01SdevEmcDvfsTableS8gb03/table.bin new file mode 100644 index 0000000000000000000000000000000000000000..bd379aa69902f40e68be9ad20688d8ea02e430ce GIT binary patch literal 1694 zcmew_!OXzGU|<+;WME=oU=Z(@@0^w%mReMtnV%OQW}s)HXA~c1q-Vgu$iPE(Qh$ zE(Qh$MFs{22?hoR76t|e5e5bZ)&K?paV{1HB}RrAhHxte1_oIb24T(+24QXm24M~! z24MyXhG2091_n_M24QIlhHwQ21_m}324Q9i24OZ625}|_28I9zVLllKjx7ufCJe!b zhRhs1a~K>L7#JG37=(phFoZ}kFffRHVPH;V5Iz{dAk5*wAk4+Vz#_mX%yfi7*qVhw zn3aV=nB@fn2M<`khfD;61Mh-_i8YLd3mA0T7z8WC81(=1hcPmL5P>0^-Rm0(~~5M!`nV6b6euwxJuf55=c$k5v$ucXkx|3!gm z2IB`l1_w5VGYp&z0t{yuxEPEXn3x|NRB#lQ7hzyzm>I*Ez`?)}5D=imB=FgRQAwD6 z2_uUSgRl?_0}}(2AnSZaWdWu@CWa?W!Yq@R^i2dNFt9OKGV>`ihzhtf@SkL0HhItR zo}0l_Mn*=)nn6f_g~7!*L4r|)L0BSziJ^nZNkl}9V+X?rc1DJV2@DJ@EbQ#53@i-t z4Z^Gpf&%glOdt3iiUb%K9E2FNqJybNRC{G;DBSH`f+8`Byfr_$T9LT@c&`R`_9D3z`)_d zz|f!|z{Q{;z|g>WgHxFC4=W1?gE*@I14|1Vg9w8ly9mQ0CMHHEW(F44#YO!53W2)M9w2FxDFw#v7U$7@QSQ*2t1LBjBGKUz(!Bz^>RJ!Na8afk}sn zzko?k>A!Uj8~+&rSAm2|Mt4RAh6gGP!Y*?-g*8(c7^X6c>-umq?BSfQ%m7N=3=EDv zoWim!48j5{IEBUDFbng!Fo<*A;bh=o5LV$~5R&QP6c9MV5dQHaGlxtM=VTrRHU?t` z1_nzXPGNH%24w|_2~0w41q{Lh9~gzjIT(a3QWzNe8I$xF7#PklvM>nqnlK9U9AOt% za$rpR_>tKoL86C~p@z|aHzUJ=9!}n^Y;4>dybK%+Yz%w}T*Ax;xCGgo800x57}yv( zI0ZQrK&}+zTfo5I!#VeY1Dhd(K7#|BIKu=+&K^#o#2!wi4J@~qO#=cJ^l--a7%(ts z%kZ))GO(TI78dN`Y-|x=a%dG{a_HfdSLoq%kZ0)O>sOSU*tPF!Ny9I+V z#{@Qp0Ji0|!F`o2W8_Bn!ht35EuSsSFJavT6*53=BGV7z7(;u!(b=5fJCx zBQDQyMnIr4j4_lol$D8xL74FlI|Czwus#PvcnAX{hwd2xeGiW_0@Bi^X9O4m1P(AT NFfhyk)e;O03;_0_GzI_w literal 0 HcmV?d00001 From cc4531e3bf847e4f8055f20b9987222a5a979b09 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 9 May 2025 12:02:17 -0700 Subject: [PATCH 215/238] git subrepo push emummc subrepo: subdir: "emummc" merged: "7522f1f60" upstream: origin: "https://github.com/m4xw/emummc" branch: "develop" commit: "7522f1f60" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- emummc/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index abdce15be..69247ebe9 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = d248ea6f700c3e6987549e30a1e2eeb609ce9f8c - parent = 9112461620330ba73a74926edd4c08b3cc0310f0 + commit = 7522f1f6054a71bdff5beadee0302cead1235be3 + parent = 0e2ef545f947d24c6add254874ab493ba84bbdc9 method = merge cmdver = 0.4.1 From 4d4f0ba96876d20e505c7aa11c9bf215f276dd8b Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 9 May 2025 12:05:01 -0700 Subject: [PATCH 216/238] svc: bump supported kernel version --- libraries/libvapours/include/vapours/svc/svc_version.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/libvapours/include/vapours/svc/svc_version.hpp b/libraries/libvapours/include/vapours/svc/svc_version.hpp index 8c9033ab0..4ea900fb7 100644 --- a/libraries/libvapours/include/vapours/svc/svc_version.hpp +++ b/libraries/libvapours/include/vapours/svc/svc_version.hpp @@ -57,8 +57,8 @@ namespace ams::svc { /* This is the highest SVC version supported by Atmosphere, to be updated on new kernel releases. */ /* NOTE: Official kernel versions have SVC major = SDK major + 4, SVC minor = SDK minor. */ - constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(19); - constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 3); + constexpr inline u32 SupportedKernelMajorVersion = ConvertToSvcMajorVersion(20); + constexpr inline u32 SupportedKernelMinorVersion = ConvertToSvcMinorVersion( 5); constexpr inline u32 SupportedKernelVersion = EncodeKernelVersion(SupportedKernelMajorVersion, SupportedKernelMinorVersion); From 1d3f3c6e56b994b544fc8cd330c400205d166159 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 9 May 2025 12:11:13 -0700 Subject: [PATCH 217/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "9e8cbe3fa" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "9e8cbe3fa" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 67a54d63c..a2f582fa0 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 989fb7be0c68bf229fe6789428b6c448b6de142a - parent = be19749841e581de4cc5d38f39f4de5fa4046c52 + commit = 9e8cbe3faa4604e9ae162546d13a74755ce30667 + parent = 4d4f0ba96876d20e505c7aa11c9bf215f276dd8b method = merge cmdver = 0.4.1 From 6da88f8f3ec5a719d8b6f171502b4e7f67710db7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 27 May 2025 22:24:41 -0700 Subject: [PATCH 218/238] docs: add banner to readme --- README.md | 1 + img/np++.png | Bin 0 -> 2254 bytes 2 files changed, 1 insertion(+) create mode 100644 img/np++.png diff --git a/README.md b/README.md index e17945104..aee0ff97d 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ ![License](https://img.shields.io/badge/License-GPLv2-blue.svg) [![Chat on Discord](https://img.shields.io/badge/Discord-5865f2?logo=discord&logoColor=white)](https://discordapp.com/invite/ZdqEhed) +![Made with Notepad++](img/np++.png?raw=true) Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. diff --git a/img/np++.png b/img/np++.png new file mode 100644 index 0000000000000000000000000000000000000000..bcbc6b58d28c460215750c1b1e1024ee132197fb GIT binary patch literal 2254 zcmeAS@N?(olHy`uVBq!ia0y~yV2EH~V36lvV_;xNKEd^Xfq{Xuz$3Dlfr0M`2s2LA z=96Y%;7IdyaSX|5d^@u`;L3H;Kt|Pz1nfk!l`D>H4P83rTY{*1Trs%uHM9WQ(XIR z^E>{soA)>UxOTEU?fLiJ&*xRY-+BN3&$+hG|Luv2ii-Ln*w1s%|5n3u$+)<T6@p?Q(PG{#DHSs!&${Rdiyl5=-Ts35qp)wAi;s`KE=b1qKE#npd;_soYW3 z<2!?b+ZSGJh*^|SFlSavVkdvOy1%B2ZN%!UOdB#kr!~fGzN+-)^irdHbM2;n`7(1& z++L~2{|~pxvUBknq@EI)G}ZHT_4%$)cd3IPq%@+h#oFG2AJ! zYt{X$mPg+mRq*<7?QL}B>$UL)B_4AWCVQtkNMDTmVNiarCh6+Nl(aOis&4W0&(r5T zJ#ysOgw-cqtG{Td`^`(aelAwVuBfHCoqyt_S*ISUcFW53Y(CiEwB~oC-}2q>H!flc zpEBJz?~cWS-hkg%{kFttDeov3km_xlFhL;g%$$SP!s5~H$9l(uxQa@PCh=hOqWR)-oMH+F=d=!@+sBF`^=r}ozKfYfAcMMo1{I- z_F}mx(~&3Zo)xe+K1g2PH);NS{|pZeu2z|?QM?vHFMYzQXNudoxVa=5&1R6Xxqk23 z{T=7-SQh^{n4s{!do2qa%c2RVKYn|)XF$o#>Obwy1RKKACYW$0*Tg zw(PUQ=b>eH{EsPKd%kC$`s;GmCidU|mZ-ln%zAX}*yhw*@jI*DN?q`}@XUAiiF4=J z92Q>+2&w6+tNm?Nu}Ri#aq=#<+&DQ=(bk}qDjFIxGyA6$i=SIO;k2#MmcOs>U#+hG zow!h&|G??GS=&DB-f41s4NFP?gE#L!zd3vFWc{mGA3nc5xyZFUVqcOa!$QS{HPNe- zRWu|DcoZciCFf{bA2vU}UyxV*>C>kgB3z3WFP>@p+B|0E-b1HEwdHR;n=f`lew~2Q ztlY2~l^~HzVu#vJ8A|oa{Q9N9@c!(KbJ_W7kJkrnOgPB&=kMRfzK=UMZEK4A_fPg8 z!|nF&h0c#U-pV(}tzW)j!-OkSt{mU~TAiUWLB4Z}!+o)w7-f}h)^|g^y8J~M1#YT0 z)z|Esz35T!pQ>NgvWJ))YHMx7SARY6r0CV_*Nn$4-puh{|2s!lZSu#R_Buiwd|z^{ z%ik+b6q^2vDe7&Y2lXw+Ry`Iz~p$biS7(zgYX~ z!k<2euVeG3LIr;v~7O$mAPPcCJmm2#kx9BWtckx<$R;%QT zKTmSSEr+l*5smv##haKgOqu&v{O8Y~J+=0oA0w4F&d7~fyXtwwz04xhoiV$YrQiMa z_07%A?UlvPg7R0SAO9vR`|PF8$MS2NPrv=OZWG&cE?=GLWvcJJ7?sq-IljGCYgWtH z5*gi@*EDnW@eO;Q3mR=UvaJ1OQvCe9vX#}X#*EmNeP6zm{E44n{A#;BtApBf0aJs9 z6;l^W*yS-~U;b{G`N*ZKtBa$X=lOX{d0{E3TL&c!JEopJ_hi>4!QJ0W&at;1uG|oB zE?IZNz$7wbOJtyziqDV3=R1766!f*{@2&nUX{I!9dYj6k0Id}(*CoEcR}*k(&)m$l z{3kj83Llo3|5Iyr{r3Kzo077JnvCUCE|!P;bgX^cse7)t`{}K9Hus-4?!G%aKPu|< zy&qHRzIgXI>~=l=vWcrt_LsWY;;9WE;`V%5{cn#|r9>bzvkR~6zta+aZ(nzZRc{Gy zl4psn)QHvHd-R@&;ZE5_@g}#bH(yLsR`59aW6i{#+IkiSUN-K1bw(*gozaJN(xlyH z_ln<_^SSqBuZXz#fXL>VPny}+h=UDHBHj1 zv*mVg*rE2;OUg^sSy|bwR3&WmtB>|^&)s|G=hwaSi*8rO`9E=5`6u;o``o-+!4k7{ z?&Rg1^{Dzfq3Chn#P!8q77H~K!+z;3^PT{n2V*bbD-Qpwv8J3+=O%DBY&7FaP ifiE?}GtJkRL5qQbfr9}8E(K2pF+5%UT-G@yGywql=2cYy literal 0 HcmV?d00001 From 69cc653e7fceff902da1cb46d41473d4640cd1b0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 10:32:26 -0700 Subject: [PATCH 219/238] Add version enums for 20.1.0 --- .../libstratosphere/include/stratosphere/hos/hos_types.hpp | 1 + libraries/libvapours/include/vapours/ams/ams_api_version.h | 4 ++-- .../libvapours/include/vapours/ams/ams_target_firmware.h | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 66be2b66a..55828b5f6 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -89,6 +89,7 @@ namespace ams::hos { Version_19_0_1 = ::ams::TargetFirmware_19_0_1, Version_20_0_0 = ::ams::TargetFirmware_20_0_0, Version_20_0_1 = ::ams::TargetFirmware_20_0_1, + Version_20_1_0 = ::ams::TargetFirmware_20_1_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index dbd4a2cfe..aa16aa0e2 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -17,10 +17,10 @@ #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #define ATMOSPHERE_RELEASE_VERSION_MINOR 9 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 0 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 755fc6387..5afcdc79c 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -87,8 +87,9 @@ #define ATMOSPHERE_TARGET_FIRMWARE_19_0_1 ATMOSPHERE_TARGET_FIRMWARE(19, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_20_0_0 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_20_0_1 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 1) +#define ATMOSPHERE_TARGET_FIRMWARE_20_1_0 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_0_1 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_1_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -168,6 +169,7 @@ namespace ams { TargetFirmware_19_0_1 = ATMOSPHERE_TARGET_FIRMWARE_19_0_1, TargetFirmware_20_0_0 = ATMOSPHERE_TARGET_FIRMWARE_20_0_0, TargetFirmware_20_0_1 = ATMOSPHERE_TARGET_FIRMWARE_20_0_1, + TargetFirmware_20_1_0 = ATMOSPHERE_TARGET_FIRMWARE_20_1_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From f646d9c8f9d955b6f9323225beeeadd11eaeb788 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 10:44:31 -0700 Subject: [PATCH 220/238] kern: use KLightLock for KCoreBarrierInterruptHandler --- libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp index 657af7f52..401a4d4d7 100644 --- a/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp +++ b/libraries/libmesosphere/source/arch/arm64/kern_cpu.cpp @@ -112,7 +112,7 @@ namespace ams::kern::arch::arm64::cpu { class KCoreBarrierInterruptHandler : public KInterruptHandler { private: util::Atomic m_target_cores; - KSpinLock m_lock; + KLightLock m_lock; public: constexpr KCoreBarrierInterruptHandler() : KInterruptHandler(), m_target_cores(0), m_lock() { /* ... */ } @@ -123,11 +123,8 @@ namespace ams::kern::arch::arm64::cpu { } void SynchronizeCores(u64 core_mask) { - /* Disable dispatch while we synchronize. */ - KScopedDisableDispatch dd; - /* Acquire exclusive access to ourselves. */ - KScopedSpinLock lk(m_lock); + KScopedLightLock lk(m_lock); /* If necessary, force synchronization with other cores. */ if (const u64 other_cores_mask = core_mask & ~(1ul << GetCurrentCoreId()); other_cores_mask != 0) { From 3fbc59cce165cf3532217e59dbeb2de69cf47abd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 10:48:42 -0700 Subject: [PATCH 221/238] kern: wait 100us after synchronizing cores before saving interrupt state on sleep --- .../source/board/nintendo/nx/kern_k_sleep_manager.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp index 5e5983c86..59e7770ea 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_sleep_manager.cpp @@ -524,6 +524,14 @@ namespace ams::kern::board::nintendo::nx { /* Ensure that all cores get to this point before continuing. */ cpu::SynchronizeAllCores(); + /* Wait 100us before continuing. */ + { + const s64 timeout = KHardwareTimer::GetTick() + ams::svc::Tick(TimeSpan::FromMicroSeconds(100)); + while (KHardwareTimer::GetTick() < timeout) { + __asm__ __volatile__("" ::: "memory"); + } + } + /* Save the interrupt manager's state. */ Kernel::GetInterruptManager().Save(core_id); From 801438953d2d1b8edf93cf3d34fe4a7cda0dd274 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 10:54:52 -0700 Subject: [PATCH 222/238] kern: save/restore spendsgir in KInterruptController::Save/RestoreCoreLocal --- .../arch/arm/kern_generic_interrupt_controller.hpp | 1 + .../arch/arm/kern_generic_interrupt_controller.inc | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp index 63e245659..a3c28eaa9 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp @@ -116,6 +116,7 @@ namespace ams::kern::arch::arm { u32 ipriorityr[NumLocalInterrupts / 4]; u32 itargetsr[NumLocalInterrupts / 4]; u32 icfgr[NumLocalInterrupts / 16]; + u32 spendsgir[4]; }; struct GlobalState { diff --git a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc index ef363c0cf..9fa5ffb38 100644 --- a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc +++ b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc @@ -113,6 +113,12 @@ namespace ams::kern::arch::arm { constexpr size_t Offset = 0; state->icfgr[i] = m_gicd->icfgr[i + Offset]; } + + /* Save spendsgir. */ + static_assert(util::size(state->spendsgir) == util::size(m_gicd->spendsgir)); + for (size_t i = 0; i < util::size(state->spendsgir); ++i) { + state->spendsgir[i] = m_gicd->spendsgir[i]; + } } void KInterruptController::SaveGlobal(GlobalState *state) const { @@ -168,6 +174,12 @@ namespace ams::kern::arch::arm { m_gicd->icenabler[i + Offset] = 0xFFFFFFFF; m_gicd->isenabler[i + Offset] = state->isenabler[i]; } + + /* Restore spendsgir. */ + static_assert(util::size(state->spendsgir) == util::size(m_gicd->spendsgir)); + for (size_t i = 0; i < util::size(state->spendsgir); ++i) { + m_gicd->spendsgir[i] = state->spendsgir[i]; + } } void KInterruptController::RestoreGlobal(const GlobalState *state) const { From 0a299a3d40f6032744d535ea23482da052260638 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 11:48:04 -0700 Subject: [PATCH 223/238] erpt: update IDs for 20.1.0 --- .../include/stratosphere/erpt/erpt_ids.autogen.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp index c4dd26ea8..a6a6d5f55 100644 --- a/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp +++ b/libraries/libstratosphere/include/stratosphere/erpt/erpt_ids.autogen.hpp @@ -926,6 +926,7 @@ HANDLER(GameCardLastAwakenFailureResult, 732, GameCardDetailedErrorInfo, FieldType_NumericU32, FieldFlag_None ) \ HANDLER(GameCardInsertedTimestamp, 733, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \ HANDLER(GameCardPreviousInsertedTimestamp, 734, GameCardDetailedErrorInfo, FieldType_NumericI64, FieldFlag_None ) \ + HANDLER(WlanChipResetTriggered, 735, WlanInfo, FieldType_Bool, FieldFlag_None ) \ HANDLER(TestStringNx, 1000, TestNx, FieldType_String, FieldFlag_None ) \ HANDLER(BoostModeCurrentLimit, 1001, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ HANDLER(ChargeConfiguration, 1002, BatteryChargeInfo, FieldType_NumericI32, FieldFlag_None ) \ From ae65b5df0c01bda45cecf0fa05a1e074e10982ba Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 12:02:56 -0700 Subject: [PATCH 224/238] fusee/emummc: add support for FS 20.1.0 --- emummc/source/FS/FS_offsets.c | 8 +++ emummc/source/FS/FS_versions.h | 3 ++ emummc/source/FS/offsets/2010.h | 59 +++++++++++++++++++++ emummc/source/FS/offsets/2010_exfat.h | 59 +++++++++++++++++++++ fusee/program/source/fusee_stratosphere.cpp | 8 +++ 5 files changed, 137 insertions(+) create mode 100644 emummc/source/FS/offsets/2010.h create mode 100644 emummc/source/FS/offsets/2010_exfat.h diff --git a/emummc/source/FS/FS_offsets.c b/emummc/source/FS/FS_offsets.c index 3ceca0f8e..0db07fe8e 100644 --- a/emummc/source/FS/FS_offsets.c +++ b/emummc/source/FS/FS_offsets.c @@ -77,6 +77,8 @@ #include "offsets/1900_exfat.h" #include "offsets/2000.h" #include "offsets/2000_exfat.h" +#include "offsets/2010.h" +#include "offsets/2010_exfat.h" #include "../utils/fatal.h" #define GET_OFFSET_STRUCT_NAME(vers) g_offsets##vers @@ -165,6 +167,8 @@ DEFINE_OFFSET_STRUCT(_1900); DEFINE_OFFSET_STRUCT(_1900_EXFAT); DEFINE_OFFSET_STRUCT(_2000); DEFINE_OFFSET_STRUCT(_2000_EXFAT); +DEFINE_OFFSET_STRUCT(_2010); +DEFINE_OFFSET_STRUCT(_2010_EXFAT); const fs_offsets_t *get_fs_offsets(enum FS_VER version) { switch (version) { @@ -290,6 +294,10 @@ const fs_offsets_t *get_fs_offsets(enum FS_VER version) { return &(GET_OFFSET_STRUCT_NAME(_2000)); case FS_VER_20_0_0_EXFAT: return &(GET_OFFSET_STRUCT_NAME(_2000_EXFAT)); + case FS_VER_20_1_0: + return &(GET_OFFSET_STRUCT_NAME(_2010)); + case FS_VER_20_1_0_EXFAT: + return &(GET_OFFSET_STRUCT_NAME(_2010_EXFAT)); default: fatal_abort(Fatal_UnknownVersion); } diff --git a/emummc/source/FS/FS_versions.h b/emummc/source/FS/FS_versions.h index 5b2dfc508..312f63224 100644 --- a/emummc/source/FS/FS_versions.h +++ b/emummc/source/FS/FS_versions.h @@ -113,6 +113,9 @@ enum FS_VER FS_VER_20_0_0, FS_VER_20_0_0_EXFAT, + FS_VER_20_1_0, + FS_VER_20_1_0_EXFAT, + FS_VER_MAX, }; diff --git a/emummc/source/FS/offsets/2010.h b/emummc/source/FS/offsets/2010.h new file mode 100644 index 000000000..70691ece7 --- /dev/null +++ b/emummc/source/FS/offsets/2010.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_2010_H__ +#define __FS_2010_H__ + +// Accessor vtable getters +#define FS_OFFSET_2010_SDMMC_ACCESSOR_GC 0x1A7DB0 +#define FS_OFFSET_2010_SDMMC_ACCESSOR_SD 0x1AA130 +#define FS_OFFSET_2010_SDMMC_ACCESSOR_NAND 0x1A8560 + +// Hooks +#define FS_OFFSET_2010_SDMMC_WRAPPER_READ 0x1A3C20 +#define FS_OFFSET_2010_SDMMC_WRAPPER_WRITE 0x1A3C80 +#define FS_OFFSET_2010_RTLD 0x2B594 +#define FS_OFFSET_2010_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2010_CLKRST_SET_MIN_V_CLK_RATE 0x1C6150 + +// Misc funcs +#define FS_OFFSET_2010_LOCK_MUTEX 0x19CD80 +#define FS_OFFSET_2010_UNLOCK_MUTEX 0x19CDD0 + +#define FS_OFFSET_2010_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1A3BE0 +#define FS_OFFSET_2010_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1A3C00 + +// Misc Data +#define FS_OFFSET_2010_SD_MUTEX 0xFF5408 +#define FS_OFFSET_2010_NAND_MUTEX 0xFF0CF0 +#define FS_OFFSET_2010_ACTIVE_PARTITION 0xFF0D30 +#define FS_OFFSET_2010_SDMMC_DAS_HANDLE 0xFD2B08 + +// NOPs +#define FS_OFFSET_2010_SD_DAS_INIT 0x289F4 + +// Nintendo Paths +#define FS_OFFSET_2010_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2010_H__ diff --git a/emummc/source/FS/offsets/2010_exfat.h b/emummc/source/FS/offsets/2010_exfat.h new file mode 100644 index 000000000..d07c9e6eb --- /dev/null +++ b/emummc/source/FS/offsets/2010_exfat.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 m4xw + * Copyright (c) 2019 Atmosphere-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __FS_2010_EXFAT_H__ +#define __FS_2010_EXFAT_H__ + +// Accessor vtable getters +#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_GC 0x1B36D0 +#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_SD 0x1B5A50 +#define FS_OFFSET_2010_EXFAT_SDMMC_ACCESSOR_NAND 0x1B3E80 + +// Hooks +#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_READ 0x1AF540 +#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_WRITE 0x1AF5A0 +#define FS_OFFSET_2010_EXFAT_RTLD 0x2B594 +#define FS_OFFSET_2010_EXFAT_RTLD_DESTINATION ((uintptr_t)(INT64_C(-0x4C))) + +#define FS_OFFSET_2010_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1D1A70 + +// Misc funcs +#define FS_OFFSET_2010_EXFAT_LOCK_MUTEX 0x1A86A0 +#define FS_OFFSET_2010_EXFAT_UNLOCK_MUTEX 0x1A86F0 + +#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AF500 +#define FS_OFFSET_2010_EXFAT_SDMMC_WRAPPER_CONTROLLER_CLOSE 0x1AF520 + +// Misc Data +#define FS_OFFSET_2010_EXFAT_SD_MUTEX 0x1006408 +#define FS_OFFSET_2010_EXFAT_NAND_MUTEX 0x1001CF0 +#define FS_OFFSET_2010_EXFAT_ACTIVE_PARTITION 0x1001D30 +#define FS_OFFSET_2010_EXFAT_SDMMC_DAS_HANDLE 0xFDFB08 + +// NOPs +#define FS_OFFSET_2010_EXFAT_SD_DAS_INIT 0x289F4 + +// Nintendo Paths +#define FS_OFFSET_2010_EXFAT_NINTENDO_PATHS \ +{ \ + {.opcode_reg = 3, .adrp_offset = 0x0006DB14, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 3, .adrp_offset = 0x0007CE1C, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x00084A08, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 4, .adrp_offset = 0x0009AE48, .add_rel_offset = 0x00000004}, \ + {.opcode_reg = 0, .adrp_offset = 0, .add_rel_offset = 0}, \ +} + +#endif // __FS_2010_EXFAT_H__ diff --git a/fusee/program/source/fusee_stratosphere.cpp b/fusee/program/source/fusee_stratosphere.cpp index 34134ff42..34e88dfb3 100644 --- a/fusee/program/source/fusee_stratosphere.cpp +++ b/fusee/program/source/fusee_stratosphere.cpp @@ -183,6 +183,9 @@ namespace ams::nxboot { FsVersion_20_0_0, FsVersion_20_0_0_Exfat, + FsVersion_20_1_0, + FsVersion_20_1_0_Exfat, + FsVersion_Count, }; @@ -278,6 +281,9 @@ namespace ams::nxboot { { 0x63, 0x54, 0x96, 0x9E, 0x60, 0xA7, 0x97, 0x7B }, /* FsVersion_20_0_0 */ { 0x47, 0x41, 0x07, 0x10, 0x65, 0x4F, 0xA4, 0x3F }, /* FsVersion_20_0_0_Exfat */ + + { 0xED, 0x34, 0xB4, 0x50, 0x58, 0x4A, 0x5B, 0x43 }, /* FsVersion_20_1_0 */ + { 0xA5, 0x1A, 0xA4, 0x92, 0x6C, 0x41, 0x87, 0x59 }, /* FsVersion_20_1_0_Exfat */ }; const InitialProcessBinaryHeader *FindInitialProcessBinary(const pkg2::Package2Header *header, const u8 *data, ams::TargetFirmware target_firmware) { @@ -668,11 +674,13 @@ namespace ams::nxboot { AddPatch(fs_meta, 0x17A9A0, NogcPatch1, sizeof(NogcPatch1)); break; case FsVersion_20_0_0: + case FsVersion_20_1_0: AddPatch(fs_meta, 0x1A7E25, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x1A8025, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x17C250, NogcPatch1, sizeof(NogcPatch1)); break; case FsVersion_20_0_0_Exfat: + case FsVersion_20_1_0_Exfat: AddPatch(fs_meta, 0x1B3745, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x1B3945, NogcPatch0, sizeof(NogcPatch0)); AddPatch(fs_meta, 0x187B70, NogcPatch1, sizeof(NogcPatch1)); From f4e1d0bf9f89be80559653766892d69d54eedf93 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 12:18:51 -0700 Subject: [PATCH 225/238] kern: move spendsgir static assert --- .../mesosphere/arch/arm/kern_generic_interrupt_controller.hpp | 1 + .../source/arch/arm/kern_generic_interrupt_controller.inc | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp index a3c28eaa9..a44c92218 100644 --- a/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp +++ b/libraries/libmesosphere/include/mesosphere/arch/arm/kern_generic_interrupt_controller.hpp @@ -118,6 +118,7 @@ namespace ams::kern::arch::arm { u32 icfgr[NumLocalInterrupts / 16]; u32 spendsgir[4]; }; + static_assert(sizeof(LocalState{}.spendsgir) == sizeof(GicDistributor{}.spendsgir)); struct GlobalState { u32 isenabler[NumGlobalInterrupts / 32]; diff --git a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc index 9fa5ffb38..e7f2eb4fa 100644 --- a/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc +++ b/libraries/libmesosphere/source/arch/arm/kern_generic_interrupt_controller.inc @@ -115,7 +115,6 @@ namespace ams::kern::arch::arm { } /* Save spendsgir. */ - static_assert(util::size(state->spendsgir) == util::size(m_gicd->spendsgir)); for (size_t i = 0; i < util::size(state->spendsgir); ++i) { state->spendsgir[i] = m_gicd->spendsgir[i]; } @@ -176,7 +175,6 @@ namespace ams::kern::arch::arm { } /* Restore spendsgir. */ - static_assert(util::size(state->spendsgir) == util::size(m_gicd->spendsgir)); for (size_t i = 0; i < util::size(state->spendsgir); ++i) { m_gicd->spendsgir[i] = state->spendsgir[i]; } From 409c3cf9e190dbb65fe76570954939cbe8a5eca0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 12:29:17 -0700 Subject: [PATCH 226/238] emummc: note 20.1.0 support in README --- emummc/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emummc/README.md b/emummc/README.md index ea9a91d7c..aa9736d27 100644 --- a/emummc/README.md +++ b/emummc/README.md @@ -2,7 +2,7 @@ *A SDMMC driver replacement for Nintendo's Filesystem Services, by **m4xw*** ### Supported Horizon Versions -**1.0.0 - 20.0.0** +**1.0.0 - 20.1.0** ## Features * Arbitrary SDMMC backend selection From 17be65b4b91c393d04a88d5f286188dddde96cc8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 12:29:54 -0700 Subject: [PATCH 227/238] git subrepo push emummc subrepo: subdir: "emummc" merged: "a8e5f1a18" upstream: origin: "https://github.com/m4xw/emummc" branch: "develop" commit: "a8e5f1a18" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- emummc/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emummc/.gitrepo b/emummc/.gitrepo index 69247ebe9..1aad635a5 100644 --- a/emummc/.gitrepo +++ b/emummc/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/m4xw/emummc branch = develop - commit = 7522f1f6054a71bdff5beadee0302cead1235be3 - parent = 0e2ef545f947d24c6add254874ab493ba84bbdc9 + commit = a8e5f1a184aeb8ba884166a1e4f386088d4a6cf1 + parent = 409c3cf9e190dbb65fe76570954939cbe8a5eca0 method = merge cmdver = 0.4.1 From 6b01ebca9e3c0f4511def5d74d21263e5fb35069 Mon Sep 17 00:00:00 2001 From: Marcus Carter Date: Tue, 27 May 2025 16:23:21 -0400 Subject: [PATCH 228/238] Clarify that code type 0xC4 uses a 64-bit value in cheats.md by formatting the key values as such Changes the formatting of the key values at `Code Type 0xC4: Begin Extended Keypress Conditional Block` in cheats.md so that it is perfectly clear that those values are 64-bit values rather than 32-bit or 28-bit like `Code Type 0x8: Begin Keypress Conditional Block`, and also for the fact that the formatting matches the rest of the document and is thus cleaner. --- docs/features/cheats.md | 70 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/docs/features/cheats.md b/docs/features/cheats.md index bf7320f23..465ded946 100644 --- a/docs/features/cheats.md +++ b/docs/features/cheats.md @@ -423,41 +423,41 @@ Note that for multiple button combinations, the bitmasks should be OR'd together #### Keypad Values Note: This is the direct output of `hidKeysDown()`. -+ 000000001: A -+ 000000002: B -+ 000000004: X -+ 000000008: Y -+ 000000010: Left Stick Pressed -+ 000000020: Right Stick Pressed -+ 000000040: L -+ 000000080: R -+ 000000100: ZL -+ 000000200: ZR -+ 000000400: Plus -+ 000000800: Minus -+ 000001000: Left -+ 000002000: Up -+ 000004000: Right -+ 000008000: Down -+ 000010000: Left Stick Left -+ 000020000: Left Stick Up -+ 000040000: Left Stick Right -+ 000080000: Left Stick Down -+ 000100000: Right Stick Left -+ 000200000: Right Stick Up -+ 000400000: Right Stick Right -+ 000800000: Right Stick Down -+ 001000000: SL Left Joy-Con -+ 002000000: SR Left Joy-Con -+ 004000000: SL Right Joy-Con -+ 008000000: SR Right Joy-Con -+ 010000000: Top button on Poké Ball Plus (Palma) controller -+ 020000000: Verification -+ 040000000: B button on Left NES/HVC controller in Handheld mode -+ 080000000: Left C button in N64 controller -+ 100000000: Up C button in N64 controller -+ 200000000: Right C button in N64 controller -+ 400000000: Down C button in N64 controller ++ 00000000 00000001: A ++ 00000000 00000002: B ++ 00000000 00000004: X ++ 00000000 00000008: Y ++ 00000000 00000010: Left Stick Pressed ++ 00000000 00000020: Right Stick Pressed ++ 00000000 00000040: L ++ 00000000 00000080: R ++ 00000000 00000100: ZL ++ 00000000 00000200: ZR ++ 00000000 00000400: Plus ++ 00000000 00000800: Minus ++ 00000000 00001000: Left ++ 00000000 00002000: Up ++ 00000000 00004000: Right ++ 00000000 00008000: Down ++ 00000000 00010000: Left Stick Left ++ 00000000 00020000: Left Stick Up ++ 00000000 00040000: Left Stick Right ++ 00000000 00080000: Left Stick Down ++ 00000000 00100000: Right Stick Left ++ 00000000 00200000: Right Stick Up ++ 00000000 00400000: Right Stick Right ++ 00000000 00800000: Right Stick Down ++ 00000000 01000000: SL Left Joy-Con ++ 00000000 02000000: SR Left Joy-Con ++ 00000000 04000000: SL Right Joy-Con ++ 00000000 08000000: SR Right Joy-Con ++ 00000000 10000000: Top button on Poké Ball Plus (Palma) controller ++ 00000000 20000000: Verification ++ 00000000 40000000: B button on Left NES/HVC controller in Handheld mode ++ 00000000 80000000: Left C button in N64 controller ++ 00000001 00000000: Up C button in N64 controller ++ 00000002 00000000: Right C button in N64 controller ++ 00000004 00000000: Down C button in N64 controller ### Code Type 0xF0: Double Extended-Width Instruction Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble. From 77603bf7e54cc2717ec38c0c3fc98621c78ff642 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 19:33:49 -0700 Subject: [PATCH 229/238] docs: add basic changelog for 1.9.1 --- docs/changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index d498e3242..d23789cb0 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,7 @@ # Changelog +## 1.9.1 ++ Basic support was added for 20.1.0. ++ General system stability improvements to enhance the user's experience. ## 1.9.0 + Basic support was added for 20.0.0. + The console should boot and atmosphère should be fully functional. However, not all modules have been fully updated to reflect the latest changes. From b11850b3a3369becd3059f195e32fc1bbdb7b54e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 28 May 2025 19:34:34 -0700 Subject: [PATCH 230/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "0f72b2ceb" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "0f72b2ceb" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index a2f582fa0..64265c604 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 9e8cbe3faa4604e9ae162546d13a74755ce30667 - parent = 4d4f0ba96876d20e505c7aa11c9bf215f276dd8b + commit = 0f72b2ceba36c4255763d79ec48575ceb41d2539 + parent = 77603bf7e54cc2717ec38c0c3fc98621c78ff642 method = merge cmdver = 0.4.1 From d8a37b4b7184b80ba979bcceb98365b8365a1c3a Mon Sep 17 00:00:00 2001 From: lsp199308 <77911322+lsp199308@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:04:52 +0800 Subject: [PATCH 231/238] loader: add usb 3.0 enable patches for 20.1.0 (#2556) * loader: add usb 3.0 enable patches for 20.1.0 --- stratosphere/loader/source/ldr_embedded_usb_patches.inc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stratosphere/loader/source/ldr_embedded_usb_patches.inc b/stratosphere/loader/source/ldr_embedded_usb_patches.inc index f91f1da82..efb05efef 100644 --- a/stratosphere/loader/source/ldr_embedded_usb_patches.inc +++ b/stratosphere/loader/source/ldr_embedded_usb_patches.inc @@ -74,6 +74,11 @@ constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_20_0_0[] = { { 0x7090, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, }; +constexpr inline const EmbeddedPatchEntry Usb30ForceEnablePatches_20_1_0[] = { + { 0x7010, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, + { 0x7090, "\x20\x00\x80\x52\xC0\x03\x5F\xD6", 8 }, +}; + constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("C0D3F4E87E8B0FE9BBE9F1968A20767F3DC08E03"), util::size(Usb30ForceEnablePatches_9_0_0), Usb30ForceEnablePatches_9_0_0 }, { ParseModuleId("B9C700CA8335F8BAA0D2041D8D09F772890BA988"), util::size(Usb30ForceEnablePatches_10_0_0), Usb30ForceEnablePatches_10_0_0 }, @@ -88,4 +93,5 @@ constexpr inline const EmbeddedPatch Usb30ForceEnablePatches[] = { { ParseModuleId("4F21AE15E814FA46515C0401BB23D4F7ADCBF3F4"), util::size(Usb30ForceEnablePatches_18_0_0), Usb30ForceEnablePatches_18_0_0 }, /* 18.0.0 */ { ParseModuleId("54BB9BB32C958E02752DC5E4AE8D016BFE1F5418"), util::size(Usb30ForceEnablePatches_19_0_0), Usb30ForceEnablePatches_19_0_0 }, /* 19.0.0 */ { ParseModuleId("40E80E7442C0DFC985315E6F9E8C77229818AC0F"), util::size(Usb30ForceEnablePatches_20_0_0), Usb30ForceEnablePatches_20_0_0 }, /* 20.0.0 */ + { ParseModuleId("A5EF8D22EDF8A384E4135270ED596C1D2D524159"), util::size(Usb30ForceEnablePatches_20_1_0), Usb30ForceEnablePatches_20_1_0 }, /* 20.1.0 - 20.1.1 */ }; From 4a3e2b5c573d55d883d34f154fc8c8cbf7ac5e78 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 14 Jul 2025 18:23:14 -0700 Subject: [PATCH 232/238] ams: add enum version support for 20.1.x/20.2.0 --- .../include/stratosphere/hos/hos_types.hpp | 3 +++ .../libvapours/include/vapours/ams/ams_target_firmware.h | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index 55828b5f6..c7530b0ea 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -90,6 +90,9 @@ namespace ams::hos { Version_20_0_0 = ::ams::TargetFirmware_20_0_0, Version_20_0_1 = ::ams::TargetFirmware_20_0_1, Version_20_1_0 = ::ams::TargetFirmware_20_1_0, + Version_20_1_1 = ::ams::TargetFirmware_20_1_1, + Version_20_1_5 = ::ams::TargetFirmware_20_1_5, + Version_20_2_0 = ::ams::TargetFirmware_20_2_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index 5afcdc79c..b0ee74b62 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -88,8 +88,11 @@ #define ATMOSPHERE_TARGET_FIRMWARE_20_0_0 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_20_0_1 ATMOSPHERE_TARGET_FIRMWARE(20, 0, 1) #define ATMOSPHERE_TARGET_FIRMWARE_20_1_0 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_20_1_1 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 1) +#define ATMOSPHERE_TARGET_FIRMWARE_20_1_5 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 5) +#define ATMOSPHERE_TARGET_FIRMWARE_20_2_0 ATMOSPHERE_TARGET_FIRMWARE(20, 2, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_1_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_2_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -170,6 +173,9 @@ namespace ams { TargetFirmware_20_0_0 = ATMOSPHERE_TARGET_FIRMWARE_20_0_0, TargetFirmware_20_0_1 = ATMOSPHERE_TARGET_FIRMWARE_20_0_1, TargetFirmware_20_1_0 = ATMOSPHERE_TARGET_FIRMWARE_20_1_0, + TargetFirmware_20_1_1 = ATMOSPHERE_TARGET_FIRMWARE_20_1_1, + TargetFirmware_20_1_5 = ATMOSPHERE_TARGET_FIRMWARE_20_1_5, + TargetFirmware_20_2_0 = ATMOSPHERE_TARGET_FIRMWARE_20_2_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From 7e0eb10e32f83e4ab139cf72db5ee5394dabc6e2 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 14 Jul 2025 18:24:52 -0700 Subject: [PATCH 233/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "4e3615355" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "4e3615355" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 64265c604..c106c2138 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 0f72b2ceba36c4255763d79ec48575ceb41d2539 - parent = 77603bf7e54cc2717ec38c0c3fc98621c78ff642 + commit = 4e3615355a2e05c3cba688ffd05f680be62fc1c5 + parent = 4a3e2b5c573d55d883d34f154fc8c8cbf7ac5e78 method = merge cmdver = 0.4.1 From a487efad6bbc536401a6ea2b897a579e38307c07 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 16 Jul 2025 10:23:05 -0700 Subject: [PATCH 234/238] ams: bump version, add 1.9.2 changelog --- docs/changelog.md | 4 ++++ libraries/libvapours/include/vapours/ams/ams_api_version.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index d23789cb0..7b4fe0698 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,8 @@ # Changelog +## 1.9.2 ++ Basic support was added for 20.2.0. ++ USB 3.0 support force-enable was fixed for 20.1.0+. ++ General system stability improvements to enhance the user's experience. ## 1.9.1 + Basic support was added for 20.1.0. + General system stability improvements to enhance the user's experience. diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index aa16aa0e2..ce39c8a49 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -17,10 +17,10 @@ #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #define ATMOSPHERE_RELEASE_VERSION_MINOR 9 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 1 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 2 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 2 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 From af859d9e658fcb35493080e8053014190661d086 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 16 Jul 2025 10:23:50 -0700 Subject: [PATCH 235/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "af10bca1b" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "af10bca1b" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index c106c2138..13939fac7 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = 4e3615355a2e05c3cba688ffd05f680be62fc1c5 - parent = 4a3e2b5c573d55d883d34f154fc8c8cbf7ac5e78 + commit = af10bca1bc56a740d52712e6a00d38217e4935c3 + parent = a487efad6bbc536401a6ea2b897a579e38307c07 method = merge cmdver = 0.4.1 From c77acb32be8ef31389fc2e94a74e51d76e5b41e1 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 22 Jul 2025 00:36:51 -0700 Subject: [PATCH 236/238] fs.mitm: steal some heap when building romfs for kotor2 (closes #2564) --- stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp index 025fcaba3..cba29e380 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_romfs.cpp @@ -36,6 +36,11 @@ namespace ams::mitm::fs { }; constexpr const ApplicationWithDynamicHeapInfo ApplicationsWithDynamicHeap[] = { + /* STAR WARS: Knights of the Old Republic II: The Sith Lords. */ + /* Requirement ? MB. 16 MB stolen heap fixes a crash, though. */ + /* Unknown heap sensitivity. */ + { 0x0100B2C016252000, 16_MB, 0_MB }, + /* Animal Crossing: New Horizons. */ /* Requirement ~24 MB. */ /* No particular heap sensitivity. */ From debfff9f620c7fad0da633ee92d8e2a678f19de6 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Jul 2025 15:16:51 -0700 Subject: [PATCH 237/238] ams: bump version, support 20.3.0 --- docs/changelog.md | 4 ++++ .../libstratosphere/include/stratosphere/hos/hos_types.hpp | 1 + libraries/libvapours/include/vapours/ams/ams_api_version.h | 4 ++-- .../libvapours/include/vapours/ams/ams_target_firmware.h | 4 +++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 7b4fe0698..93e7e87fb 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,4 +1,8 @@ # Changelog +## 1.9.3 ++ Basic support was added for 20.3.0. ++ Compatibility was fixed for loading mods with KOTOR 2 (star wars). ++ General system stability improvements to enhance the user's experience. ## 1.9.2 + Basic support was added for 20.2.0. + USB 3.0 support force-enable was fixed for 20.1.0+. diff --git a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp index c7530b0ea..3a0ac040a 100644 --- a/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/hos/hos_types.hpp @@ -93,6 +93,7 @@ namespace ams::hos { Version_20_1_1 = ::ams::TargetFirmware_20_1_1, Version_20_1_5 = ::ams::TargetFirmware_20_1_5, Version_20_2_0 = ::ams::TargetFirmware_20_2_0, + Version_20_3_0 = ::ams::TargetFirmware_20_3_0, Version_Current = ::ams::TargetFirmware_Current, diff --git a/libraries/libvapours/include/vapours/ams/ams_api_version.h b/libraries/libvapours/include/vapours/ams/ams_api_version.h index ce39c8a49..517ce8198 100644 --- a/libraries/libvapours/include/vapours/ams/ams_api_version.h +++ b/libraries/libvapours/include/vapours/ams/ams_api_version.h @@ -17,10 +17,10 @@ #define ATMOSPHERE_RELEASE_VERSION_MAJOR 1 #define ATMOSPHERE_RELEASE_VERSION_MINOR 9 -#define ATMOSPHERE_RELEASE_VERSION_MICRO 2 +#define ATMOSPHERE_RELEASE_VERSION_MICRO 3 #define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 20 -#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 2 +#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 3 #define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0 diff --git a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h index b0ee74b62..643ee7f6f 100644 --- a/libraries/libvapours/include/vapours/ams/ams_target_firmware.h +++ b/libraries/libvapours/include/vapours/ams/ams_target_firmware.h @@ -91,8 +91,9 @@ #define ATMOSPHERE_TARGET_FIRMWARE_20_1_1 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 1) #define ATMOSPHERE_TARGET_FIRMWARE_20_1_5 ATMOSPHERE_TARGET_FIRMWARE(20, 1, 5) #define ATMOSPHERE_TARGET_FIRMWARE_20_2_0 ATMOSPHERE_TARGET_FIRMWARE(20, 2, 0) +#define ATMOSPHERE_TARGET_FIRMWARE_20_3_0 ATMOSPHERE_TARGET_FIRMWARE(20, 3, 0) -#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_2_0 +#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_20_3_0 #define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0) #define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT @@ -176,6 +177,7 @@ namespace ams { TargetFirmware_20_1_1 = ATMOSPHERE_TARGET_FIRMWARE_20_1_1, TargetFirmware_20_1_5 = ATMOSPHERE_TARGET_FIRMWARE_20_1_5, TargetFirmware_20_2_0 = ATMOSPHERE_TARGET_FIRMWARE_20_2_0, + TargetFirmware_20_3_0 = ATMOSPHERE_TARGET_FIRMWARE_20_3_0, TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT, From 8b8e4438e825872715b73ed5c87ad7fe7b9e227d Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 29 Jul 2025 15:17:41 -0700 Subject: [PATCH 238/238] git subrepo push libraries subrepo: subdir: "libraries" merged: "bc7a0fc11" upstream: origin: "https://github.com/Atmosphere-NX/Atmosphere-libs" branch: "master" commit: "bc7a0fc11" git-subrepo: version: "0.4.1" origin: "???" commit: "???" --- libraries/.gitrepo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/.gitrepo b/libraries/.gitrepo index 13939fac7..bbc0f9a4e 100644 --- a/libraries/.gitrepo +++ b/libraries/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/Atmosphere-NX/Atmosphere-libs branch = master - commit = af10bca1bc56a740d52712e6a00d38217e4935c3 - parent = a487efad6bbc536401a6ea2b897a579e38307c07 + commit = bc7a0fc11a57b62a27227e8cffd65cc8ed459c5b + parent = debfff9f620c7fad0da633ee92d8e2a678f19de6 method = merge cmdver = 0.4.1