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) {